# How to Create Custom Victory Conditions in Unciv: A Complete Modding Guide

> Learn to create custom victory conditions in Unciv using only JSON. This guide requires no code changes, making modding accessible for everyone. Define your unique win states today.

- Repository: [Yair Morgenstern/Unciv](https://github.com/yairm210/Unciv)
- Tags: how-to-guide
- Published: 2026-06-18

---

**Custom victory conditions in Unciv are defined entirely through JSON configuration files, requiring no changes to the Kotlin source code.**

Unciv is an open-source Android/Desktop reimplementation of Civilization V that supports extensive modding through data-driven configuration. Creating **custom victory conditions in Unciv** allows modders to design unique win states beyond the standard Domination or Scientific victories. This guide explains how to leverage the victory system architecture to add new win conditions using only JSON definitions.

## Understanding the Victory System Architecture

The victory evaluation logic resides in [`VictoryManager.kt`](https://github.com/yairm210/Unciv/blob/main/VictoryManager.kt) at [`core/src/com/unciv/logic/civilization/managers/VictoryManager.kt`](https://github.com/yairm210/Unciv/blob/main/core/src/com/unciv/logic/civilization/managers/VictoryManager.kt). This manager reads the active ruleset's **VictoryTypes** definitions and evaluates each **milestone** listed for every victory type. When `getVictoryTypeAchieved()` determines that the final milestone of a victory type is satisfied, it returns the victory name and triggers the game end.

The system checks `GameParameters.victoryTypes` on every evaluation cycle (lines 18-21 in [`VictoryManager.kt`](https://github.com/yairm210/Unciv/blob/main/VictoryManager.kt)) to determine which victory types are active for the current session.

## Creating Victory Types with JSON

To add a custom victory condition, create or edit a [`VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.json) file in your mod folder at [`MyMod/Assets/jsons/VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/MyMod/Assets/jsons/VictoryTypes.json). This file must conform to the schema defined in [`docs/Modders/schemas/VictoryTypes.schema.json`](https://github.com/yairm210/Unciv/blob/main/docs/Modders/schemas/VictoryTypes.schema.json).

Refer to the vanilla implementation at `android/assets/jsons/Civ V - Vanilla/VictoryTypes.json` for a working template of built-in victory structures.

### Defining Victory Structure

Each entry in [`VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.json) requires a `name`, a list of `milestones`, and optional parameters such as `requiredSpaceshipParts` (for space race victories) or `hiddenInVictoryScreen`. The engine processes milestones sequentially using `Milestone.hasBeenCompletedBy(civInfo)`, checking each in order until it finds one that is incomplete.

### Writing Milestone Conditions

Milestones use Unciv's "unique" syntax to specify countable objectives, buildings, technologies, units, or policies. The syntax mirrors standard uniques with bracketed parameters.

```json
[
  {
    "name": "Eco Victory",
    "milestones": [
      "Have [Forest] tile count >= 30",
      "Have [Environmental] policy tree completed",
      "Own the [National Park] improvement in every city"
    ],
    "requiredSpaceshipParts": [],
    "hiddenInVictoryScreen": false
  }
]

```

## Implementing Instant Victory Triggers

For victories tied to specific units or buildings, add the **"Triggers Victory"** unique to your [`Units.json`](https://github.com/yairm210/Unciv/blob/main/Units.json) or [`Buildings.json`](https://github.com/yairm210/Unciv/blob/main/Buildings.json). The `VictoryManager` checks `civInfo.hasUnique(UniqueType.TriggersVictory)` as a fallback mechanism (lines 24-26 in [`VictoryManager.kt`](https://github.com/yairm210/Unciv/blob/main/VictoryManager.kt)), immediately ending the game when the condition is met.

```json
[
  {
    "name": "Eco Dome",
    "requiredTech": "Advanced Ecology",
    "cost": 320,
    "uniques": ["Triggers Victory"]
  }
]

```

## Enabling Custom Victories in Game Parameters

A victory type must be explicitly enabled in the game session through `GameParameters.victoryTypes`. When starting a custom game or loading a modded map, include your victory's key in this list—either via the Advanced Setup screen or programmatically in [`MapParameters.json`](https://github.com/yairm210/Unciv/blob/main/MapParameters.json).

```json
{
  "victoryTypes": ["Domination", "Scientific", "Eco Victory"]
}

```

Without this configuration, the `VictoryManager` will not evaluate your custom milestones during gameplay.

## Adding Victory Screen Illustrations

To display custom artwork on the Victory screen, create a folder structure at `VictoryIllustrations/<VictoryName>/` within your mod assets. Include images named `Background.png`, `Won.png`, `Lost.png`, and milestone-specific illustrations. The UI automatically loads these when the victory type is active, as documented in the modding guides.

## Summary

- Victory logic is centralized in [`VictoryManager.kt`](https://github.com/yairm210/Unciv/blob/main/VictoryManager.kt) and evaluates JSON-defined milestones via `getVictoryTypeAchieved()`
- Create [`VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.json) in `MyMod/Assets/jsons/` to define new win conditions following the schema in [`VictoryTypes.schema.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.schema.json)
- Milestones use unique syntax and are checked sequentially via `Milestone.hasBeenCompletedBy()`
- Use the `"Triggers Victory"` unique for instant win conditions on units or buildings
- Enable victories in `GameParameters.victoryTypes` for them to appear in-game
- Add visual assets in `VictoryIllustrations/<name>/` for complete UI integration

## Frequently Asked Questions

### Do I need to modify the Kotlin source code to create custom victories?

No. Unciv's victory system is fully data-driven. You only need to create a [`VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.json) file in your mod folder following the schema documented in [`VictoryTypes.schema.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.schema.json). The `VictoryManager` automatically loads and evaluates these definitions at runtime without requiring changes to [`VictoryManager.kt`](https://github.com/yairm210/Unciv/blob/main/VictoryManager.kt).

### What file path should I use for custom victory definitions?

Place your [`VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.json) file at [`MyMod/Assets/jsons/VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/MyMod/Assets/jsons/VictoryTypes.json) where `MyMod` is your mod's root directory. This follows the standard Unciv mod file structure and allows the ruleset loader to discover your victory types automatically alongside other JSON configurations.

### How does the game check if a civilization has achieved a custom victory?

The `VictoryManager.getVictoryTypeAchieved()` function iterates through each enabled victory type in `GameParameters.victoryTypes` and calls `Milestone.hasBeenCompletedBy(civInfo)` for every milestone listed. If all milestones return true, or if the civilization has the `TriggersVictory` unique, the victory is awarded immediately and the game ends.

### Can I create a victory condition that requires constructing a specific building?

Yes. Add the `"Triggers Victory"` unique to any building definition in your [`Buildings.json`](https://github.com/yairm210/Unciv/blob/main/Buildings.json). When a civilization completes that building, `civInfo.hasUnique(UniqueType.TriggersVictory)` returns true in [`VictoryManager.kt`](https://github.com/yairm210/Unciv/blob/main/VictoryManager.kt) (lines 24-26), triggering an immediate victory regardless of other milestone conditions defined in [`VictoryTypes.json`](https://github.com/yairm210/Unciv/blob/main/VictoryTypes.json).