{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://www.shardsofstone.com/schemas/v1/def-overrides.json",
  "$comment": "GENERATED by tools/generate_modding_reference.ts. Do not edit by hand.",
  "title": "DefOverrideSet",
  "description": "Per-match data overrides (format v2): patches and clones of units, buildings, items, spells, upgrades and heroes, plus sound and model URL maps.",
  "type": "object",
  "properties": {
    "units": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/UnitOverride"
      }
    },
    "buildings": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/BuildingOverride"
      }
    },
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/ItemOverride"
      }
    },
    "spells": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/SpellOverride"
      }
    },
    "upgrades": {
      "description": "Research / tech upgrades (`UPGRADE_DEFS`).",
      "type": "array",
      "items": {
        "$ref": "#/definitions/UpgradeOverride"
      }
    },
    "heroes": {
      "description": "Heroes (`HERO_DEFS`). A clone is trainable as `hero_<id>` once a building's `produces` lists it.",
      "type": "array",
      "items": {
        "$ref": "#/definitions/HeroOverride"
      }
    },
    "sounds": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "pattern": "^(data:|https?://)"
      }
    },
    "models": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "pattern": "^(data:|https?://|/assets/)",
        "description": "A .glb/.gltf URL or data URI; name it from a def with \"modelUrl\": \"mod:<key>\"."
      }
    }
  },
  "additionalProperties": false,
  "definitions": {
    "AbilityType": {
      "type": "string",
      "enum": [
        "active",
        "passive_aura"
      ]
    },
    "AoeShape": {
      "description": "Footprint an area spell covers. Mirrors the boss telegraph vocabulary (`TelegraphShape` in bossAbilities.ts) on purpose — the geometry for all four already exists, tested and deterministic, in systems/combat/aoeShapes.ts, and was boss-only for no reason other than nobody having wired it to spells.",
      "type": "string",
      "enum": [
        "circle",
        "cone",
        "line",
        "arc"
      ]
    },
    "ArmorClass": {
      "type": "string",
      "enum": [
        "cloth",
        "leather",
        "mail",
        "plate"
      ]
    },
    "AuraDef": {
      "type": "object",
      "required": [
        "id",
        "name",
        "radius",
        "stat",
        "modifier",
        "affectsAllies",
        "affectsEnemies"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "radius": {
          "type": "number"
        },
        "stat": {
          "type": "string"
        },
        "modifier": {
          "type": "number"
        },
        "affectsAllies": {
          "type": "boolean"
        },
        "affectsEnemies": {
          "type": "boolean"
        },
        "targetClass": {
          "description": "Restrict which entity class this aura applies to. Default 'all'. 'unit' = skip buildings; 'building' = only buildings (High-Elf adjacency).",
          "type": "string",
          "enum": [
            "unit",
            "building",
            "all"
          ]
        },
        "groundOnly": {
          "description": "When true, the aura skips FLYING and NAVAL targets — for ground-only effects like Undead \"Draining Blight\" that should only hit ground troops.",
          "type": "boolean"
        },
        "noStack": {
          "description": "When true, this aura does NOT stack across multiple source entities: a target within range of N sources projecting the same aura id gets ONE instance (strongest modifier wins), refreshed each tick — instead of the effect multiplying per source. AuraSystem already defaults BUILDING-sourced auras to this behavior even when the flag is unset (so clustered Undead Draining Blight / Lizardmen Obelisks / Dark-Elf Shadow Shroud don't multiply); set it explicitly to force / suppress non-stacking regardless of source. Hero passive + item auras leave it unset and keep per-source stacking.",
          "type": "boolean"
        }
      },
      "additionalProperties": false
    },
    "BuildingDefPatch": {
      "type": "object",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "race": {
          "anyOf": [
            {
              "$ref": "#/definitions/Race"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "role": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "width": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "height": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "rotatable": {
          "description": "Placement may swap width/height with a quarter turn.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "hp": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "armor": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "cost": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "gold": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "lumber": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "stone": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "oil": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buildTime": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "produces": {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requires": {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isResourceDrop": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "acceptsGold": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "acceptsLumber": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "acceptsStone": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "acceptsOil": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "attackDamage": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "attackRange": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "attackSpeed": {
          "description": "Attack speed (attacks per second). Defaults to 30 if omitted.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "aoeRadius": {
          "description": "Area of effect radius for splash damage. Defaults to 0.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "sightRadius": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "populationProvided": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "spriteKey": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "modelId": {
          "description": "If set, renders via 3D GLB pipeline; falls back to 2D sprite if omitted or load fails",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "modelUrl": {
          "description": "External or direct GLB URL override",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "animationsUrl": {
          "description": "External or direct animations GLB URL override",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "researches": {
          "description": "Upgrade IDs this building can research",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "upgradesTo": {
          "description": "If set, this building can be upgraded to the specified building ID(s)",
          "anyOf": [
            {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "upgradesFrom": {
          "description": "If set, this building is an upgrade of the specified building ID (replaces it in-place)",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "tier": {
          "description": "Tier level: 1 = base, 2 = upgraded, 3 = fully upgraded",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isCoastalBuilding": {
          "description": "Must be placed on coastline (touching both land and water)",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isWaterBuilding": {
          "description": "Must be placed entirely on water tiles",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isQuarry": {
          "description": "Must be placed over at least one stone tile",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isLumberGrove": {
          "description": "Must be placed over at least one tree tile (wood elf lumber grove)",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canAirlift": {
          "description": "Lizardmen Solar Levitation: this structure can tear itself out of the ground on solar thrusters, fly, and set down elsewhere (see `components/Airborne.ts`, `systems/AirliftSystem.ts`).",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requiresCorruption": {
          "description": "Ratmen: may only be placed on the player's own terrain corruption.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requiresEnergyField": {
          "description": "High Elf: may only be placed within radius of a friendly Energy Crystal.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isCorruptionNode": {
          "description": "Ratmen Corruption Node — projects a large corruption radius (can seed child nodes).",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isTunnel": {
          "description": "Ratmen Gnawhole tunnel endpoint (entrance/exit share one def + sprite).",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "tunnelEndsPerPair": {
          "description": "How many PLAYER-PLACED buildings one tunnel pair costs. Defaults to 1.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isEnergyCrystal": {
          "description": "High Elf Energy Crystal — supplies population AND projects a build power-field.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "producesArcane": {
          "description": "Passive Arcane (High-Elf soft currency) generated per tick by this building.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "hasAspectSelection": {
          "description": "Lizardmen Sacred Geometry: building completes DORMANT and the player picks its aspect via the `set_obelisk_aspect` command (ObeliskAspect component; auras derived by data/obeliskAspects.ts, NOT def.auras). Also switches the build cap to the dynamic getObeliskCap() rule instead of maxCount.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "spellcasterMana": {
          "description": "Starting/max mana for this building's Spellcaster (with `spells`). Defaults to 0 — building-cast spells are then gated on cooldown/arcane only.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "spellcasterManaRegen": {
          "description": "Mana regen per second for this building's Spellcaster. Defaults to 0.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "auras": {
          "description": "Aura(s) this building projects to nearby entities (attached at build completion).",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "$ref": "#/definitions/AuraDef"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "garrisonCapacity": {
          "description": "Max workers that can garrison inside (town hall bell ability)",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "navalBuildOnly": {
          "description": "Only naval workers (tankers/barges) can build this",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canAttackAir": {
          "description": "Whether this building can attack flying units. Defaults to true for buildings with attackDamage > 0.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "description": {
          "description": "Short one-sentence description of what this building does gameplay-wise",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "maxCount": {
          "description": "Maximum number of this building allowed per player. Undefined = unlimited.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buildLimitPerTownHall": {
          "description": "Maximum number of this building per owned town hall. Used with maxCount for combined limits.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "fortressWeapons": {
          "description": "Multi-weapon system for fortress-type buildings",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "cannons": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "count": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "damage": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "range": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "attackSpeed": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "aoeRadius": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "canAttackAir": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        }
                      },
                      "additionalProperties": {
                        "$ref": "#/definitions/PatchValue"
                      }
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "arrows": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "count": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "damage": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "range": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "attackSpeed": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "aoeRadius": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        },
                        "canAttackAir": {
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "$ref": "#/definitions/PatchOperator"
                            }
                          ]
                        }
                      },
                      "additionalProperties": {
                        "$ref": "#/definitions/PatchValue"
                      }
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "spriteGridHeight": {
          "description": "Visual grid height when sprite is taller than footprint (e.g., 4 for a 2x4 visual on a 2x2 footprint)",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "detectionRadius": {
          "description": "Sensor tower detection radius in tiles — reveals enemies on minimap through fog",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "campaignOnly": {
          "description": "If true, only available in campaign mode via Insight upgrades",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "noRubble": {
          "description": "If true, this building spawns NO rubble entity when destroyed (DeathSystem opt-out). Used by dungeon breakable props (crates/urns/barrels) which are smashable buildings but should vanish cleanly on death.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "raceOnly": {
          "description": "Restrict this building to a specific race (e.g. wood_elf only)",
          "anyOf": [
            {
              "$ref": "#/definitions/PlayableRace"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "shadowHeight": {
          "description": "Visual height (in tiles) used by the 2D projected-shadow renderer. Taller buildings cast longer shadows. Omit for auto-default based on footprint.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "spells": {
          "description": "Castable abilities for this building (spell IDs from SPELL_DEFS). SpellSystem attaches a Spellcaster component to completed buildings whose def declares spells (e.g. observatory `reveal_area`).",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "armorType": {
          "description": "Override the default 'fortified' armor class.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "heavy",
                "unarmored",
                "light",
                "medium",
                "fortified",
                "magic",
                "hero",
                "ethereal"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "attackDamageType": {
          "description": "Element of this building's attack (towers/fortresses). Defaults: arrow towers → 'pierce', cannon/siege → 'siege'.",
          "anyOf": [
            {
              "$ref": "#/definitions/DamageType"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "resists": {
          "description": "Per-element resist fractions for this building.",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "fire": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "frost": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "lightning": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "arcane": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "shadow": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "nature": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "holy": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "water": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "BuildingOverride": {
      "description": "An override of a BuildingDef. With baseId: a new def cloned from baseId, then patched. Without: a patch of the existing def with this id.",
      "type": "object",
      "required": [
        "id",
        "patch"
      ],
      "properties": {
        "id": {
          "description": "The id this override installs. With `baseId` set, this is a NEW id.",
          "type": "string",
          "minLength": 1
        },
        "baseId": {
          "description": "Present = clone from this def then patch. Absent = patch the def already registered under `id`.",
          "type": "string"
        },
        "patch": {
          "$ref": "#/definitions/BuildingDefPatch",
          "description": "Partial BuildingDef. Scalars and plain arrays replace, objects deep-merge, and $-operator objects edit in place. modelUrl/animationsUrl may be \"mod:<key>\", naming an entry in models."
        }
      },
      "additionalProperties": false
    },
    "DamageType": {
      "type": "string",
      "enum": [
        "siege",
        "slash",
        "pierce",
        "blunt",
        "fire",
        "frost",
        "lightning",
        "arcane",
        "shadow",
        "nature",
        "holy",
        "water"
      ]
    },
    "EquipSlotId": {
      "type": "string",
      "enum": [
        "weapon",
        "helmet",
        "chest",
        "cloak",
        "belt",
        "boots",
        "ring",
        "trinket"
      ]
    },
    "FullHeroDefPatch": {
      "type": "object",
      "properties": {
        "heroId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "race": {
          "anyOf": [
            {
              "$ref": "#/definitions/Race"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "baseUnitTypeId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "description": {
          "description": "1–2 sentence identity blurb shown in the Unit Viewer / codex.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "classAnalog": {
          "description": "WoW spec analog that names the hero's possession fantasy, e.g. 'Protection Warrior'.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "attackDamageType": {
          "description": "The hero's primary attack element (also tags possession auto-attacks). See docs/ELEMENTS.md.",
          "anyOf": [
            {
              "$ref": "#/definitions/DamageType"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "resistStrong": {
          "description": "Element this hero resists (affinity profile). Optional.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "fire",
                "frost",
                "lightning",
                "arcane",
                "shadow",
                "nature",
                "holy",
                "water"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "resistWeak": {
          "description": "Element this hero is vulnerable to (affinity profile). Optional.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "fire",
                "frost",
                "lightning",
                "arcane",
                "shadow",
                "nature",
                "holy",
                "water"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "statOverrides": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "hp": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "damage": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "armor": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "range": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "speed": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "sightRadius": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "mana": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "portraitKey": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "baseXpToLevel": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "hpPerLevel": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "damagePerLevel": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "armorPerLevel": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "abilityTiers": {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "$ref": "#/definitions/HeroAbilityTier"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "cost": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "gold": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "lumber": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "stone": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "oil": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buildTime": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "populationCost": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "xpRadius": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "modelId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "bakeYawSign": {
          "anyOf": [
            {
              "type": "integer",
              "enum": [
                1,
                -1
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "bakeYawOffset": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "HeroAbilityChoice": {
      "type": "object",
      "required": [
        "abilityId",
        "name",
        "type",
        "description",
        "iconKey"
      ],
      "properties": {
        "abilityId": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "type": {
          "$ref": "#/definitions/AbilityType"
        },
        "spellId": {
          "type": "string"
        },
        "aura": {
          "$ref": "#/definitions/AuraDef"
        },
        "description": {
          "type": "string"
        },
        "iconKey": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "HeroAbilityTier": {
      "type": "object",
      "required": [
        "level",
        "choices"
      ],
      "properties": {
        "level": {
          "type": "number"
        },
        "choices": {
          "type": "array",
          "items": [
            {
              "$ref": "#/definitions/HeroAbilityChoice"
            },
            {
              "$ref": "#/definitions/HeroAbilityChoice"
            }
          ],
          "minItems": 2,
          "maxItems": 2,
          "additionalItems": false
        }
      },
      "additionalProperties": false
    },
    "HeroOverride": {
      "description": "An override of a FullHeroDef. With baseId: a new def cloned from baseId, then patched. Without: a patch of the existing def with this id.",
      "type": "object",
      "required": [
        "id",
        "patch"
      ],
      "properties": {
        "id": {
          "description": "The id this override installs. With `baseId` set, this is a NEW id.",
          "type": "string",
          "minLength": 1
        },
        "baseId": {
          "description": "Present = clone from this def then patch. Absent = patch the def already registered under `id`.",
          "type": "string"
        },
        "patch": {
          "$ref": "#/definitions/FullHeroDefPatch",
          "description": "Partial FullHeroDef. Scalars and plain arrays replace, objects deep-merge, and $-operator objects edit in place."
        }
      },
      "additionalProperties": false
    },
    "ItemAuraDefPatch": {
      "type": "object",
      "properties": {
        "stat": {
          "description": "Buff stat projected onto nearby allies (e.g. 'thorns', 'damage', 'armor').",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "modifier": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "radius": {
          "description": "Radius in grid tiles.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "ItemCategory": {
      "type": "string",
      "enum": [
        "gear",
        "aura_gear",
        "active",
        "consumable",
        "scroll",
        "town_portal",
        "tome"
      ]
    },
    "ItemDefPatch": {
      "type": "object",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "rarity": {
          "anyOf": [
            {
              "$ref": "#/definitions/ItemRarity"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "category": {
          "anyOf": [
            {
              "$ref": "#/definitions/ItemCategory"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "slot": {
          "description": "Equip slot — only for gear / aura_gear.",
          "anyOf": [
            {
              "$ref": "#/definitions/EquipSlotId"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "stats": {
          "description": "Permanent buff stats while equipped.",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "stat",
                  "value"
                ],
                "properties": {
                  "stat": {
                    "type": "string"
                  },
                  "value": {
                    "type": "number"
                  }
                },
                "additionalProperties": false
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "aura": {
          "description": "Aura projected while equipped (aura_gear). AuraDef.id is derived as 'item:<slot>:<id>'.",
          "anyOf": [
            {
              "$ref": "#/definitions/ItemAuraDefPatch"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "activeSpellId": {
          "description": "Activatable spell for category 'active' (not consumed on use).",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "activeCooldown": {
          "description": "Cooldown in ticks for the active spell (tracked as SpellCooldown 'item:<id>').",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "consumableSpellId": {
          "description": "Spell cast when a consumable is used (item consumed on success).",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "scrollSpellId": {
          "description": "Spell cast when a scroll is used (item consumed on success).",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "eatHpFraction": {
          "description": "Out-of-combat \"eat/drink\" recovery (dungeon crawler). When either eat fraction is set, USING this consumable starts an interruptible channel (EAT_DRINK_CHANNEL_TICKS) that restores this fraction of MAX HP over the duration — handled entirely in ItemSystem, no consumableSpellId needed. Only usable out of combat; the channel cancels (item still spent) if the hero takes damage or moves. Fractions scale with the hero's own pools.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "eatManaFraction": {
          "description": "As eatHpFraction, for MAX mana. Skipped on heroes with no mana pool.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "tomeEffect": {
          "description": "Instant effect for tomes.",
          "anyOf": [
            {
              "$ref": "#/definitions/ItemTomeEffectPatch"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "allowedWeaponClass": {
          "description": "Restricts the item to heroes whose weapon classes include this.",
          "anyOf": [
            {
              "$ref": "#/definitions/WeaponClass"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "armorClass": {
          "description": "Armor class of an armor-slot piece (drives class checks + set bonus).",
          "anyOf": [
            {
              "$ref": "#/definitions/ArmorClass"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "setId": {
          "description": "Named item set this piece belongs to (see SET_DEFS). Lives on the def, NOT on ItemInstance — saves only carry item ids, so adding/removing a setId never breaks serialization.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "price": {
          "description": "Gold price.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "iconKey": {
          "description": "ALWAYS the item id — icon filenames derive from it.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "modelKey": {
          "description": "Ground-drop prop GLB category.",
          "anyOf": [
            {
              "$ref": "#/definitions/ItemModelKey"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "description": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "flavor": {
          "description": "Optional single short sentence, italic on the tooltip.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "soldAt": {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "ItemModelKey": {
      "description": "Which shared GLB prop a ground item draws as. One model per key, not per item — `tools/generate_item_props.js` generates exactly these.",
      "type": "string",
      "enum": [
        "scroll",
        "tome",
        "chest",
        "sword",
        "armor",
        "potion",
        "relic",
        "flag_banner"
      ]
    },
    "ItemOverride": {
      "description": "An override of a ItemDef. With baseId: a new def cloned from baseId, then patched. Without: a patch of the existing def with this id.",
      "type": "object",
      "required": [
        "id",
        "patch"
      ],
      "properties": {
        "id": {
          "description": "The id this override installs. With `baseId` set, this is a NEW id.",
          "type": "string",
          "minLength": 1
        },
        "baseId": {
          "description": "Present = clone from this def then patch. Absent = patch the def already registered under `id`.",
          "type": "string"
        },
        "patch": {
          "$ref": "#/definitions/ItemDefPatch",
          "description": "Partial ItemDef. Scalars and plain arrays replace, objects deep-merge, and $-operator objects edit in place."
        }
      },
      "additionalProperties": false
    },
    "ItemRarity": {
      "type": "string",
      "enum": [
        "common",
        "uncommon",
        "rare",
        "epic",
        "legendary"
      ]
    },
    "ItemTomeEffectPatch": {
      "type": "object",
      "properties": {
        "kind": {
          "description": "'bag_slots' permanently expands the hero's backpack by `amount` slots (capped at INVENTORY_MAX_SIZE); the others bump xp / max HP / damage.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "xp",
                "hp",
                "damage",
                "bag_slots"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "amount": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "PatchOperator": {
      "type": "object",
      "description": "A patch operator: a non-empty object whose keys all start with `$`. Array operators apply in the order remove → replaceById → prepend → append. `$replace`, `$unset` and `$ops` must stand alone.",
      "minProperties": 1,
      "properties": {
        "$append": {
          "type": "array",
          "description": "Add these elements to the end."
        },
        "$prepend": {
          "type": "array",
          "description": "Add these elements to the front."
        },
        "$remove": {
          "type": "array",
          "description": "Drop elements equal to a listed value, or whose id is a listed value."
        },
        "$replaceById": {
          "type": "array",
          "description": "Swap in the element with the same id (upsert).",
          "items": {
            "type": "object",
            "description": "Each element needs an id field (id/abilityId/heroId/spellId/unitTypeId/typeId/level, or the one named by $idKey)."
          }
        },
        "$idKey": {
          "type": "string",
          "description": "Which field is the id (default: id/abilityId/heroId/spellId/unitTypeId/typeId/level)."
        },
        "$replace": {
          "description": "Replace the field wholesale (objects included)."
        },
        "$unset": {
          "const": true,
          "description": "Delete the field."
        },
        "$ops": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/PatchValue"
          },
          "description": "Apply several patch values in order."
        }
      },
      "additionalProperties": false,
      "not": {
        "anyOf": [
          {
            "required": [
              "$replace"
            ],
            "minProperties": 2
          },
          {
            "required": [
              "$unset"
            ],
            "minProperties": 2
          },
          {
            "required": [
              "$ops"
            ],
            "minProperties": 2
          }
        ]
      }
    },
    "PatchValue": {
      "description": "Any patch value: a scalar or array (replaces), a patch operator, or a plain object (deep-merges; it may not mix $-keys with plain keys).",
      "anyOf": [
        {
          "type": [
            "string",
            "number",
            "boolean",
            "null",
            "array"
          ]
        },
        {
          "$ref": "#/definitions/PatchOperator"
        },
        {
          "type": "object",
          "propertyNames": {
            "not": {
              "pattern": "^\\$"
            }
          },
          "additionalProperties": {
            "$ref": "#/definitions/PatchValue"
          }
        }
      ]
    },
    "PlayableRace": {
      "type": "string",
      "enum": [
        "dwarf",
        "goblin",
        "ratmen",
        "lizardmen",
        "wood_elf",
        "high_elf",
        "dark_elf",
        "human",
        "undead"
      ]
    },
    "Race": {
      "type": "string",
      "enum": [
        "dwarf",
        "goblin",
        "ratmen",
        "lizardmen",
        "wood_elf",
        "high_elf",
        "dark_elf",
        "human",
        "undead",
        "neutral",
        "creep"
      ]
    },
    "SpellDefPatch": {
      "type": "object",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "manaCost": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "arcaneCost": {
          "description": "High-Elf building-cast economy cost, paid from Player.arcane (NOT mana). Validated PRE-COMMIT in SpellSystem.doCast (step 4c) so a cast the player can't afford doesn't burn the building's cooldown; deducted where the effect resolves (e.g. executeCrystalBeam). undefined/0 = no Arcane cost.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "cooldown": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "range": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "targetType": {
          "anyOf": [
            {
              "$ref": "#/definitions/SpellTargetType"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "effectType": {
          "anyOf": [
            {
              "$ref": "#/definitions/SpellEffectType"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "damage": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "healAmount": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "aoeRadius": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buffId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buffDuration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buffStat": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buffModifier": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "projectileSpeed": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "shots": {
          "description": "Projectiles per cast. Default 1. Damage is split evenly between them.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "shotIntervalTicks": {
          "description": "Ticks between consecutive shots. 0 (default) fires them all on one tick, which reads as a shotgun blast rather than a volley.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "shotCurve": {
          "description": "Lateral swing of each shot, in tiles (see Projectile.curveAmount).",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "hits": {
          "description": "Altitude axis this spell can reach — the spell-side twin of `UnitDef.canAttackAir`, which was enforced for normal attacks but had no spell equivalent at all. Until this existed, `getEntitiesInRadius` filtered only on hostility and health, so an EARTHQUAKE damaged flying units.",
          "anyOf": [
            {
              "$ref": "#/definitions/SpellHitsAxis"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "iconKey": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "hotkey": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "description": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "summonUnitTypeId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "summonCount": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "summonDuration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requiresResearch": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requiresVision": {
          "description": "Point-target spells only: the cast is rejected unless the CASTING player currently has vision of the target tile. Sim-side this is a deterministic proximity check against the player's own fogRevealer entities (playerHasVisionAt — NEVER FogOfWar, which is local-player-only and would desync lockstep MP); the UI additionally blocks + red-tints targeting via FogOfWar.isVisible for local feedback. Used by Ward Pyramid map-wide casts.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "zoneAffects": {
          "description": "Who the zone affects, judged against the CASTING player's id.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "allies",
                "enemies"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "zoneEffects": {
          "description": "Aura-style stat modifiers stamped (3-tick TTL, refreshed while inside) on every qualifying unit in the zone — e.g. [{ stat: 'damagePct', modifier: 0.15 }, { stat: 'armor', modifier: 2 }]. Buildings are never affected. Overlapping zones from the same spell don't stack (noStack).",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "stat",
                  "modifier"
                ],
                "properties": {
                  "stat": {
                    "type": "string"
                  },
                  "modifier": {
                    "type": "number"
                  }
                },
                "additionalProperties": false
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "zoneHealPerTick": {
          "description": "Direct HP restored per tick to allied units in the zone (healing ward). Applied raw + capped at max HP; 0.4 = 8 hp/s at 20 tps.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "raiseUnitTypeId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "raiseIsPermanent": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "raiseDuration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "consumesCorpse": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "dotHeal": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "duration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canAutocast": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "autocastOnly": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "autocastByDefault": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "splashDamageFactor": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "secondaryDebuffStat": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "secondaryDebuffModifier": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "secondaryDebuffDuration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "stunDuration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "lineWidth": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "lineLength": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "coneAngle": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "coneRange": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "aoeShape": {
          "anyOf": [
            {
              "$ref": "#/definitions/AoeShape"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "innerRadius": {
          "description": "'arc' only — hollow centre, in grid tiles. A ring wedge rather than a pie slice, for sweeps that should spare whoever is right on top of the caster.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "selfHpCost": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "restoreMana": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "drainsManaToCaster": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "mirrorFraction": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "armorPenalty": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "grantsCharges": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requiresCharges": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "dotDamage": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "dotDuration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "dashToTarget": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "dashVector": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "backward",
                "cursor"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "dashDistance": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "pullTarget": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "lifestealFraction": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "executeThreshold": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "executeMultiplier": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "detonatesDots": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "weaponDamagePercent": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "absorbAmount": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "chainTargets": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "chainRadius": {
          "description": "How far a bounce may reach, in TILES. Defaults to DEFAULT_CHAIN_RADIUS_TILES; read by `SpellSystem.executeChainDamage` and mirrored by `SpellVFXBridge` so the drawn arcs and the damaged units cannot disagree.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "rageCost": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "rageGain": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "energyCost": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "damageType": {
          "anyOf": [
            {
              "$ref": "#/definitions/DamageType"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "castTime": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "channeled": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "channelManaRestore": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "rtsCastBar": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "castSoundId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "impactSoundId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "SpellEffectType": {
      "type": "string",
      "enum": [
        "damage",
        "heal",
        "buff",
        "debuff",
        "aoe_damage",
        "aoe_heal",
        "aoe_buff",
        "aoe_debuff",
        "summon",
        "invisibility",
        "polymorph",
        "special",
        "bombard",
        "raise_dead",
        "restore_mana",
        "reveal",
        "cleanse",
        "passive",
        "line_damage",
        "cone_damage",
        "production_haste",
        "global_army_buff",
        "crystal_beam",
        "timed_zone",
        "convert",
        "star_gate_beam"
      ]
    },
    "SpellHitsAxis": {
      "description": "Altitude axis a spell can reach — the spell-side twin of `UnitDef.canAttackAir`.",
      "type": "string",
      "enum": [
        "ground",
        "air",
        "both"
      ]
    },
    "SpellOverride": {
      "description": "An override of a SpellDef. With baseId: a new def cloned from baseId, then patched. Without: a patch of the existing def with this id.",
      "type": "object",
      "required": [
        "id",
        "patch"
      ],
      "properties": {
        "id": {
          "description": "The id this override installs. With `baseId` set, this is a NEW id.",
          "type": "string",
          "minLength": 1
        },
        "baseId": {
          "description": "Present = clone from this def then patch. Absent = patch the def already registered under `id`.",
          "type": "string"
        },
        "patch": {
          "$ref": "#/definitions/SpellDefPatch",
          "description": "Partial SpellDef. Scalars and plain arrays replace, objects deep-merge, and $-operator objects edit in place."
        }
      },
      "additionalProperties": false
    },
    "SpellTargetType": {
      "type": "string",
      "enum": [
        "unit",
        "none",
        "point",
        "self",
        "friendly",
        "enemy",
        "corpse"
      ]
    },
    "UnitDefPatch": {
      "type": "object",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "description": {
          "description": "One-line gameplay description shown in verbose hover tooltips.",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "race": {
          "anyOf": [
            {
              "$ref": "#/definitions/Race"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "role": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "worker",
                "melee",
                "ranged",
                "heavy",
                "siege",
                "caster",
                "healer",
                "flyer",
                "air_fighter",
                "heavy_flyer",
                "naval_worker",
                "naval_ranged",
                "naval_heavy",
                "naval_stealth",
                "naval_transport",
                "trader",
                "naval_trader",
                "prop",
                "king"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "hp": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "damage": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "armor": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "range": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "attackSpeed": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "speed": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "sightRadius": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isFlying": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isNaval": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "isRanged": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canAttackAir": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canAttackGround": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "aoeRadius": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "maxCarry": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "gatherRate": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "mana": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "cost": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "gold": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "lumber": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "stone": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "oil": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "buildTime": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "populationCost": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requires": {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "spriteKey": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "modelId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "modelUrl": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "animationsUrl": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "bakeYawSign": {
          "anyOf": [
            {
              "type": "integer",
              "enum": [
                1,
                -1
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "bakeYawOffset": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "gridWidth": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "gridHeight": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "renderScale": {
          "description": "Visual-only size multiplier applied to the rendered sprite/model (all LOD tiers + 2D canvas). Default 1. Does NOT change the grid footprint, occupancy, collision, or pathfinding — purely how big the unit looks. Use for mounted/oversized units whose height-normalized model otherwise reads too small (e.g. cavalry). The model stays footprint-centered and ground-anchored as it grows.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "motionTrail": {
          "description": "If set, both renderers draw a fading motion trail from the unit's centre along its actual flight path — a speed cue for very fast movers (Runic Eye). `length` = max recorded path points in 2D (default 16). Read at render time by RenderSystem (2D) and World3DRenderer (3D).",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "color": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "length": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canHop": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "hopDistance": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "campaignOnly": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "dungeonOnly": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "summonOnly": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "invulnerable": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "spawnCount": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "produces": {
          "description": "Unit type ids this UNIT can train from its own production queue — a mobile factory (the dwarf Sky Anvil flying carrier trains its own air wing).",
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "maxCount": {
          "description": "Maximum number of this unit type a player may own AT ONCE. Counts living units PLUS everything already sitting in a production queue — without the queued half a player just queues five at a time and the cap means nothing. Rebuildable: the slot frees the moment one dies. Enforced in `commands/trainValidation.ts` (reason 'unit-cap'), which is the single sim authority for training, so the AI inherits it for free — it routes through the same `request-train` event via `aiUtils.tryRequestTrain`. Mirrors BuildingDef.maxCount. Undefined = unlimited.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "transportCapacity": {
          "description": "If set, the unit gets a `transport` component with this capacity and can carry ground units. THIS FIELD — not `role === 'naval_transport'` — is what attaches the component, which is what lets an AIR transport exist without adding to the `role` union (see the role comment above: every exhaustive role table would break) and without being swept into the AI's naval invasion/island-colonisation logic, which keys off that role. All nine naval transports carry `transportCapacity: 6` explicitly so the number lives in the def rather than being restated at each spawn site. Runtime-mutable by the `transportCapacity` upgrade stat; the component field is already serialized, sync-checked and in the worker snapshot.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "airCarrier": {
          "description": "\"This transport is an aircraft CARRIER, not merely a flying troop ship.\"",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "arcaneCost": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "innateStealth": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canAttackUnits": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "corpseCapacity": {
          "description": "If set (> 0), the unit gets a `corpseCarrier` component: it auto-vacuums nearby corpses (up to this many) and can disgorge them later, banking them past the normal decay timer. Undead Corpse Wagon only today.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "vacuumRadius": {
          "description": "Tiles the corpse-pickup zone extends BEYOND the unit's footprint on each side (a box). 0 (default) = footprint-only \"run-over\" collection: the wagon must drive over a corpse to bank it, and disgorged corpses (dropped just outside the footprint) are never re-vacuumed while it sits still. Only meaningful alongside `corpseCapacity`.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "raceOnly": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "lifesteal": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "suicideAttack": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "thorns": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "canTrample": {
          "description": "If true, the unit rolls straight THROUGH small (1x1) enemy ground units — they don't block its movement — and crushes each one for `trampleDamage` (blunt) the moment it rolls onto it. A crushed unit isn't damaged again until it leaves the wheel's footprint and re-enters (drive back and forth to re-crush). Buildings, friendly units and oversized units still block. Attaches a `trample` component. Doom Wheel only.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "trampleDamage": {
          "description": "Blunt crush damage dealt on first contact while trampling (default 25).",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "treeWalker": {
          "description": "Wood-Elf ground units path THROUGH tree terrain (which blocks everyone else) — enabling forest ambushes and terrain shortcuts. Ground-only ('land_forest' MoveType + NavGrid.isForestWalkable); ignored on flyers/naval.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "deathStyle": {
          "description": "How this unit dies, used by the ragdoll/corpse rendering pipeline (Workstream D). - 'ragdoll' : humanoid skinned-mesh ragdoll physics (default for most units) - 'topple' : large non-humanoid beasts fall over like a felled tree - 'crash' : flying units spiral down and impact the ground - 'sink' : naval units list and sink beneath the water - 'shatter' : siege / large mechanical units break apart into fragments Set on every unit so the death event handler doesn't need fallback inference.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "ragdoll",
                "topple",
                "crash",
                "sink",
                "shatter"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "leavesCorpse": {
          "description": "Explicit override for \"does this unit leave a body?\". Omit to take the default rules in `corpseRules.ts` (siege/cavalry/bosses leave nothing, everything else does). No corpse also means no skeleton and no raising.",
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "bounty": {
          "description": "Gold awarded to the killing player when this unit dies (creeps only). CreepSpawnSystem applies a small deterministic variance on top.",
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "lootTable": {
          "description": "Deterministic item drop table rolled on death (creeps only). dropChance is 0..1; entries are weighted picks of item ids from items.ts.",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "dropChance": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "entries": {
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "itemId",
                          "weight"
                        ],
                        "properties": {
                          "itemId": {
                            "type": "string"
                          },
                          "weight": {
                            "type": "number"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "damageType": {
          "description": "Override the role-derived auto-attack element (e.g. hammer melee → 'blunt').",
          "anyOf": [
            {
              "$ref": "#/definitions/DamageType"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "armorType": {
          "description": "Override the role-derived armor class.",
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "heavy",
                "unarmored",
                "light",
                "medium",
                "fortified",
                "magic",
                "hero",
                "ethereal"
              ]
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "resists": {
          "description": "Per-element resist fractions, e.g. { fire: 0.4, frost: -0.5 }.",
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "fire": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "frost": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "lightning": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "arcane": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "shadow": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "nature": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "holy": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "water": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "UnitOverride": {
      "description": "An override of a UnitDef. With baseId: a new def cloned from baseId, then patched. Without: a patch of the existing def with this id.",
      "type": "object",
      "required": [
        "id",
        "patch"
      ],
      "properties": {
        "id": {
          "description": "The id this override installs. With `baseId` set, this is a NEW id.",
          "type": "string",
          "minLength": 1
        },
        "baseId": {
          "description": "Present = clone from this def then patch. Absent = patch the def already registered under `id`.",
          "type": "string"
        },
        "patch": {
          "$ref": "#/definitions/UnitDefPatch",
          "description": "Partial UnitDef. Scalars and plain arrays replace, objects deep-merge, and $-operator objects edit in place. modelUrl/animationsUrl may be \"mod:<key>\", naming an entry in models."
        }
      },
      "additionalProperties": false
    },
    "UpgradeDefPatch": {
      "type": "object",
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "race": {
          "anyOf": [
            {
              "$ref": "#/definitions/Race"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "cost": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "gold": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "lumber": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "stone": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "oil": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "researchTime": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "researchedAt": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "effect": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "stat": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "modifier": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                },
                "appliesTo": {
                  "anyOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "$ref": "#/definitions/PatchOperator"
                    }
                  ]
                }
              },
              "additionalProperties": {
                "$ref": "#/definitions/PatchValue"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "requires": {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "description": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        },
        "iconKey": {
          "description": "Optional explicit icon key for the upgrade portrait. Defaults to the upgrade id (icons live at sprites/portraits/upgrades/<key>.png).",
          "anyOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/PatchOperator"
            }
          ]
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/PatchValue"
      }
    },
    "UpgradeOverride": {
      "description": "An override of a UpgradeDef. With baseId: a new def cloned from baseId, then patched. Without: a patch of the existing def with this id.",
      "type": "object",
      "required": [
        "id",
        "patch"
      ],
      "properties": {
        "id": {
          "description": "The id this override installs. With `baseId` set, this is a NEW id.",
          "type": "string",
          "minLength": 1
        },
        "baseId": {
          "description": "Present = clone from this def then patch. Absent = patch the def already registered under `id`.",
          "type": "string"
        },
        "patch": {
          "$ref": "#/definitions/UpgradeDefPatch",
          "description": "Partial UpgradeDef. Scalars and plain arrays replace, objects deep-merge, and $-operator objects edit in place."
        }
      },
      "additionalProperties": false
    },
    "WeaponClass": {
      "type": "string",
      "enum": [
        "ranged",
        "melee_1h",
        "melee_2h",
        "staff"
      ]
    }
  }
}
