I've started thinking about generalization. So we can better support disparate but similar games rules like those of Civilization I/II/III, Alpha Centauri. Hopefully also the rules in the Civilization Call to Power series. Regarding the other 4X games (i.e. MoO, MoM)... well, we will get there in due time.
- Build Dependencies
- Obsoletion Dependencies
- Redundancy Dependencies
- Effects
- Sources Cache
Build dependencies[]
A category system for the build dependencies in the Sid Meyer 4X games. Jargon for exactly the same concepts:
Civilization | Alpha Centauri |
---|---|
Food | Nutrients |
Shields | Minerals |
Trade | Energy |
Taxes | Economy |
Science | Labs |
Luxuries | Psych |
Coins | Credits |
City | Base |
Improvement | Facility |
Wonder | Secret Project |
Palace | Headquarters |
All things are built in a city and may depend on one available technology or the presence in the city radius of a special or terrain type to be buildable. Some things may also depend on the existance of a technology or building/wonder, government to be built (e.g. Fanatics, Nukes, SS Module, Mfg. Plant). In Civilization III the specials concept is split and there may be aditional building dependencies on these global specials called resources.
You may not build something if it is obsolete. Everything has a build cost in shields.
Small Wonders/Galactic Achievements[]
- unique per player.
- destroyed when the city is captured.
World Wonders[]
- unique per game.
- not rebuildable after destruction (must destroy city to destroy wonder).
- can be captured.
Improvements[]
- unique per city.
- rebuildable after destruction.
- can be destroyed or captured (razechance).
Space Constructions[]
- limited maximum amount per player.
- rebuildable after destruction.
not physically present in the city they are built on.
Palace[]
- unique per player.
- rebuildable. if already exists, then it is moved.
- free for your first city.
- destroyed when the city is captured (savepalace gives you another one).
Other things you can build:
Capitalization[]
- unlimited amount.
Units[]
- variable limited amount per city.
Why is this knowledge important?
- so we can generalize the dependencies to build things, like small wonders.
- for e.g. doing a can_build function.
Redundancy dependencies[]
Redundancy applies to effects. It should not prevent you from building something. Currently we do not allow players with a Great Wall wonder to build City Walls for e.g., when we should. It may be a good idea to provide detailed information on effects to the user so they will not build redundant effects. But if the player wants to build it even if it is made 100% redundant by something that supposedly has a "perpetual" effect, you should not forbid him to.
You should also be able to build a Hydro Plant without destroying your Power Plant first. Then the best effect in the redundant group wins. IIRC Civ I did things this way.
The player knows best. For e.g. he could know that he will lose that "perpetual" wonder and has to start building alternatives before that happens, while he still can.
Sources cache[]
Currently we cannot have small wonders or improvements with effects having larger than city range. This is because our sources caches for buildings are in game.global_wonders[] and pcity->improvements[].
The improvements with larger than city range we are interested in having are limited to one per player or per game (i.e. world/player unique wonders).
The main culprit is global.global_wonders[]. It can only store one city id per building type, so it cannot possibly work for Palace (multiple players in a game have their own) or small wonders.
The way we fixed this was by adding a new player wide pplayer->small_wonders[] array, akin to the one for great wonders.
I've considered several other possible alternatives, which would provide more generic traits (more than one improvement of a type with larger than city range effects per player, etc). They are all hard to cache. City ids are nice and safe because if a city switches players, it still has the same id. If a continent splits, the city id is still the same. If the client doesn't know the city yet, it won't crash. If a city is destroyed, looking up that city id won't find anything (and it won't crash either). The people who created this code were ingenious to make it so in the first place.
Make the common case fast, and the uncommon case possible.