Civilizations (also called Factions or Races in other games) are a concept as old as Dune 2. Their purpose is to add strategic complexity by inserting a layer of asymmetry to a game, thus enabling a variety of unique play styles and increasing replayability. How we are handling this and how much complexity we can add with the openage modding API is our topic for today.
Other articles in the modding API series:
- Introduction
- Units, Buildings & more
- Abilities
- Patching
- Attack
- Bonus
- Inventory System
- Too many villagers!
- Transform
- Civilizations (you're here)
- Restocking farms
Initial requirements
Throughout the history of strategy games, a lot of different ways to implement civilizations have evolved. In some games factions distinguish themselves only by a difference in unit stats, e.g. in Empire Earth, while others make them entirely unique (Starcraft being a prime example) with individual units, techs and strategies built around them. The Age of Empires series occupies some kind of middle ground in which each civilization uses a subset of a shared tech tree in addition to a few economic and military boni for each civ. Of course, other strategy games introduced many related flavors for their faction systems that come with their own quirks.
To support all these levels of uniqueness, we need a system that is flexible and easy to adjust. We would also like it to still be easily moddable, so that graphical and balance changes can be made by the community. Fortuately for us, nyan makes both of these requirements really easy to fulfill.
Upgrades and unlocks in openage
Before we begin explaining how civilizations are implemented, we should do a quick recap on how upgrades and unlocks are realized in openage. On a technical level every upgrade in a game is defined as a bundle of patches which modify the game entities that are currently available. In turn most upgrades are unlocked by other upgrades and were therefore also patched in at some point. This basically means that any uprade is the result of a series of patch bundles which can be traced back to one starting configuration. For example, the upgrade from spearman to pikeman is a result of these events:
- Starting configuration: Dark Age buildings, units, techs are available
- Researching
FeudalAgeTech
patchesCastleAgeTech
intoResearch
ability of town center - Researching
CastleAgeTech
patchesPikemanTech
intoResearch
ability of barracks - Researching
PikemanTech
patches graphics, name and attributes (HP (+10), attack damage (+1), etc.) ofSpearman
The way we unlock PikemanTech
is implicitely defined through the previous techs and the starting configuration. It is also important to stress that the upgrade path is not fixed and could just as well look like this:
- Starting configuration: Dark Age buildings, units, techs are available
- Researching
FeudalAgeTech
patchesWoodenStaffTech
intoResearch
ability of blacksmith - Researching
WoodenStaffTech
patchesPointyStickTech
intoResearch
ability of blacksmith - Researching
PointyStickTech
patchesPikemanTech
intoResearch
ability of barracks - Researching
PikemanTech
patches graphics, name and attributes (HP (+10), attack damage (+1), etc.) ofSpearman
This is benefical for two major reasons. For one it allows techs or units to be unlocked in different ways, which is always cool. But more importantly it shows that a tech's functionality is independent from its unlock path. Sure, PikemanTech
has to be unlocked at some point, but it doesn't matter if CastleAgeTech
or PointyStickTech
did it. In consequence, this means that any of these five steps on the unlock path -- including the starting configuration -- can be altered individually without breaking the engine logic.
Civilizations
But what does this have to do with the uniqueness of civilizations? It turns out that any unique property of a civilization is just a change of a step on the unlock path. And because we are able to alter every individual step without dangerous consequences, we can change pretty much anything we want. The civilization setup is practically a 0th step that comes with its own changes which again are introduced by patching.
Let's say we want to have a civilization that grants every pikeman of this civ 5 more HP than the "standard" pikemans have. We do so by patching the patch from PikemanTech
that upgrades HP to give another 5 points of health.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
In the series of events that leads to the research of PikemanTech
, the application of CivAdditionalHP
is part of the 0th step we talked about earlier.
- Civ setup:
CivAdditionalHP
patchesHPforPikeman
fromPikemanTech
to grant an additional 5 points of health - Starting configuration: Dark Age buildings, units, techs are available
- Researching
FeudalAgeTech
patchesCastleAgeTech
intoResearch
ability of town center - Researching
CastleAgeTech
patchesPikemanTech
intoResearch
ability of barracks - Researching
PikemanTech
patches graphics, name and attributes (HP (+15), attack damage (+1), etc.) ofSpearman
Of course, as the unlock path of PikemanTech
itself consists of patches we are able to change them, too. For example, we can have PikemanTech
unlocked in Feudal instead of Castle Age.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
We essentially removed one intermediate step on the unlock path.
- Civ setup:
CivMovePikeToFeudal
patchesPikemanTechUnlock
intoFeudalAgeTech
- Starting configuration: Dark Age buildings, units, techs are available
- Researching
FeudalAgeTech
patchesPikemanTech
intoResearch
ability of barracks - Researching
PikemanTech
patches graphics, name and attributes (HP (+10), attack damage (+1), etc.) ofSpearman
When we handle things this way, we end up with a very flexible system that allows us to uniquely define how a game is played with a civilization. One faction might unlock the pikeman by researching Feudal Age, another one by researching Imperial Age. Keep in mind that we don't even need age upgrades for unlocks, PikemanTech
might as well be unlocked by Forging or another not so important tech. The starting configuration can also be changed easily because it just represents the game data before any patches have been applied. The civilization setup can alter it the same way we did with the other steps.
The question that remains is whether this system still allows for easy modding. When we look at any unlock path, we see that the 0th step is nothing special and essentially the same as the others: The use of patching to alter attributes. Similar to how we added the 0th step for "Civ Setup", we can introduce another step that comes even before the 0th step. This step would be able to change all subsequent steps, including "Civ Setup". Such a preliminary step would be exactly what a data mod is. And because mods are also a bundle of patches, we can have a step before each mod, which would also be a mod that allows a preliminary step that would again be a mod... (repeat indefinitely)
API description
All of a civilization's individual properties are handled by the Civilization
API object. Civilization
defines various attributes for its name and ingame help, the names of civilization leaders and its starting resources. boni
is meant for civilization specific Bonus
objects that are not bound to game entities or techs, such as the vietnamese bonus that reveals the starting positions of enemy players on the map. Everything concerning uniqueness of the civilization is handled by three patch bundles civ_setup
, graphics_set
and team_setup
. They will be applied in the "0th step" we mentioned previously.
- civ_setup: Contains all patches for civ specific data changes, excluding graphical setup
- graphics_set: Contains all graphical changes for game entities
- team_setup: These patches are applied to the player of the civilization and their allies
All patches together define the unique properties of the civilization.
Questions?
Any more questions? Let us know and discuss those ideas by visiting our subreddit /r/openage!
As always, if you want to reach us directly in the dev chatroom:
- Matrix:
#sfttech:matrix.org
- IRC:
#sfttech
on libera.chat