277 lines
12 KiB
JSON
277 lines
12 KiB
JSON
{
|
|
"_readme": [
|
|
"Engine data for Total Annihilation. Everything the simulation knows lives here — adding a unit,",
|
|
"building, weapon, terrain type, army or map theme is a JSON-only change.",
|
|
"After editing, run `node tools/verifyTotalAnnihilation.js` — 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 — 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,
|
|
"separationStiffness": 0.55,
|
|
"shoveAfterSec": 0.6,
|
|
"stuckGiveUpSec": 3.0,
|
|
"arriveSlackPx": 12,
|
|
"friendlyFire": false,
|
|
"buildPowerNominal": 100,
|
|
"eliminateWhenUnrecoverable": true
|
|
},
|
|
|
|
"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.4, "light": 0.8, "medium": 0.35, "heavy": 0.15, "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": 90, "reload": 2.4, "burst": 1,
|
|
"range": 340, "speed": 700, "spread": 0.015, "leadTarget": true,
|
|
"aoe": 48, "aoeFalloff": 0.4, "targets": ["ground"],
|
|
"armorMul": { "infantry": 0.5, "light": 1.0, "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": 480, "minRange": 140, "speed": 340, "turnRate": 2.2,
|
|
"aoe": 80, "aoeFalloff": 0.35, "targets": ["ground"],
|
|
"armorMul": { "infantry": 0.6, "light": 1.1, "medium": 1.2, "heavy": 1.3, "structure": 1.4 },
|
|
"fx": { "style": "rocket", "color": "#ff8844", "width": 2, "trail": true },
|
|
"sound": "sfx-battle-missle" },
|
|
|
|
{ "id": "dgun", "name": "D-Gun", "kind": "beam",
|
|
"damage": 2000, "reload": 1.5, "burst": 1,
|
|
"range": 220, "energyPerShot": 500, "targets": ["ground"],
|
|
"armorMul": { "infantry": 1, "light": 1, "medium": 1, "heavy": 1, "structure": 1 },
|
|
"fx": { "style": "dgun", "color": "#8ad4ff", "width": 9, "lifeMs": 260 },
|
|
"sound": "sfx-scifi-launch" }
|
|
],
|
|
|
|
"units": [
|
|
{ "id": "commander", "name": "Commander", "role": "builder",
|
|
"size": "medium", "radius": 20,
|
|
"hp": 3000, "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"],
|
|
"produce": { "energy": 25, "mass": 3.0 },
|
|
"storage": { "energy": 1000, "mass": 1000 },
|
|
"weapons": ["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": 90, "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": 70, "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": 180, "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": 520, "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": 400, "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": 800, "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": 700, "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": 1400, "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": 2200, "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 }
|
|
],
|
|
|
|
"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.10,
|
|
"roughFraction": 0.18,
|
|
"cliffFraction": 0.10,
|
|
"metalSpotsPerStart": 4,
|
|
"metalSpotRadiusTiles": 14,
|
|
"minStartSeparationTiles": 40,
|
|
"smoothPasses": 3,
|
|
"startClearRadiusTiles": 8,
|
|
"noiseScale": 0.09
|
|
}
|
|
}
|
|
}
|