How to Implement Custom Civilizations in Unciv JSON Files: A Complete Modding Guide
Implement custom civilizations in Unciv by creating a Nations.json file in your mod's jsons folder, defining Nation objects with required fields like name, outerColor, and cities, which Unciv loads via Ruleset.load() and merges into the base game ruleset.
Unciv is an open-source, mod-friendly reimplementation of Civilization V that loads all game rules—including civilizations—from JSON files. To implement custom civilizations in Unciv JSON files, you create Nation definitions that the game's Ruleset class deserializes and merges at runtime. This guide walks through the exact file structure, required fields, and loading mechanics based on the yairm210/Unciv source code.
Understanding the Nation Data Structure
In core/src/com/unciv/models/ruleset/Ruleset.kt lines 60-71, the Ruleset.load() method iterates over the RulesetFile.Nations enum entry to deserialize civilization data. The game parses each Nations.json file into a LinkedHashMap<String, Nation>, where the key is the nation's internal name derived from the name field.
Schema Validation
The JSON schema defining all valid fields resides in docs/Modders/schemas/Nations.schema.json. Unciv validates every mod file against this schema at startup, printing errors to the console if your JSON structure is invalid.
File Structure and Location
Unciv supports two locations for civilization definitions:
- Base game:
android/assets/jsons/[RulesetName]/Nations.json - Mods:
mods/YourModName/jsons/Nations.json
When loading, Unciv first reads base game files, then processes mod files in alphabetical order. Later entries override earlier ones with identical keys, allowing your custom civilizations to replace existing nations.
Required and Optional JSON Fields
Each civilization entry in Nations.json must include specific fields to display correctly in-game.
Required fields:
name: String identifier for the civilizationouterColor/innerColor: RGB objects defining UI colors (schema:Color.schema.json)cities: Array of city names (capital must be first)
Optional strategic fields:
leaderName: Display name of the leader (omit for city-states)cityStateType: Type identifier like"Cultured"or"Maritime"startBias: Array of terrain preferences (e.g.,["Coast", "Grassland"])uniques: Object containing civilization-specific abilities (schema:Uniques.schema.json)style: Suffix for image file names (e.g.,"_dark")spyNames: Array of names for espionage unitsfavoredReligion: Preferred religion stringcivilopediaText: Object for in-game encyclopedia entries
Implementing a Custom Civilization
To create a functional mod, set up the folder structure and populate your Nations.json with valid entries.
Step 1: Create the Mod Directory
Create a folder structure exactly as follows:
mods/
└── MyCustomCiv/
└── jsons/
└── Nations.json
Step 2: Define the Nation JSON
Here's a minimal working example for a seafaring civilization:
[
{
"name": "Atlantis",
"leaderName": "Poseidon",
"outerColor": { "r": 0, "g": 0, "b": 255 },
"innerColor": { "r": 0, "g": 255, "b": 255 },
"style": "dark",
"startBias": [ "Coast", "Grassland" ],
"uniques": {
"uniques": [
"Starts with a Great Scientist",
"All sea units have +1 movement"
]
},
"cities": [ "Poseidon's Pearl", "Triton's Reef", "Nereid Bay" ],
"spyNames": [ "Kraken", "Sirens" ],
"favoredReligion": "Oceanic"
}
]
Step 3: Advanced Configuration
For a complete civilization with personality and diplomatic text:
[
{
"name": "Macedonia",
"leaderName": "Alexander",
"adjective": [ "Macedonian" ],
"personality": "Aggressive",
"style": "standard",
"outerColor": { "r": 255, "g": 0, "b": 0 },
"innerColor": { "r": 255, "g": 255, "b": 0 },
"startBias": [ "Coast", "Hills" ],
"uniques": {
"uniques": [
"May build the Acropolis (Wonders) cheaper",
"Units receive +10% combat strength when fighting on hills"
]
},
"cities": [ "Alexandria", "Pella", "Miletus", "Thessalonica" ],
"spyNames": [ "Hephaestus", "Hercules" ],
"preferredVictoryType": "Domination",
"introduction": "Welcome to the ancient world!",
"civilopediaText": { "text": "A classical civilization that excels at warfare and expansion." }
}
]
How Unciv Merges Custom Civilizations
The loading mechanism in Ruleset.kt uses a LinkedHashMap<String, Nation> to store civilizations. When processing mods, the game:
- Loads base game nations into the map
- Iterates through mod folders alphabetically
- Merges mod nations, overwriting existing keys with matching names
- Sets the
originRulesetproperty on eachNationinstance to track whether it came from the base game or a specific mod
This merge strategy allows total conversion mods to replace existing civilizations while additive mods can introduce new ones with unique names.
Validation and Debugging
Unciv performs strict JSON schema validation at startup. If your Nations.json contains invalid fields or malformed objects, the game logs errors to the console and displays warnings in the UI. Always validate your syntax against docs/Modders/schemas/Nations.schema.json before distribution.
Summary
- Implement custom civilizations in Unciv JSON files by creating a
Nations.jsonfile inmods/YourMod/jsons/ - The
Ruleset.load()method incore/src/com/unciv/models/ruleset/Ruleset.ktdeserializes nations into aLinkedHashMap<String, Nation> - Required fields include
name,outerColor,innerColor, andcities - Optional fields like
uniques,startBias, andcityStateTypedefine gameplay behavior - Mods override base game entries based on alphabetical loading order and matching keys
- Validate all JSON against
docs/Modders/schemas/Nations.schema.jsonto prevent runtime errors
Frequently Asked Questions
What file name should I use for custom civilizations?
Use exactly Nations.json placed inside your mod's jsons folder. The game specifically looks for this filename when iterating through RulesetFile.Nations during the loading sequence in Ruleset.kt.
Can I override existing civilizations from the base game?
Yes. If your mod's Nations.json contains a civilization with the same name field as a base game civ, Unciv will override the original definition. The loading code processes mods alphabetically and replaces existing map entries with later ones.
How do I define unique abilities for my custom civilization?
Add a uniques object to your nation definition following the structure in docs/Modders/schemas/Uniques.schema.json. This field accepts an array of unique ability strings that modify gameplay mechanics, such as "Starts with a Great Scientist" or combat bonuses.
Why is my custom civilization not appearing in the game?
Ensure your mod folder is placed in the correct location (mods/YourModName/jsons/Nations.json), verify your JSON syntax is valid against the schema, and check that the name field is unique unless you intend to override an existing civilization. Console errors will indicate specific validation failures.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →