"""Write job.json + sheet prompt for the SPACECRAFT batch (16 Oct 2026 ~20:30 CET, operator: "massively enrich the library of
models: spaceships, motherships, alien vessels, cruisers, battleships, escape pods, speeders, fighter ships (several genres);
Gemini high or Astra xhigh direct Blender; texture them with Nano Banana Pro or GPT Image 2 + our paint technique").
32 models in 8 showroom families, half drawn by GPT-6 Astra (xhigh, tools/author/launch.sh), half by Gemini 4 Argon (high,
Antigravity CLI, tools/author/launch_agy.sh). job.json "pen" picks the launcher and becomes the card's provenance.author.
usage: python3 tools/space/make_jobs_space.py   (order -> /tmp/space-20261016/order.txt, "<slug> <pen>" per line, pens interleaved)

Contract spacecraft/v1 (flying craft) and hover/v1 (speeders) are written out in FRAME_* / NODES_* below; tools/space/check_space.py
checks them and tools/space/import_space.py turns them into card fields."""
import json, os

ROOT = os.path.expanduser('~/forge-build/forge-assets')
SCR = '/tmp/space-20261016'

FRAME_SHIP = ('Nose toward +Z, up = +Y, +X = the ship\'s LEFT side, centred on X = 0; origin (0,0,0) at the ship\'s centre of mass '
              '(about the middle of the hull), the ship level and flying: landing gear, if the design has any, is RETRACTED with its '
              'doors closed.')
FRAME_POD = ('Upright: the capsule axis along Y with the heat shield at the bottom and the hatch facing +Z, centred on X = 0 and Z = 0; '
             'origin (0,0,0) at the centre of mass.')
FRAME_HOVER = ('Front toward +Z, up = +Y, +X = the vehicle\'s LEFT side, centred on X = 0; origin (0,0,0) on the ground plane directly '
               'below the middle of the vehicle. It HOVERS: nothing touches y = 0, the lowest point sits at the ride height given in '
               'the size line.')

GAME = ('GAME WEIGHT overrides the budget above: every texture image at most 1024 px, ORM / occlusion maps at most 512 px; share '
        'baked texture sets between parts and use tiling materials + trim textures on big surfaces. ')
BIG = ('BIG SHIP: a 1024 bake cannot hold a hull this size: use tiling hull-plate materials and trim textures (panel strips, window '
       'strips, vents) with world-scale UVs. Detail must read at three distances: the silhouette (big masses, towers, engine blocks), '
       'the middle (superstructure, turrets, hangar mouths, antenna forests, armour belts) and close up (greebles, pipes, panel '
       'seams, rows of lit windows at human scale). Small parts may be instanced/linked duplicates. ')
SHIP_NODES = ('Separate named mesh nodes: Hull (everything fixed to the hull). Every MOVING part is its own node with its object origin '
              'ON its pivot: Turret_1..Turret_n (each gun turret, origin on its vertical traverse axis, turns about its local Y) each with '
              'a child Gun_1..Gun_n (the barrels, origin on the elevation trunnion axis, elevates about X); Canopy (cockpit canopy, origin '
              'on its hinge) on craft with a canopy; and the extra moving parts named in the description. Empty nodes (no mesh): '
              'Thruster_1..Thruster_n at the centre of every main engine nozzle exit (games put flame and glow there; exhaust points to '
              '-Z), Muzzle_1..Muzzle_n at every barrel tip (child of its Gun, or of Hull for fixed guns), Hardpoint_1..n (missile and '
              'torpedo launch points), Seat_Pilot (pilot hip point) on craft with a cockpit, Camera_Chase (a good third-person chase '
              'camera point behind and above), Light_Nav_L (left tip, red), Light_Nav_R (right tip, green), Light_Beacon. '
              'Materials: the glowing inside of every engine nozzle = one material named "Engines" (emissive, colour as described, '
              'modest strength, games raise it); lit windows, running lights and glowing details = one material "Lamps" (emissive); '
              'cockpit or bridge glazing = one material "Glass" (alpha BLEND, tinted) with a visible cockpit (seat, panels, stick) '
              'behind it on small craft. In nodes.json add "axes": for every moving node, the unit axis it turns about in its '
              'parent\'s space. ')
HOVER_NODES = ('Separate named mesh nodes: Hull (everything fixed). Every MOVING part is its own node with its object origin ON its '
               'pivot (the extra moving parts named in the description). Empty nodes (no mesh): Seat_Driver (and Seat_Passenger / '
               'Seat_Gunner where it has them; Seat_Rider on a bike), Hand_L, Hand_R (grip or yoke points), Foot_L, Foot_R, '
               'Thruster_1..n (every engine exhaust centre, exhaust toward -Z), Lift_1..n (the centre of every repulsor/lift pad or '
               'fan underneath: games put the ground glow and dust there), Camera_Chase, Light_Head_L, Light_Head_R, Light_Tail_L, '
               'Light_Tail_R. Materials: glowing engine exhausts and lift pads = "Engines" (emissive); lights = "Lamps" (emissive); '
               'windscreen = "Glass" (alpha BLEND). In nodes.json add "axes" for every moving node. ')
PIVOTS = ('MOVING PARTS: never apply transforms to a moving node. Check it in Blender before export: rotate each moving node 30 degrees '
          'in a test render; nothing may leave its place. ')
NOMARK = ('No text, numbers, insignia, faction emblems, flags or logos anywhere (games add their own factions). ')
ORIGINAL = ('ORIGINAL DESIGN: never model a famous film, TV, anime or game ship (no X-wing, TIE, Star Destroyer, Millennium Falcon, '
            'Enterprise, Serenity, Normandy, Viper, Valkyrie, Gundam, Halo, Homeworld, EVE, Elite or Expanse ship): if the sheet looks '
            'like one, keep its proportions and parts but make the silhouette details, nose and engines your own. ')
RENDERS = ('RENDERS: final.png and paints.png on a dark space backdrop (near black with a faint blue gradient, no ground) lit by '
           'a strong white key light from the upper front left plus a soft cool fill, so every part reads. ')
RENDERS_HOVER = ('RENDERS: final.png and paints.png on a plain light ground in soft daylight, with the vehicle hovering. ')
SCRATCH = ('Keep this directory clean: put any helper tools you install (node_modules, vendored three.js, browser checks) under '
           '/tmp, never here. ')


def time_text(big):
    a, b = (40, 80) if big else (30, 60)
    return (f'Pace: deliver a first complete GLB within about {a} minutes, then use what is left of about {b} minutes to improve '
            'what the renders show is weakest. Use Cycles with the GPU (OptiX/CUDA) and modest samples for bakes and renders. ')


def paint(default, paints, extra=''):
    return ('PAINT CONTRACT (how games get faction colours of one model): the main hull colour lives in ONE material named exactly '
            '"Paint". Its base colour TEXTURE holds only light neutral detail (near white, with panel lines, grey grime, engine '
            'scorch, micro-meteorite pitting and chipped edges baked in) and its baseColorFactor holds the paint colour; default '
            f'factor = {default}. A game changes that factor, so nothing else (bare metal, engines, glass, lamps, weapons, cockpit) '
            f'may use Paint. {extra}In nodes.json add "paints": six good paints for this model as linear RGB triples with names, '
            f'the default first, in the spirit of: {paints}; and render paints.png: a 3x2 grid of the same 3/4 view in those six '
            'paints (EEVEE or low-sample Cycles) to prove the recolour works. ')


SHEET = ('Video game spacecraft design turnaround plate, photorealistic CG concept art, on a plain light grey background. {desc} '
         'Original design, not from any film, series, anime or game. No logos, no insignia, no flags, no text markings, no numbers '
         'on the craft. Real size {size}. Layout: big orthographic side view across the top, front view, rear view and top view '
         'below, and a 3/4 front hero view; callouts naming the main parts and dimensions in metres; material swatches (hull paint, '
         'bare metal, heat-scorched metal, glass, engine glow{extra}). Rich believable construction detail: panel lines, hatches, '
         'thrusters, vents, light wear. No other text.')
SHEET_HOVER = ('Video game vehicle design turnaround plate, photorealistic CG concept art, on a plain light grey background. {desc} '
               'Original design, not from any film, series, anime or game. No logos, no insignia, no text markings, no numbers. Real '
               'size {size}. Layout: big orthographic side view across the top, front view, rear view and top view below, and a 3/4 '
               'front hero view of it hovering above the ground; callouts naming the main parts and dimensions in metres; material '
               'swatches (paint, bare metal, rubber, glass, engine glow{extra}). Rich believable construction detail, light wear. '
               'No other text.')

MIL = 'naval grey, gunmetal, olive drab, desert sand, arctic white, deep navy, black, crimson'
CIV = 'white, industrial orange, safety yellow, signal red, teal, pale blue, charcoal, sand'
ALIEN = 'deep violet, bone white, pearl, abyssal teal, oxblood, obsidian, jade, amber'
OPERA = 'warm white, light grey, rebel red, imperial grey, midnight blue, olive, gold, black'

# (slug, pen, class, family, title, description, real size, default paint, paint spirit, extra paint/part note, tags, tris, big)
JOBS = [
 # --- fighters, several genres ---
 ('interceptor-hardsf', 'astra', 'fighter', 'fighters', 'Hard sci-fi interceptor',
  'A realistic near-future military space interceptor (hard science fiction, real spaceflight engineering): a slim armoured '
  'fuselage with a two-seat tandem cockpit under a small faceted armoured canopy, one big fusion main engine with a bell nozzle at the '
  'rear, four RCS thruster quads, folding heat-radiator panels along the sides, a nose railgun barrel, sensor blisters, cylindrical '
  'propellant tanks; no wings (there is no air in space).',
  '16.0 m long, 6.5 m wide, 4.2 m high', '[0.55, 0.56, 0.55] (light grey)', MIL,
  'Extra moving parts: Radiator_L, Radiator_R (radiator panels, origin on their hinge, deployed). ', ['hard-sci-fi', 'near-future', 'realistic', 'interceptor'], '40k to 90k', False),
 ('starfighter-opera', 'gemini4', 'fighter', 'fighters', 'Space-opera starfighter',
  'An original space-opera starfighter (cinematic space-battle style, our own design): a sleek arrowhead fuselage with a bubble canopy, '
  'two swept main wings with a laser cannon on each wingtip and a small dorsal fin, two small canards, '
  'twin big round engines at the rear with glowing nozzles, missile hardpoints under the wings, panel lines and greebles.',
  '13.5 m long, 11.0 m wingspan, 3.4 m high', '[0.75, 0.74, 0.70] (warm white)', OPERA, 'The two main wings stay flat (never an X layout). ', ['space-opera', 'starfighter', 'dogfight'], '40k to 90k', False),
 ('heavy-bomber-opera', 'astra', 'bomber', 'fighters', 'Heavy assault bomber',
  'A heavy space-opera assault bomber: a thick armoured wedge body with a stepped two-seat cockpit, a dorsal twin-gun turret and a '
  'chin gun turret, a long torpedo bay with doors under the belly, three big engines in a row at the rear, short stubby wings with '
  'missile racks.',
  '24.0 m long, 16.0 m wingspan, 5.5 m high', '[0.20, 0.22, 0.24] (gunmetal)', MIL,
  'Extra moving parts: BayDoor_L, BayDoor_R (torpedo bay doors, origin on their hinges, closed). ', ['space-opera', 'bomber', 'heavy'], '50k to 110k', False),
 ('rocket-fighter-retro', 'gemini4', 'fighter', 'fighters', 'Retro rocket fighter',
  'A 1950s pulp science-fiction rocket fighter (atomic-age raygun gothic): a polished chrome-and-enamel cigar fuselage with a pointed '
  'nose cone, a big glass bubble canopy, three swept tail fins with ball tips, a ring fin around the rear rocket nozzle, two ray-gun '
  'cannons with coil rings on the nose, rivets and chrome trim strips.',
  '11.0 m long, 6.8 m fin span, 3.6 m high', '[0.65, 0.05, 0.04] (cherry red)', 'cherry red, mint, cream, sky blue, chrome silver, '
  'black, tangerine, turquoise', 'Chrome trims and nose cone are bare metal, not Paint. ', ['retro', 'pulp', 'atomic-age', 'raygun-gothic'], '40k to 90k', False),
 ('variable-fighter-anime', 'gemini4', 'fighter', 'fighters', 'Anime-style swing-wing fighter',
  'An original anime-style space fighter (crisp angular Japanese animation mecha design, our own): a long slim angular fuselage with a '
  'sharp chisel nose and a long canopy, swing wings at mid sweep, twin vertical tails canted outward, two big engine nacelles with '
  'square-to-round nozzles, a gun pod under the fuselage, missile launchers in the wing roots, crisp panel lines and contrast '
  'stripes as geometry.',
  '15.8 m long, 13.0 m wingspan, 4.0 m high', '[0.85, 0.85, 0.88] (white)', OPERA,
  'Extra moving parts: Wing_L, Wing_R (swing wings, origin on the wing pivot, sweep about Y). Contrast stripes are a second '
  'non-Paint material. ', ['anime', 'mecha-style', 'swing-wing'], '40k to 90k', False),
 ('stealth-interceptor', 'astra', 'fighter', 'fighters', 'Stealth interceptor',
  'A cyberpunk stealth space interceptor: an all-faceted flat diamond body made of angled planes (no curves), a flush faceted canopy, '
  'two buried engines with flattened slot nozzles, internal weapon bays, thin red emissive accent lines along some facet edges, '
  'radar-absorbent matte surface.',
  '14.0 m long, 9.5 m wide, 2.6 m high', '[0.04, 0.04, 0.045] (matte black)', MIL,
  'Extra moving parts: BayDoor_L, BayDoor_R (weapon bay doors, origin on their hinges, closed). Engines glow red-orange. ',
  ['stealth', 'cyberpunk', 'faceted'], '30k to 80k', False),
 ('dieselpunk-space-fighter', 'astra', 'fighter', 'fighters', 'Dieselpunk space fighter',
  'A dieselpunk space fighter (Second World War warbird engineering in space): a riveted armour-plated fuselage with an armoured '
  'greenhouse canopy, gull wings carrying four heavy autocannons with ribbed barrels, a big radial-engine-like reactor cowling at the '
  'nose with exhaust stacks, three rocket engines in the tail, a bulky tail fin, ammunition feed fairings, chipped paint over steel.',
  '12.5 m long, 13.0 m wingspan, 4.0 m high', '[0.25, 0.30, 0.20] (olive)', MIL, '', ['dieselpunk', 'warbird', 'ww2-in-space'], '40k to 90k', False),
 ('pirate-scrap-fighter', 'gemini4', 'fighter', 'fighters', 'Pirate scrap fighter',
  'A space-pirate scrap fighter (junk-built): a salvaged engine block with a cockpit pod welded on, mismatched armour plates in '
  'different metals bolted on, an oversized cannon on one side, exposed cables and pipes, patched plates, one big engine and two '
  'small ones, spikes and a ram on the nose.',
  '12.0 m long, 9.0 m wide, 4.5 m high', '[0.45, 0.12, 0.06] (rust red)', 'rust red, faded green, dirty yellow, black, '
  'patchwork grey, toxic green, purple, sand', 'Only the largest painted plates are Paint; bare and rusty plates are not. ',
  ['pirate', 'junk', 'scrap', 'space-opera'], '40k to 90k', False),
 # --- alien vessels ---
 ('alien-bio-fighter', 'gemini4', 'fighter', 'alien', 'Bio-organic alien fighter',
  'An alien bio-organic fighter that was grown, not built: a chitin carapace of overlapping armour plates like a beetle, rib-like '
  'struts, membrane wing fins, glowing bioluminescent vents and a glowing plasma sac at the rear, two organic cannon spurs at the '
  'front, no straight lines, no rivets, a wet glossy shell.',
  '14.0 m long, 12.0 m wide, 4.5 m high', '[0.18, 0.10, 0.22] (deep violet)', ALIEN,
  'The carapace plates are Paint (glossy); membranes and the glowing parts are not. Engines glow acid green. No Glass needed: the '
  'pilot sits under a translucent membrane dome. ', ['alien', 'organic', 'biomechanical'], '40k to 90k', False),
 ('alien-crystal-vessel', 'gemini4', 'cruiser', 'alien', 'Crystalline alien vessel',
  'A crystalline alien vessel: a cluster of long faceted crystal shards around a glowing core, held in a dark metallic cradle of thin '
  'arcs, energy veins running along the crystals, no windows, no visible guns, a ring of light at the rear as its engine.',
  '60 m long, 30 m wide, 26 m high', '[0.12, 0.30, 0.45] (sea-glass blue)', ALIEN,
  'The crystal shards are Paint (glossy, near-white detail of facets and inner fractures); the cradle is dark metal. Extra moving '
  'part: Core (the glowing core, origin at its centre, spins about Z). ', ['alien', 'crystal', 'energy'], '30k to 90k', False),
 ('alien-saucer', 'astra', 'saucer', 'alien', 'Alien flying saucer',
  'A realistic, believable alien flying saucer (classic disc, our own design): a wide double-convex metal disc with a raised central '
  'dome, an outer rim with a ring of recessed light ports and a rotating outer ring, a belly emitter lens, three landing legs '
  'retracted into flush pods, seamless panel lines, subtle iridescent metal.',
  '28 m diameter, 8.5 m high', '[0.55, 0.57, 0.60] (silver)', ALIEN,
  'Extra moving part: Ring (the outer rim ring, origin on the vertical axis, spins about Y). The emitter lens is Engines. ',
  ['alien', 'saucer', 'ufo', 'classic'], '30k to 80k', False),
 ('alien-harvester', 'astra', 'mothership', 'alien', 'Alien harvester mothership',
  'A huge alien harvester mothership: a dark elongated segmented hull like a deep-sea creature, hanging tentacle-like harvesting arms '
  'underneath, rows of glowing amber vents, spines along the back, a big glowing maw at the front, no human-style windows.',
  '420 m long, 160 m wide, 120 m high', '[0.10, 0.11, 0.10] (dark carapace)', ALIEN,
  'Extra moving parts: Arm_1..Arm_6 (the harvesting arms, origin on their root pivot). ', ['alien', 'mothership', 'harvester', 'big'], '80k to 200k', True),
 ('alien-elegant-cruiser', 'gemini4', 'cruiser', 'alien', 'Elegant alien cruiser',
  'An elegant cruiser of an ancient advanced alien race: a long smooth flowing hull like a stretched seed pod, sweeping crescent '
  'wings, glowing energy channels along the hull, a separate ring floating around the waist, two smooth weapon pods, a pearl-white '
  'shell with gold trims.',
  '180 m long, 90 m wide, 40 m high', '[0.80, 0.78, 0.72] (pearl)', ALIEN,
  'Gold trims are bare metal. Extra moving parts: Ring (the waist ring, origin on the ship axis, spins about Z), Turret_1, Turret_2 '
  '(the weapon pods). ', ['alien', 'cruiser', 'elegant'], '60k to 160k', True),
 # --- spaceships ---
 ('crew-shuttle', 'astra', 'shuttle', 'ships', 'Crew shuttle',
  'A realistic near-future crew shuttle that lands on planets: a compact blended lifting-body shaped like a flattened wedge with '
  'rounded edges (no large delta wing and no single tall tail fin), two small outward-canted tail fins at the rear corners, a black '
  'heat-shield belly, a cockpit with four forward windows set into the nose, a side crew hatch, a rear cargo ramp, two main engines '
  'and RCS thruster clusters, landing gear retracted under flush doors.',
  '26 m long, 18 m wingspan, 7 m high', '[0.85, 0.85, 0.83] (white)', CIV,
  'The heat-shield tiles are not Paint. Extra moving parts: Ramp (rear ramp, origin on its hinge, closed), Hatch (crew hatch, origin '
  'on its hinge, closed). ', ['shuttle', 'near-future', 'transport'], '50k to 110k', False),
 ('cargo-hauler', 'gemini4', 'freighter', 'ships', 'Cargo hauler',
  'A long-haul space cargo hauler (blue-collar space trucker): a cab module at the front with a big windscreen and lights, a long open '
  'truss spine carrying twelve standard cargo containers clamped in two rows, a big reactor and engine block at the rear with four '
  'nozzles, radiator fins, antennae, worn industrial paint with plain hazard stripes.',
  '120 m long, 28 m wide, 24 m high', '[0.80, 0.45, 0.05] (industrial orange)', CIV,
  'Containers are their own material (games may tint them). ', ['freighter', 'cargo', 'industrial', 'civilian'], '60k to 150k', True),
 ('mining-ship', 'astra', 'miner', 'ships', 'Asteroid mining ship',
  'An industrial asteroid mining ship: a boxy armoured hull with a big front drill head and two articulated grabber arms, ore hoppers '
  'on the sides, floodlight banks, a cockpit bridge on top, two big engines, scrape marks and dirt.',
  '65 m long, 30 m wide, 22 m high', '[0.85, 0.65, 0.05] (safety yellow)', CIV,
  'Extra moving parts: Drill (drill head, origin on its axis, spins about Z), Arm_L, Arm_R (grabber arms, origin on the shoulder '
  'pivots). ', ['mining', 'industrial', 'civilian'], '60k to 140k', True),
 ('science-explorer', 'gemini4', 'explorer', 'ships', 'Deep-space explorer',
  'A deep-space exploration and science vessel: a long slender spine, a forward command module with an observation dome, a rotating '
  'habitat ring in the middle, big solar and radiator arrays, a large dish antenna, sensor booms, a fusion drive section at the rear '
  'with a big nozzle.',
  '160 m long, 70 m wide, 70 m high', '[0.82, 0.82, 0.80] (white)', CIV,
  'Extra moving parts: Ring (habitat ring, origin on the ship axis, spins about Z), Radar (dish, origin on its mount pivot). ',
  ['explorer', 'science', 'hard-sci-fi'], '60k to 150k', True),
 ('corvette-gunship', 'astra', 'corvette', 'ships', 'Corvette gunship',
  'A military corvette gunship (fast patrol warship): an aggressive arrowhead armoured hull, a raised bridge with slit windows, two '
  'dorsal twin-gun turrets and one ventral turret, missile cells on the flanks, four big engines.',
  '85 m long, 32 m wide, 18 m high', '[0.35, 0.37, 0.40] (navy grey)', MIL, '', ['military', 'corvette', 'gunship', 'patrol'], '60k to 140k', True),
 ('troop-dropship', 'gemini4', 'dropship', 'ships', 'Troop dropship',
  'An armoured military troop dropship: a wide flat lifting-body hull with short stub wings, a glazed two-seat cockpit in a rounded '
  'chin pod under a raised nose, two big ducted lift fans buried in the wing roots (grilles on top and underneath), two rear main '
  'thrusters, a rear loading ramp, sliding side doors with door guns, a chin cannon turret, angular armour panels in two tones.',
  '28 m long, 22 m wide, 7 m high', '[0.24, 0.27, 0.20] (olive)', MIL,
  'Extra moving parts: Ramp (origin on its hinge, closed), Door_L, Door_R (sliding side doors, origin on the slide line, closed), '
  'Fan_L, Fan_R (lift fans, origin on their axis, spin about Y), Turret_1 with child Gun_1 (chin cannon). The second armour tone '
  'is its own material. ', ['military', 'dropship', 'troop', 'transport'], '50k to 110k', False),
 # --- escape pods ---
 ('escape-pod-capsule', 'astra', 'pod', 'pods', 'Escape pod',
  'A realistic three-person escape pod: a squat cone-shaped capsule with a thick ablative heat shield at the base, a round side hatch '
  'with a small window, a ring of small RCS thrusters, a parachute housing at the top, handrails, a beacon light, scorch marks.',
  '3.4 m high, 3.0 m diameter', '[0.85, 0.35, 0.05] (rescue orange)', CIV,
  'The heat shield is not Paint. Extra moving part: Hatch (origin on its hinge, closed). Thruster_1 is the main retro-rocket under '
  'the heat shield (exhaust down) and the RCS jets are Rcs_1..Rcs_n empties. ', ['escape-pod', 'capsule', 'rescue'], '15k to 50k', False),
 ('lifeboat-pod', 'gemini4', 'pod', 'pods', 'Lifeboat pod',
  'A twelve-person sci-fi lifeboat: a rounded bullet-shaped hull with a ring of small windows, a docking collar with a hatch at the '
  'top, short stabiliser fins, four small engines at the rear, a beacon, high-visibility orange and white areas.',
  '9.0 m long, 4.0 m diameter', '[0.85, 0.35, 0.05] (rescue orange)', CIV,
  'The white areas are their own material. Extra moving part: Hatch (origin on its hinge, closed). ', ['escape-pod', 'lifeboat', 'rescue'], '20k to 60k', False),
 # --- cruisers ---
 ('light-cruiser', 'astra', 'cruiser', 'cruisers', 'Light cruiser',
  'A space-opera light cruiser: a long slab hull with a narrow bow, a tall command tower near the '
  'stern, four twin-gun turrets (two dorsal, two ventral), point-defence guns, a hangar opening under the bow, four big engines in a '
  'block at the stern, armour belts, many lit window strips.',
  '320 m long, 70 m wide, 60 m high', '[0.60, 0.61, 0.62] (light grey)', MIL, 'The hull is a long slab, never a triangle or dagger. ', ['cruiser', 'military', 'space-opera'], '80k to 200k', True),
 ('heavy-cruiser-naval', 'astra', 'cruiser', 'cruisers', 'Heavy cruiser (naval style)',
  'A heavy space cruiser in wet-navy battleship style: a long ship-like hull with a sharp flared bow, a stepped bridge '
  'superstructure, three triple-barrel main gun turrets on top and one under the hull, secondary twin turrets along the flanks, '
  'missile batteries, a big engine cluster at the stern.',
  '450 m long, 70 m wide, 90 m high', '[0.32, 0.34, 0.36] (dark grey)', MIL, '', ['cruiser', 'naval', 'heavy'], '80k to 200k', True),
 ('hardsf-cruiser', 'gemini4', 'cruiser', 'cruisers', 'Hard sci-fi cruiser',
  'A realistic hard science-fiction military cruiser: a long spine of modules, a forward armoured command and weapons section with a '
  'spinal railgun running through the hull, big diamond-shaped radiator wings, spherical propellant tanks, drone launch racks, point-'
  'defence turrets, a fusion drive with a large magnetic nozzle.',
  '260 m long, 110 m wide, 40 m high', '[0.70, 0.70, 0.68] (pale grey)', MIL, '', ['cruiser', 'hard-sci-fi', 'realistic'], '80k to 180k', True),
 # --- battleships ---
 ('dreadnought', 'astra', 'battleship', 'battleships', 'Dreadnought battleship',
  'A massive space dreadnought battleship: a thick armoured hull of layered armour plates, a tall bridge tower, six heavy triple-gun '
  'turrets (four dorsal, two ventral), dozens of point-defence guns, torpedo tubes in the bow, a huge engine block with eight '
  'nozzles, glowing window strips, hangar slits.',
  '900 m long, 180 m wide, 160 m high', '[0.30, 0.32, 0.34] (dark grey)', MIL, '', ['battleship', 'dreadnought', 'military'], '100k to 220k', True),
 ('railgun-battleship', 'gemini4', 'battleship', 'battleships', 'Spinal railgun battleship',
  'A battleship built around one giant spinal railgun: the twin rails run the full length of the hull and open at the bow, heavy '
  'armour wraps around them, capacitor banks along the sides glow blue, two rows of broadside turrets, a command tower aft, four huge '
  'engines.',
  '1100 m long, 160 m wide, 140 m high', '[0.70, 0.68, 0.62] (bone white)', MIL, '', ['battleship', 'railgun', 'military'], '100k to 220k', True),
 # --- motherships ---
 ('carrier-mothership', 'astra', 'mothership', 'motherships', 'Carrier mothership',
  'A huge fleet carrier mothership: a long flat-topped hull with two long hangar bays opening along the sides (glowing inside), a '
  'command island tower, defensive turrets, a forest of antennae, a massive engine section.',
  '1400 m long, 380 m wide, 220 m high', '[0.55, 0.55, 0.52] (warm grey)', MIL,
  'Add empties Hangar_1..Hangar_n at the launch slots (small craft leave from there along +Z or sideways). ', ['mothership', 'carrier', 'fleet'], '100k to 220k', True),
 ('colony-mothership', 'gemini4', 'mothership', 'motherships', 'Colony mothership',
  'A generation colony mothership: a long spine carrying a forward shield dome, three huge rotating habitat rings with lit windows, '
  'cargo and fabrication modules, a docking hub with small shuttles docked, and a vast fusion engine section with radiator wings.',
  '2000 m long, 600 m wide, 600 m high', '[0.80, 0.80, 0.78] (white)', CIV,
  'Extra moving parts: Ring_1, Ring_2, Ring_3 (habitat rings, origin on the ship axis, spin about Z). Add empties Dock_1..Dock_n. ',
  ['mothership', 'colony', 'civilian'], '100k to 220k', True),
 # --- speeders (hover/v1) ---
 ('speeder-bike', 'gemini4', 'speeder', 'speeders', 'Speeder bike',
  'A one-rider hover speeder bike built like a sport motorbike without wheels: a compact muscular body with the rider seat, '
  'handlebars with grips, foot pegs, two short steering vanes on outriggers at the front, a turbine engine under the seat with a '
  'glowing exhaust, repulsor lift pads underneath glowing softly.',
  '4.2 m long, 1.4 m wide, 1.25 m high, hovering 0.5 m above the ground', '[0.10, 0.25, 0.15] (racing green)', CIV,
  'Extra moving parts: Vane_L, Vane_R (steering vanes, origin on their hinge). Use Seat_Rider instead of Seat_Driver. Keep it '
  'compact: no long forward rods. ',
  ['speeder', 'hover-bike', 'sci-fi'], '30k to 80k', False),
 ('landspeeder', 'astra', 'speeder', 'speeders', 'Open-top landspeeder',
  'An open-top two-seat sports hover car: a sleek low wedge body with sculpted flanks and a raised rear deck, a low wraparound '
  'windscreen, two seats side by side, a steering yoke, twin turbine engines faired INTO the rear flanks with glowing exhaust rings '
  '(no engines on top), a small rear spoiler fin, four repulsor glow pads under the body, chrome trim.',
  '4.8 m long, 2.2 m wide, 1.3 m high, hovering 0.45 m above the ground', '[0.75, 0.55, 0.20] (sand gold)', CIV,
  'Extra moving part: Yoke (steering yoke, origin on its column). ', ['speeder', 'landspeeder', 'hover-car'], '30k to 80k', False),
 ('military-hover-speeder', 'gemini4', 'speeder', 'speeders', 'Military recon speeder',
  'An armed military hover recon speeder for two crew (driver and gunner): an angular armoured open-top hull, a rear pintle-mounted '
  'twin gun, front air intakes, four vectoring lift fans under the hull, side skirts, an antenna, storage boxes.',
  '6.5 m long, 3.0 m wide, 2.1 m high, hovering 0.5 m above the ground', '[0.30, 0.33, 0.24] (field green)', MIL,
  'Extra moving parts: Turret_1 with child Gun_1 (the pintle gun) and Muzzle_1, Fan_FL, Fan_FR, Fan_RL, Fan_RR (lift fans, origin '
  'on their axis, spin about Y). Add Seat_Gunner. ', ['speeder', 'military', 'hover'], '30k to 90k', False),
 ('hover-cargo-skiff', 'astra', 'speeder', 'speeders', 'Cargo hover skiff',
  'An open cargo hover skiff (flat utility barge floating over the ground): a long flat deck with railings and cargo crates, a small '
  'driver station at the rear with controls, four big lift-fan nacelles at the corners, worn industrial look.',
  '9.0 m long, 3.8 m wide, 2.4 m high, hovering 0.6 m above the ground', '[0.50, 0.42, 0.30] (worn tan)', CIV,
  'Crates are their own material. Extra moving parts: Fan_FL, Fan_FR, Fan_RL, Fan_RR (lift fans, origin on their axis). ',
  ['speeder', 'skiff', 'utility'], '30k to 90k', False),
]

