{ "_readme": [ "Engine data for Total Annihilation. Everything the simulation knows lives here \u2014 adding a unit,", "building, weapon, terrain type, army or map theme is a JSON-only change.", "After editing, run `node tools/verifyTotalAnnihilation.js` \u2014 it cross-checks every id reference,", "frame index and closed key set in this file and will tell you exactly what broke.", "", "Sheet resolution: a unit/building's `sheetSlot` names a field on its ARMY (unitSheet or", "structureSheet), so one unit definition renders correctly for every army. That is what makes a", "third army a two-line change: add an `armies` entry pointing at two new sheets in", "data/totalannihilation-artwork.json.", "", "Units are drawn once and ROTATED at runtime \u2014 there are no per-facing frames. `turretFrame` is", "an optional second sprite that aims independently of the hull." ], "version": 1, "constants": { "tickHz": 20, "tileSize": 64, "unitCapPerArmy": 100, "projectileCap": 400, "startEnergy": 1000, "startMass": 1000, "baseEnergyCap": 500, "baseMassCap": 500, "pathBudgetPerTick": 8, "retargetPeriodTicks": 10, "engageHoldFraction": 0.45, "separationStiffness": 0.55, "shoveAfterSec": 0.6, "stuckGiveUpSec": 3.0, "arriveSlackPx": 12, "friendlyFire": false, "buildPowerNominal": 100, "eliminateWhenUnrecoverable": true, "victoryDefault": "commander" }, "victoryModes": [ { "id": "commander", "label": "COMMANDER KILL", "desc": "Destroy the enemy Commander and the war is over." }, { "id": "annihilation", "label": "ANNIHILATION", "desc": "Fight on after a Commander falls — an army dies when it can no longer build." } ], "sizeClasses": { "small": { "radius": 16, "footprint": 1, "mass": 1 }, "medium": { "radius": 26, "footprint": 1, "mass": 4 }, "large": { "radius": 44, "footprint": 2, "mass": 16 } }, "armorClasses": [ "infantry", "light", "medium", "heavy", "structure" ], "moveClasses": { "foot": { "cost": { "ground": 1.0, "rough": 1.3, "road": 0.85, "metal": 1.0, "cliff": null, "water": null } }, "tread": { "cost": { "ground": 1.0, "rough": 1.8, "road": 0.7, "metal": 1.0, "cliff": null, "water": null } }, "wheel": { "cost": { "ground": 1.0, "rough": 2.4, "road": 0.6, "metal": 1.0, "cliff": null, "water": null } } }, "armies": [ { "id": "arm", "name": "ARM", "color": "#4a90e2", "unitSheet": "arm-units", "structureSheet": "arm-structures" }, { "id": "core", "name": "CORE", "color": "#e05a2f", "unitSheet": "core-units", "structureSheet": "core-structures" } ], "commanders": [ { "id": "vance", "armyId": "arm", "opponentId": "ethel", "name": "Commander Ethel", "tagline": "Holds the line, and makes you pay for every metre of it.", "aiProfile": { "aggression": 0.45, "expansion": 0.65 } }, { "id": "klaxon", "armyId": "core", "opponentId": "klaxon", "name": "Unit KLAXON", "tagline": "Efficiency is a weapon. You are an inefficiency.", "aiProfile": { "aggression": 0.7, "expansion": 0.45 } }, { "id": "cybro", "armyId": "core", "opponentId": "cybro", "name": "Cy-Bro", "tagline": "Builds faster than you can knock it down.", "aiProfile": { "aggression": 0.35, "expansion": 0.85 } }, { "id": "nadia", "armyId": "arm", "opponentId": "nadia", "name": "Commander Nadia", "tagline": "Hits the flank while you watch the front.", "aiProfile": { "aggression": 0.8, "expansion": 0.4 } } ], "terrain": [ { "id": "ground", "ch": ".", "frame": 0, "buildable": true, "blocksMove": false, "elevation": 0 }, { "id": "rough", "ch": "r", "frame": 3, "buildable": true, "blocksMove": false, "elevation": 0 }, { "id": "road", "ch": "=", "frame": 8, "buildable": true, "blocksMove": false, "elevation": 0 }, { "id": "metal", "ch": "M", "frame": 7, "buildable": true, "blocksMove": false, "elevation": 0, "massMultiplier": 2.0 }, { "id": "cliff", "ch": "^", "frame": 4, "buildable": false, "blocksMove": true, "blocksFire": true, "elevation": 1 }, { "id": "water", "ch": "~", "frame": 5, "buildable": false, "blocksMove": true, "elevation": -1 } ], "weapons": [ { "id": "rifle", "name": "Assault Rifle", "kind": "hitscan", "damage": 6, "reload": 0.5, "burst": 3, "burstDelay": 0.06, "range": 200, "spread": 0.05, "targets": [ "ground" ], "armorMul": { "infantry": 1.3, "light": 0.85, "medium": 0.3, "heavy": 0.12, "structure": 0.2 }, "fx": { "style": "tracer", "color": "#ffe6a0", "width": 1.5, "lifeMs": 70 }, "sound": "sfx-battle-gunfire-modern" }, { "id": "sniperrifle", "name": "Marksman Rifle", "kind": "hitscan", "damage": 55, "reload": 3.0, "burst": 1, "range": 460, "spread": 0.0, "targets": [ "ground" ], "armorMul": { "infantry": 2.2, "light": 0.9, "medium": 0.3, "heavy": 0.1, "structure": 0.1 }, "fx": { "style": "beam", "color": "#d8f0ff", "width": 2, "lifeMs": 160 }, "sound": "sfx-laser-zap" }, { "id": "tankgun", "name": "120mm Cannon", "kind": "ballistic", "damage": 95, "reload": 2.0, "burst": 1, "range": 350, "speed": 700, "spread": 0.015, "leadTarget": true, "aoe": 40, "aoeFalloff": 0.15, "targets": [ "ground" ], "armorMul": { "infantry": 1.3, "light": 1.15, "medium": 1.0, "heavy": 0.8, "structure": 1.2 }, "fx": { "style": "shell", "color": "#ffd27a", "width": 3, "muzzle": 18 }, "sound": "sfx-battle-tank" }, { "id": "rocketpod", "name": "Rocket Pod", "kind": "guided", "damage": 130, "reload": 4.0, "burst": 2, "burstDelay": 0.25, "range": 440, "minRange": 110, "speed": 340, "turnRate": 2.2, "aoe": 48, "aoeFalloff": 0.15, "targets": [ "ground" ], "armorMul": { "infantry": 0.3, "light": 0.6, "medium": 1.0, "heavy": 1.4, "structure": 1.5 }, "fx": { "style": "rocket", "color": "#ff8844", "width": 2, "trail": true }, "sound": "sfx-battle-missle" }, { "id": "commanderlaser", "name": "Commander Laser", "kind": "hitscan", "damage": 38, "reload": 1.1, "burst": 1, "range": 260, "spread": 0.01, "targets": [ "ground" ], "armorMul": { "infantry": 1.3, "light": 1.0, "medium": 0.8, "heavy": 0.6, "structure": 0.5 }, "fx": { "style": "beam", "color": "#9ff0c8", "width": 3, "lifeMs": 120 }, "sound": "sfx-laser-zap" }, { "id": "dgun", "name": "D-Gun", "kind": "beam", "damage": 2000, "reload": 1.5, "burst": 1, "range": 220, "energyPerShot": 500, "targets": [ "ground" ], "manual": true, "armorMul": { "infantry": 1, "light": 1, "medium": 1, "heavy": 1, "structure": 1 }, "fx": { "style": "dgun", "color": "#8ad4ff", "width": 9, "lifeMs": 260 }, "sound": "sfx-scifi-launch" }, { "id": "towerlaser", "name": "Heavy Laser", "kind": "hitscan", "damage": 62, "reload": 1.4, "burst": 1, "range": 340, "spread": 0.01, "targets": [ "ground" ], "armorMul": { "infantry": 1.4, "light": 1.2, "medium": 0.9, "heavy": 0.55, "structure": 0.4 }, "fx": { "style": "beam", "color": "#a8e8ff", "width": 4, "lifeMs": 140 }, "sound": "sfx-laser-zap" }, { "id": "towermissile", "name": "Guided Missile", "kind": "guided", "damage": 175, "reload": 4.5, "burst": 1, "range": 620, "minRange": 180, "speed": 320, "turnRate": 2.0, "aoe": 56, "aoeFalloff": 0.15, "targets": [ "ground" ], "armorMul": { "infantry": 0.35, "light": 0.7, "medium": 1.1, "heavy": 1.5, "structure": 1.3 }, "fx": { "style": "rocket", "color": "#ffb15c", "width": 2.5, "trail": true }, "sound": "sfx-battle-missle" } ], "units": [ { "id": "commander", "name": "Commander", "role": "builder", "isCommander": true, "size": "medium", "radius": 20, "hp": 7000, "selfHeal": { "fractionPerMinute": 0.33, "pauseAfterDamageSec": 30 }, "speed": 62, "turnRate": 3.5, "moveClass": "foot", "armorClass": "heavy", "sight": 420, "cost": { "energy": 0, "mass": 0 }, "buildTime": 0, "buildPower": 100, "buildRange": 200, "builds": [ "energygen", "massgen", "barracks", "vehicleplant", "lasertower", "missilelauncher" ], "produce": { "energy": 25, "mass": 3.0 }, "storage": { "energy": 1000, "mass": 1000 }, "weapons": [ "commanderlaser", "dgun" ], "deathExplosion": { "radius": 280, "damage": 1200 }, "sheetSlot": "unitSheet", "frame": 0, "turretFrame": 1, "procShape": "commander", "icon": 0, "spritePx": 56 }, { "id": "infantry", "name": "Infantry", "role": "combat", "size": "small", "radius": 16, "hp": 260, "speed": 55, "turnRate": 6.0, "moveClass": "foot", "armorClass": "infantry", "sight": 260, "cost": { "energy": 120, "mass": 24 }, "buildTime": 6, "builtBy": [ "barracks" ], "weapons": [ "rifle" ], "sheetSlot": "unitSheet", "frame": 2, "procShape": "infantry", "icon": 1, "spritePx": 30, "moveSound": "sfx-march" }, { "id": "sniper", "name": "Sniper", "role": "combat", "size": "small", "radius": 16, "hp": 200, "speed": 46, "turnRate": 5.0, "moveClass": "foot", "armorClass": "infantry", "sight": 500, "cost": { "energy": 260, "mass": 55 }, "buildTime": 12, "builtBy": [ "barracks" ], "weapons": [ "sniperrifle" ], "sheetSlot": "unitSheet", "frame": 3, "procShape": "sniper", "icon": 2, "spritePx": 30, "moveSound": "sfx-march" }, { "id": "jeep", "name": "Jeep", "role": "scout", "size": "small", "radius": 20, "hp": 480, "speed": 175, "turnRate": 3.4, "moveClass": "wheel", "armorClass": "light", "sight": 520, "cost": { "energy": 320, "mass": 70 }, "buildTime": 8, "builtBy": [ "vehicleplant" ], "weapons": [ "rifle" ], "sheetSlot": "unitSheet", "frame": 4, "turretFrame": 5, "procShape": "jeep", "icon": 3, "spritePx": 40, "moveSound": "sfx-engine-medium" }, { "id": "tank", "name": "Tank", "role": "combat", "size": "medium", "radius": 26, "hp": 1900, "speed": 90, "turnRate": 2.2, "moveClass": "tread", "armorClass": "medium", "sight": 300, "cost": { "energy": 700, "mass": 180 }, "buildTime": 20, "builtBy": [ "vehicleplant" ], "weapons": [ "tankgun" ], "sheetSlot": "unitSheet", "frame": 6, "turretFrame": 7, "procShape": "tank", "icon": 4, "spritePx": 54, "moveSound": "sfx-engine-heavy" }, { "id": "rockettank", "name": "Rocket Tank", "role": "artillery", "size": "medium", "radius": 28, "hp": 1250, "speed": 75, "turnRate": 1.8, "moveClass": "tread", "armorClass": "medium", "sight": 320, "cost": { "energy": 1100, "mass": 300 }, "buildTime": 28, "builtBy": [ "vehicleplant" ], "weapons": [ "rocketpod" ], "sheetSlot": "unitSheet", "frame": 8, "turretFrame": 9, "procShape": "rockettank", "icon": 5, "spritePx": 56, "moveSound": "sfx-engine-heavy" } ], "buildings": [ { "id": "energygen", "name": "Energy Generator", "footprint": { "w": 2, "h": 2 }, "hp": 1440, "armorClass": "structure", "sight": 160, "cost": { "energy": 200, "mass": 60 }, "buildTime": 12, "produce": { "energy": 20 }, "storage": { "energy": 500 }, "deathExplosion": { "radius": 110, "damage": 160 }, "sheetSlot": "structureSheet", "frame": 0, "buildFrame": 1, "procShape": "energyGen", "icon": 10 }, { "id": "massgen", "name": "Mass Generator", "footprint": { "w": 2, "h": 2 }, "hp": 1260, "armorClass": "structure", "sight": 160, "cost": { "energy": 600, "mass": 50 }, "buildTime": 16, "produce": { "mass": 2.0 }, "upkeep": { "energy": 15 }, "storage": { "mass": 250 }, "terrainMultiplier": "massMultiplier", "sheetSlot": "structureSheet", "frame": 2, "buildFrame": 3, "procShape": "massGen", "icon": 11 }, { "id": "barracks", "name": "Barracks", "footprint": { "w": 3, "h": 3 }, "hp": 2520, "armorClass": "structure", "sight": 220, "cost": { "energy": 600, "mass": 180 }, "buildTime": 26, "buildPower": 100, "builds": [ "infantry", "sniper" ], "spawnOffset": { "x": 0, "y": 2.2 }, "sheetSlot": "structureSheet", "frame": 4, "buildFrame": 5, "procShape": "barracks", "icon": 12 }, { "id": "vehicleplant", "name": "Vehicle Plant", "footprint": { "w": 3, "h": 3 }, "hp": 3960, "armorClass": "structure", "sight": 220, "cost": { "energy": 1400, "mass": 520 }, "buildTime": 40, "buildPower": 100, "builds": [ "jeep", "tank", "rockettank" ], "spawnOffset": { "x": 0, "y": 2.2 }, "sheetSlot": "structureSheet", "frame": 6, "buildFrame": 7, "procShape": "vehiclePlant", "icon": 13 }, { "id": "lasertower", "name": "Laser Tower", "footprint": { "w": 1, "h": 1 }, "hp": 1300, "armorClass": "structure", "sight": 300, "cost": { "energy": 420, "mass": 120 }, "buildTime": 16, "upkeep": { "energy": 5 }, "weapons": [ "towerlaser" ], "deathExplosion": { "radius": 90, "damage": 120 }, "sheetSlot": "structureSheet", "frame": 8, "buildFrame": 9, "procShape": "laserTower", "icon": 14 }, { "id": "missilelauncher", "name": "Missile Launcher", "footprint": { "w": 2, "h": 2 }, "hp": 1700, "armorClass": "structure", "sight": 420, "cost": { "energy": 1100, "mass": 380 }, "buildTime": 34, "upkeep": { "energy": 20 }, "weapons": [ "towermissile" ], "deathExplosion": { "radius": 150, "damage": 280 }, "sheetSlot": "structureSheet", "frame": 10, "buildFrame": 11, "procShape": "missileLauncher", "icon": 15 } ], "commandIcons": { "move": 20, "attack": 21, "attackMove": 22, "stop": 23, "hold": 24, "patrol": 25, "guard": 26, "assist": 27 }, "aiSkills": [ { "skill": 1, "decisionPeriodMs": 1500, "apmCap": 1, "squadSize": 3, "expansion": 0.6, "microLevel": 0, "reactionMs": 4000 }, { "skill": 2, "decisionPeriodMs": 1100, "apmCap": 2, "squadSize": 4, "expansion": 1.0, "microLevel": 1, "reactionMs": 3000 }, { "skill": 3, "decisionPeriodMs": 800, "apmCap": 4, "squadSize": 6, "expansion": 1.6, "microLevel": 2, "reactionMs": 2000 }, { "skill": 4, "decisionPeriodMs": 500, "apmCap": 8, "squadSize": 8, "expansion": 2.2, "microLevel": 3, "reactionMs": 1000 }, { "skill": 5, "decisionPeriodMs": 300, "apmCap": 15, "squadSize": 10, "expansion": 3.0, "microLevel": 4, "reactionMs": 300 } ], "skirmish": { "sizes": { "small": 64, "medium": 96, "large": 128 }, "symmetries": [ "mirror-x", "mirror-y", "rotational" ], "themes": [ "grasslands", "snowfields", "tropics" ], "defaults": { "size": "medium", "symmetry": "mirror-x", "theme": "grasslands", "aiSkill": 3, "playerArmy": "arm" }, "startUnits": [ "commander" ], "gen": { "waterFraction": 0.1, "roughFraction": 0.18, "cliffFraction": 0.1, "metalSpotsPerStart": 4, "metalSpotRadiusTiles": 14, "minStartSeparationTiles": 40, "smoothPasses": 3, "startClearRadiusTiles": 8, "noiseScale": 0.09 } } }