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:

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 civilization
  • outerColor / 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 units
  • favoredReligion: Preferred religion string
  • civilopediaText: 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:

  1. Loads base game nations into the map
  2. Iterates through mod folders alphabetically
  3. Merges mod nations, overwriting existing keys with matching names
  4. Sets the originRuleset property on each Nation instance 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.json file in mods/YourMod/jsons/
  • The Ruleset.load() method in core/src/com/unciv/models/ruleset/Ruleset.kt deserializes nations into a LinkedHashMap<String, Nation>
  • Required fields include name, outerColor, innerColor, and cities
  • Optional fields like uniques, startBias, and cityStateType define gameplay behavior
  • Mods override base game entries based on alphabetical loading order and matching keys
  • Validate all JSON against docs/Modders/schemas/Nations.schema.json to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →