"""Markdown report of the spaceship batch for the docs hub (16 Oct 2026). usage:
python3 tools/space/report_space.py "<HH:MM CET>" > ~/forge-build/FORGE-SPACESHIPS-2026-10-16.md   (reads tools/space/stats_space.py)"""
import json, os, subprocess, sys
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
stamp = sys.argv[1] if len(sys.argv) > 1 else ''
d = json.loads(subprocess.run(['python3', f'{ROOT}/tools/space/stats_space.py'], capture_output=True, text=True, check=True).stdout)
rows, tot = d['rows'], d['totals']
FAM = {'fighters': 'Fighters', 'alien': 'Alien vessels', 'ships': 'Spaceships', 'pods': 'Escape pods', 'cruisers': 'Cruisers',
       'battleships': 'Battleships', 'motherships': 'Motherships', 'speeders': 'Speeders'}
carded = [r for r in rows if r['state'] == 'carded']
painted = [r for r in rows if r['painted'] and not r['painted'].startswith('failed')]
running = [r for r in rows if r['state'] in ('running', 'queued', 'built, not checked')]
failed = [r for r in rows if r['state'] == 'check failed']
gem_cost = sum(r['cost'] or 0 for r in rows)
out = [f'# Forge spaceships: {len(carded)} new library models (16 Oct 2026, status {stamp})', '',
       'Review page (updates itself as ships land): https://dashboard.le-borgne.fr/spikes/spaceships-20261016/  ',
       '3D showroom (paints, moving parts, engines, painted copy): https://dashboard.le-borgne.fr/spikes/spaceships-20261016/spaceships.html', '',
       '## Blocked on you', '',
       '- Nothing. Optional: a real test build of a space game on your OhMyGames account (costs credits) to see the ships in a',
       '  game. Say "run a space game test build".', '',
       '## Live in OhMyGames builds (17 Oct 2026, ~13:20 CET)', '',
       '- Cloud library published (387 models, +32 ships, 481 files verified in Google Cloud); the Factory picker is deployed.',
       '- A space brief gets a small fleet (a fighter, a cruiser, a freighter, a shuttle); named classes come too (battleship,',
       '  mothership, escape pod, dropship, mining ship...); alien words put the alien vessels first; genre words pick their',
       '  fighter (retro, pirate, stealth, anime, dieselpunk, hard sci-fi); hover words bring the speeders. City, war and',
       '  medieval games pick exactly as before (checked on the live library).',
       '- The game kit got the spacecraft parts (`lib.parts`: thrusters for flames, muzzles, turrets and guns, rings, doors,',
       '  hangars) and builder law L12; the builder contract adds a spacecraft line when ships are picked.',
       '- Fixed before publishing: 105 guns that would have elevated into the hull and 6 doors that opened inward (signs',
       '  measured from the geometry, new card versions); 5 small craft repacked to the phone texture budget.', '',
       '## In one look', '',
       f'- **{len(carded)} of 32 ships are in the library** (cards in forge-assets), {len(running)} still building, {len(failed)} failed checks.',
       f'- **{len(painted)} have a painted copy** (GPT Image 2 through Codex + our repaint technique).',
       '- Every ship recolours (6 named paints, or any colour), has named moving parts (turrets, guns, canopies, bay doors, rings,',
       '  arms, fans), engine points for flames, no text or insignia (games add their own factions), packed for phones (KTX2 + Draco).',
       f"- Drawn in Blender by **GPT-6 Astra (xhigh)**: {tot['astra']['done']} done, {tot['astra']['avg_min']} min average, Codex subscription; "
       f"**Gemini 4 Argon (high, Antigravity CLI)**: {tot['gemini4']['done']} done, {tot['gemini4']['avg_min']} min average, "
       f'${gem_cost:.2f} list so far (Google grant).',
       '- Concept sheets: 35 Nano Banana Pro pictures (~$4.90 paid); 3 redone because they came out as famous craft (Star Wars X-34',
       '  landspeeder, Halo Pelican-like dropship, NASA orbiter).', '',
       '## The ships', '', '| Ship | Family | Drawn by | Minutes | Triangles | MB | Painted copy | Gemini $ |', '|---|---|---|---|---|---|---|---|']
for r in rows:
    out.append(f"| {r['slug']} | {FAM.get(r['family'], r['family'])} | {r['pen']} | {r['minutes'] or r['state']} | "
               f"{(r['tris'] or 0) // 1000 if r['tris'] else ''}{'k' if r['tris'] else ''} | {r['mb'] or ''} | {r['painted'] or ''} | "
               f"{'%.2f' % r['cost'] if r['cost'] else ''} |")
out += ['', '## How it was made', '',
        '1. A concept sheet per ship (Nano Banana Pro, side/front/rear/top + hero view), checked by eye for look-alikes of famous craft.',
        '2. Blender job per ship (one agent each, 10-12 at once): real sizes from 3 m pods to a 2 km colony ship, tiling hull materials',
        '   for big ships, contract checked by `tools/space/check_space.py` (pivots on their parts, guns under turrets, size, materials).',
        '3. Card in the asset library (`vehicle.space.<class>/<slug>`), showroom + review page republished after every ship.',
        '4. Paint pass (`tools/space/paint_ship.sh`): the ship is rendered from 9 to 21 sides, GPT Image 2 repaints each render, the',
        '   Pixel Match painter projects the pictures back. Ships over 60 m get close-ups along the hull (new opt-in `--segments`',
        '   in forge-repaint), because a full side view of a 400 m ship is a thin strip. Result = a painted copy next to the game model.', '',
        '## Not done / limits', '',
       '- No real game has been built with them yet (offered above).',
       '- The painted copy is static (one mesh, no recolour, no moving parts); games use the normal model. It reads clearly better',
       '  on big pale hulls; on small ships the gain is smaller.',
       '- Some turrets on the biggest ships are merged into the hull; the 5 small craft use 512 px textures (phone budget).',
       '- Not checked on a phone; showroom and library measure 0 errors on the GPU box.']
print('\n'.join(out))
