Well, I'm assuming population capacity is something that can be expressed as an equation based on other variables. So there should only be one place in code that evaluates it.
You're right that money is different. Generally you would have one time events that subtract or add an amount to this - so there is no equation that gives you the current amount of money. So yes, my claim that multiple systems shouldn't modify the same property of a Component isn't correct. It really depends on what that property expresses. For something like Money, I might make that only accessible through methods (e.g. GetMoney(), AddMoney(), SubtractMoney()).
Each building would also have bonuses that would take effect when the building is completed. Say a building increases attacking effect by x%, then some AttackSubSystem would need this information when a player attacks. But the building's bonus does not go into effect until it is completed. How does one model this state change best, while still maintaining high cohesion in the AttackSubSystem (not having to know too much about the building's logic)? I have two options here that spring to mind: 1) The AttackComponent has two columns, one for active value, and one for "desired/aim/target"-value. The subsystem always uses the active value, while the BuildingSubSystem copies target value to active value when the building is completed. 2) Another AttackModifierComponent is introduced: AttackModifiedInProgressComponent. This component would be connected to the building when first constructed and then later converted to an AttackModifierComponent.
Option 2 looks really ugly and adds complexity IMO. Any other options?
Here are my thoughts:
So, AttackSystem needs to know the multiplier. But we don't want AttackSystem to know about buildings.
I think it's reasonable that there could be an AttackMultiplier component. When we want to figure out the overall attack multiplier, we enumerate all AttackMultipliers for entities associated with that player, and combine them together (the AttackSystem could do this once per cycle). AttackMultipliers don't need to be associated with buildings of course, they could be attached to any entity.
The question now becomes when does the AttackMultiplier component get added to buildings? Seems like the BuildingSystem code could have some logic that does this when construction is completed. Or better yet, buildings always have an AttackMultiplier component. The BuildingSystem (it's ok that the BuidlingSystem knows about AttackMultiplier - someone needs to) checks the current state of the building (constructed/rundown/etc) and assigns an appropriate value to AttackMultiplier (this could be 0% if the building isn't constructed, for instance).
The AttackMultiplier component could be generalized to BonusMultiplier component, and contain other types of bonuses. Then you might actually consider a BonusCalculationSystem that enumerates all the BonusMultiplier components each cycle, and adds them up for the final tally. Other systems would request this info from the BonusCalculationSystem.