Subsystem: SocialPolicies - Adam-Poppenheimer/Civ-Clone GitHub Wiki
Social Policies are a set of bonuses, divided into a number of Policy Trees, that Civilizations can unlock by generating Culture. Once a Policy Tree is unlocked by a Civilization, it provides its starting bonuses to that Civ. Social Policies within that tree can only be unlocked once the tree is unlocked. Policies can have other Policies within the same tree as prerequisites, which need to be unlocked before the Policy with prerequisites can. Once all the Policies in a Policy Tree are unlocked, it also provides its Completion Bonuses to the civ that unlocked it. Each civ maintains its own set of locked and unlocked policies.
SocialPolicies exists primarily to service two interfaces within it: IPolicyTreeDefinition, and ISocialPolicyDefinition. These define a Policy Tree and a Policy within some Tree respectively, and are defined during design time. Their standard implementations are ScriptableObjects that allow read-only access to the rest of the codebase via private fields with the [SerializeField] attribute.
ISocialPolicyCanon, and its standard implementation SocialPolicyCanon, control and record which civilization has which Policy Trees and which Policies unlocked. It contains a number of get and set methods for that purpose, which check to make sure game-mechanical requirements are met (a Policy can't be unlocked for a civ unless its Tree and its prerequisites are unlocked, too). It presents a GetPolicyBonusesForCiv() that can be used to gather all the bonuses from all the Policy Trees and all the Polices the civ has unlocked. SocialPolicyCanon pushes data into a number of CivSignals to inform the rest of the codebase when changes are made. It also contains a pair of "Override" methods that set a civ's unlocked policies and trees without checking for correctness or emitting events. These exist to aid in map decomposition as described in the MapManagement subsystem.
The cost of unlocking Policies and Policy Trees (which follow the same equations) is managed by the ISocialPolicyCostLogic implementation. Its standard implementation takes into account the number of cities a civ has, how many trees and policies it's unlocked, and a number of configuration variables to produce an integer cost rounded to the nearest multiple of 5.
The various bonuses Polices and Policy Trees can provide to civilizations that unlock them is detailed in the ISocialPolicyBonusesData interface. The standard implementation of that interface is a ScriptableObject that maintains read-only properties via a private field with the [SerializeField] attribute. What, exactly, these bonuses do is implemented in other parts of the codebase: the main product of SocialPolicies is a collection of ISocialPolicyBonusesData to be consumed by other classes.