# Destructible tanks: contract tank-damage/v1 (11 Oct 2026)

22 library tanks follow it (WWI to today). A game shows a tank healthy, hit, stripped of its panels, immobilised, with its
gun knocked out, and as a burnt wreck, only by showing and hiding named nodes. First consumer: Iron Hills (FGE branch
`tanks/base`, `genres/tanks/view/damage.js`, guide `docs-fge/TANKS.md`); showroom damage buttons in `browse/vehicles.html`
(https://dashboard.le-borgne.fr/spikes/vehicles-20261010/).

## The two files
- **A `<slug>.glb`** = the healthy tank on the old tank contract (`Hull`, `Turret` on the ring axis, `Gun` on the trunnion,
  `Barrel` child of `Gun` for recoil, empty `Muzzle` child of `Barrel` at the tip with identity rotation, `Track_L/R` with V
  along the loop, `Wheel_L1..`/`Wheel_R1..` at their hubs, hatches on their hinges, empties `Seat_*`, `Exhaust`, `Light_Head_*`,
  `Fx_Engine`, `Fx_Ammo`, `Fx_Hatch`), plus every bolt-on item as its own mesh node `Part_<Name>` (turret items
  `Part_Turret_<Name>` under `Turret`), at least 14 (10 on small tanks), spread over all sides. Under every Part the hull is
  complete: hiding one never shows a hole.
- **B `<slug>-damage.glb`** = only damage, four top-level nodes: `Hull_Damage` at the origin (`Dmg_<Name>` twins at their
  Part's origin, `Scar_Hull_Front/_L/_R/_Rear`, `Track_L_Broken`, `Track_R_Broken`), `Turret_Damage` exactly at the Turret
  origin (`Dmg_Turret_*`, `Scar_Turret_Front/_L/_R/_Rear`, `Gun_Broken` exactly at the Gun origin), `Wreck_Hull` (one burnt
  mesh, material `Burnt`), `Wreck_Turret` at the Turret origin with a closed underside (it may land upside down).
  Turretless types (Mark IV sponsons, A7V nose gun): `layout: turretless`, `Turret_Damage` at the origin, no `Wreck_Turret`.
- Why two files: glTF has no hidden flag. One file would draw the wreck and the healthy tank on top of each other in every
  consumer that does not know the contract (OMG kit, older games, the showroom). Old consumers load file A and see a normal tank.
- Materials: `Paint` (one material, neutral detail texture x baseColorFactor = the paint; games recolour the factor), `Burnt`,
  `Scars`, `TrackSteel`, `Rubber`. File B at most 110k triangles; its textures 512 px except Paint.

## Make one
1. New tank: a row in `tools/vehicles/make_jobs_tanks2.py` (slug, title, era/country tags, description, real size, default
   paint, layout, extra Part hints); `python3 tools/vehicles/make_jobs_tanks2.py` writes `jobs/<slug>-v1/job.json` + the sheet
   prompt; make the Nano Banana Pro sheet (about USD 0.14).
   Existing library tank: `python3 tools/vehicles/make_jobs_tanks_retrofit.py` (rows: slug, latest job version, tags, the
   bolt-on items that type carries). The job starts from the previous build script, GLB and baked textures
   (`gex44:/root/fal-author/<slug>-v<N>`) and keeps the model, its offsets and its paint: bots and games aim the same way.
2. `tools/author/launch.sh jobs/<job>` (Astra GPT-6 directs Blender 5.2 on gex44 through the GPU gate). Six to eight jobs at
   once worked (local RAM and the gex44 GPU were fine). Healthy GLB in about 10-30 min, the damage file by about 60 min,
   47-60 min in all. Each job renders `states.png` (healthy, hit, stripped, immobilised, wreck, turret blown off): LOOK at it.
3. `tools/vehicles/finish_tank.sh jobs/<job>`: pack (Draco + KTX2; over the 12/24 MB phone texture budget it repacks at
   512 px), `check_vehicle.py` (`check_damage`: pivots shared with Turret/Gun, twins match Parts, every state present),
   `import_vehicle.py` (card with `files.damage_glb` and `nodes.damage` {states, parts + zone + twin, scars, broken, wreck,
   attach, fx}), `manifest.py` (browse/vehicles.json, newest version per card).
4. Games: Iron Hills `python3 tools/tanks/roster.py` (FGE `tanks/base`) with a stats row; the showroom needs nothing.

## Laws
- **A card version is never reused.** On 11 Oct the retrofit jobs (job version 2) overwrote the v2 cards of the 10 Oct
  repacks (cards from the v1 jobs). `import_vehicle.py` now exits when the card version belongs to another job;
  `make_jobs_tanks_retrofit.py` picks the next free version (retrofit cards are v3, T-90 v4).
- `check_vehicle.py`'s required-node list is tested (it was written and never run before 11 Oct).
- Showroom: after re-parenting `Turret_Damage` under `Turret`, `getObjectByName` on the damage scene no longer finds its
  children and a "show everything" traverse re-shows them: keep a Set of damage meshes and look under both roots.
- Disk: each Astra job writes 50-105 MB into `~/.codex/sessions`; a full FGE checkout is 736 MB (use sparse worktrees).
- OhMyGames AI builds get them (12 Oct 2026 00:50 CET): the library pack ships each picked tank's damage file (index
  `damage_glb` / `damage_bytes`, counted in the 8 MB cap), the kit has `lib.damage(object)` (`omg/kit/index.mjs`, test
  `test/kit_tank_damage.sh`, rule L11 in `omg/kit/LIBRARY.md`) and the builder contract says how to use it. Tanks are picked
  by era (WWI / WWII settings keep their era; others prefer modern, Cold War, WWII, WWI), named models and nations first,
  battlefields bring their nations (Normandy: Sherman + Churchill), Japanese tanks only in Pacific stories
  (`omg/factory/games_library.py`, Factory tests 37). Not done: a real paid AI build with tanks since then.
