Subsystem: Civilizations - Adam-Poppenheimer/Civ-Clone GitHub Wiki

Civilizations are, as the name might suggest, another large and important subsystem in the game. The namespace isn't subdivided and consists largely of classes that implement specific gameplay features that don't have any particular relation to each-other besides happening at a civilization-wide scale.

Civilizations have gold and culture stockpiles, as well as a queue of technologies they're trying to discover. They own cities and units, whose ownership can be changed, and are based on a template that contains their name, color, and city names, as well as a flag to indicate whether it's the barbarian civ (which needs to be handled separately in certain cases). Civilizations have happiness, global promotions, free buildings it adds to its new cities, Great People points, territory, and yield, all of which are set or calculated through a number of Canon and Logic classes. They also possess social policies and technologies, which have dedicated subsystems. Finally, they have Strategic and Luxury resources, which can be used to maintain special units and buildings, or can be traded away to other civs (handled by the Diplomacy subsystem).

For how important and complex they are the core interface/class pair of this Subsystem, ICivilization/Civilization, is actually fairly simple. It's constructed via the Factory pattern, keeps track of a few simple fields on itself, and then largely uses the Template Method design pattern to delegate calculations to other classes. Similar to ICity, ICivilization has several methods meant to be called once per turn, a task delegated to other subsystems.

Like the Cities subsystem, Civilizations uses a CivModifier class to aid in the calculation of important civ-specific game modifiers, like improvement build speed and golden age length. It does not handle civ-wide modifiers that affect only cities, like production bonuses.

Civilizations also contains some canon classes to handle possession of Units and Cities. Territory is calculated via a Logic class, since a Civ's territory is determined by the territory of its cities.

There's also the somewhat ambiguously named "Resource" classes: Things like ResourceExtractionLogic and ResourceLockingCanon. These refer to MapResources (Luxury, strategic, and bonus resources in Civ 5's parlance). Every civilization has some amount of resources available to it domestically based on what MapResources are in its territory and currently being gathered by an appropriate improvement. Luxury resources provide a happiness bonus to the civ if they have at least one free copy of that resource in their possession. Strategic resources allow one to support special types of units (iron for swordsmen, horses for cavalry, etc). Strategic resources become locked when one of these types of units exists, and are freed when these units are destroyed. Civs can also trade luxury and strategic resources between each-other, which reduces the available stockpile of the exporter and increases that of the importer.

The logic for resource transfer, then, is somewhat fiddly. The Civilizations subsystem keeps track of domestic resource production (ResourceExtractionLogic), which resources are being demanded by units and buildings (ResourceLockingCanon), how many resources are available for consumption or trade (FreeResourcesLogic), and resources transfers between civs (ResourceTransferCanon).

For game design reasons, it's possible for a civ to have more resources locked than it gains from domestic production and imports (it's possible to lose production facilities, or to capture units that lack valid support). Thus ResourceLockingCanon doesn't check to see if there are copies of a particular resource to lock before locking them. It's up to consumers to check FreeResourcesLogic to determine if their actions are valid before proceeding.

ResourceTransferCanon has a fair bit of complexity. It keeps an internal list of all resource transfers for all civs, using those to calculate the number of copies of each resource each civ is importing/exporting. It creates resource transfers through the ExportCopiesOfResource(). It can also sanity-check existing resource transfers on a specific resource using the SynchronizeResourceForCiv() method. Since a civ can't export resources it doesn't have, SynchronizeResourceForCiv() checks whether the current civ has a trade deficit and then cancels deals until that trade deficit is gone or until no resources remain. A trad deficit means the civ's locked copies plus their exported copies exceed their domestic production. For reasons of game and architecture simplicity, a civ is not permitted to export copies of a resource it is importing.

The remainder of the classes in the subsystem handle specific game-mechanical elements that were deemed to fit best in Civilizations. Free buildings and units (free in different ways from free resources, unfortunate though their similar names may be), capital city logic, civ discovery, defeat, happiness, civ-civ connections, and the like are covered here, as are golden ages.