FAMILIES = {'fighters': 'Fighters (several genres)', 'alien': 'Alien vessels', 'ships': 'Spaceships: shuttles, freighters, gunships',
            'pods': 'Escape pods', 'cruisers': 'Cruisers', 'battleships': 'Battleships', 'motherships': 'Motherships',
            'speeders': 'Speeders'}


def main():
    os.makedirs(SCR, exist_ok=True)
    order = []
    for slug, pen, cls, fam, title, desc, size, default, spirit, extra, tags, tris, big in JOBS:
        hover = fam == 'speeders'
        frame = FRAME_HOVER if hover else FRAME_POD if fam == 'pods' and slug == 'escape-pod-capsule' else FRAME_SHIP
        nodes = (GAME + (BIG if big else '') + (HOVER_NODES if hover else SHIP_NODES) + paint(default, spirit, extra) + PIVOTS
                 + NOMARK + ORIGINAL + (RENDERS_HOVER if hover else RENDERS) + SCRATCH + time_text(big))
        jd = f'{ROOT}/jobs/{slug}-v1'
        os.makedirs(jd, exist_ok=True)
        j = dict(id=f'vehicle.space.{cls}/{slug}', version=1, name=f'{desc[2:-1]} (the one on sheet.jpg)', title=title, slug=slug,
                 refs=['sheet.jpg'], size=size, tris=tris, mats=9, effort='xhigh' if pen == 'astra' else 'high', frame=frame,
                 nodes=nodes, family=fam, pen=pen, tags=tags + (['big'] if big and 'big' not in tags else []),
                 contract='hover/v1' if hover else 'spacecraft/v1')
        json.dump(j, open(f'{jd}/job.json', 'w'), indent=1)
        sheet = SHEET_HOVER if hover else SHEET
        open(f'{jd}/sheet_prompt.txt', 'w').write(sheet.format(desc=desc, size=size, extra=''))
        order.append((slug, pen, big))
    # big and small alternate inside each pen (big ones take longest, small ones land early for the review page), Astra and
    # Gemini interleaved so both pens run from the start
    def mix(xs):
        bb, ss = [o for o in xs if o[2]], [o for o in xs if not o[2]]
        return [x for pair in zip(bb, ss) for x in pair] + bb[len(ss):] + ss[len(bb):]
    a = mix([o for o in order if o[1] == 'astra'])
    g = mix([o for o in order if o[1] == 'gemini4'])
    inter = [x for pair in zip(a, g) for x in pair] + a[len(g):] + g[len(a):]
    open(f'{SCR}/order.txt', 'w').write(''.join(f'{s} {p}\n' for s, p, _ in inter))
    print(len(JOBS), 'jobs ->', f'{SCR}/order.txt', '| astra', len(a), 'gemini4', len(g))


if __name__ == '__main__':
    main()
