OpenTD game JSON

Export/import uses the portable format opentd.game (version 1). Definition schema version: 1.

Wrapper

{
  "format": "opentd.game",
  "format_version": 1,
  "title": "My maze",
  "exported_at": "2026-08-04T12:00:00Z",
  "definition": { /* editor document */ }
}

You may also import a bare definition object (the same JSON the editor stores). Imports are normalized and clamped to your account limits.

Definition object

  • title — game name (plain text)
  • settings — width, height, game_type, chaos_mode, lives, gold, delays, allow_ground_build
  • grid — 2D array of cell kinds: ground, path, tower, blocked, spawn, exit
  • spawns / exits — portal metadata (ids, positions, exit targeting)
  • towers — tower types (including upgrade linkages)
  • monsters — monster types
  • wave_types — round schedules, groups, scaling rules
  • scoreboard — ordered widget ids

Game types

  • monster_march — Monster March
  • monster_rush — Monster Rush
  • defend_the_castle — Defend the Castle

Sample definition (truncated)

{
  "version": 1,
  "title": "Example defense",
  "settings": {
    "width": 8,
    "height": 6,
    "game_type": "monster_march",
    "chaos_mode": false,
    "allow_ground_build": false,
    "starting_lives": 20,
    "starting_gold": 1000,
    "path_must_reach_exit": true,
    "start_delay_seconds": 15,
    "between_waves_delay_seconds": 5,
    "max_rounds": 100
  },
  "grid": [
    [
      "spawn",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground"
    ],
    [
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground"
    ],
    [
      "path",
      "path",
      "path",
      "path",
      "path",
      "path",
      "path",
      "path"
    ],
    [
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground"
    ],
    [
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground"
    ],
    [
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "ground",
      "exit"
    ]
  ],
  "spawns": [],
  "exits": [],
  "towers": [
    {
      "id": "twr_9cf17333fa",
      "name": "Archer",
      "cost": 50,
      "damage": 5,
      "range": 3,
      "hp": 50,
      "cooldown": 1.0,
      "description": "Basic ranged tower.",
      "weapon": {
        "type": "single",
        "projectile_count": 1,
        "burst_interval": 0.08,
        "spread_degrees": 30.0
      },
      "element": {
        "type": "none",
        "duration": 2.0,
        "tick_rate": 0.5,
        "tick_damage": 1.0,
        "slow_factor": 0.5,
        "aoe_radius": 0.0
      },
      "upgrade_of": "",
      "upgrade_level": 1
    }
  ],
  "monsters": [
    {
      "id": "mob_fefddd39c4",
      "name": "Goblin",
      "hp": 20,
      "speed": 1.0,
      "reward": 10,
      "description": "Weak and fast."
    }
  ],
  "wave_types": [
    {
      "id": "wav_368eb57f9b",
      "name": "Default wave",
      "rounds": "1-100",
      "groups": [
        {
          "monster_id": "mob_fefddd39c4",
          "count": 5
        }
      ],
      "scaling": [
        {
          "stat": "hp",
          "basis": "appearance",
          "mode": "base_times_n",
          "factor": 1.0
        }
      ]
    }
  ],
  "scoreboard": {
    "items": [
      "score",
      "lives",
      "gold",
      "wave",
      "timer"
    ]
  }
}

Import a file in your dashboard Editor guide