Subsystem: Improvements - Adam-Poppenheimer/Civ-Clone GitHub Wiki
The Improvements subsystem handles a special type of object that can be constructed in-game on HexCells called, intuitively, ah Improvement. Improvements are usually built by units called Workers. They take a certain amount of time to construct, and when finished they provide bonuses to the civilization whose territory they're in. Most provide yield bonuses to the cells they're on. Some exploit strategic and luxury resources, giving the owning civilization access to one or more copies of them. Improvements can also increase movement speed of units on them, or provide defensive bonuses to units within them. When first instantiated, an Improvement doesn't provide its bonuses. Instead, it needs to be worked on for some number of turns, at which point it's said to be constructed (not in the programmatic sense). It can also be pillaged, which deconstructs but does not destroy it.
Improvements are based around the IImprovement interface and its standard implementation, Improvement. Improvements are MonoBehaviours instantiated via the Factory pattern, built as an instance of some IImprovementTemplate. Improvements are assigned a location via ImprovementLocationCanon. An Improvement largely acts as a POD with two methods that modify its state: Construct and Pillage. These activate/deactivate ah Improvement's ability to generate its bonus, though that's handled by other classes.
From a game design standpoint, Improvements have a lot of placement restrictions (mines can only go on hills, farms near fresh water, etc) that are handled by ImprovementValidityLogic. It handles other special cases, like enabling the construction of mines outside of hills when there's a resource there that can be mined.
The total yield of an improvement is calculated through the ImprovementYieldLogic class, which has a handful of related methods for estimating yield from templates, technologies, and modifiers. The methods that accept IImprovementTemplates as arguments are used by MapGeneration to estimate the yield of generated continents to know if it should make modifications to them.
A stub class called ImprovementWorkLogic is present to calculate how much progress a particular unit can make working on a particular improvement. It exists for reasons of extensibility, in case progress became a more complicated affair later in development.
Finally, there are a pair of classes suffixed "Executer": ImprovementConstructionExecuter and ImprovementDamageExecuter. The first exists to handle the surprisingly finicky way in which units construct improvements. When you first order a unit to construct an improvement, it immediately spends all of its movement points and makes some amount of progress on the improvement. In subsequent turns, the unit will continue to work on the project, but it won't spend its movement until the end of the round, so that you can move the unit in case of danger. In either case, if the improvement has enough work invested to complete it, the improvement is constructed.
ImprovementDamageExecuter exists to handle a very special case: The Citadel building created by the Great General. This allows improvements to deal damage to nearby enemy units at the end of every round, but makes sure such sources of damage do not stack (only the most powerful effect applies).