OpenCiv3 uses a directory-based loading scheme where a playable scenario (a "game mode") is composed of three components: a ruleset, textures, and behaviors.
A game mode is defined by a base directory and zero or more "addon" directories layered on top. This layering is applied uniformly across all three components:
- Base Loading: The engine loads the base directory. For rulesets, it looks for
ruleset.json first, then ruleset.lua (which must evaluate to a table). For textures and behaviors, it loads textures.lua and behaviors.lua respectively. - Addon Layering: For each directory in the
addonPaths list, the engine looks for a matching script. Addon scripts must return a function with the signature table -> table. This function is called with the current state of the component, and its return value becomes the new state. - Finalization: The composed ruleset is converted to JSON for
SaveGame compatibility, while textures and behaviors remain as Lua tables for the BehaviorEngine and texture loader.
This allows addons to be incremental, composable transforms that only need to provide the specific scripts they intend to modify.
-- Example of an addon ruleset.lua
return function(civ3_ruleset)
-- ...mutate civ3_ruleset...
return civ3_ruleset
end