From 2ba37e3d9e8523f1fa1595a4a39832309f6f3f02 Mon Sep 17 00:00:00 2001 From: Nic Date: Sat, 18 Jul 2026 05:39:16 +0200 Subject: [PATCH] docs(assets): integrate M3 hub production flow --- docs/ROADMAP.md | 22 +- .../2026-07-12-asset-pipeline-free-options.md | 9 +- docs/assets/prompts/README.md | 15 +- .../assets/prompts/m3-hubs/01-environments.md | 200 ++++++++ docs/assets/prompts/m3-hubs/02-npcs.md | 134 +++++ .../m3-hubs/03-review-and-integration.md | 163 ++++++ docs/assets/prompts/m3-hubs/README.md | 169 +++++++ docs/assets/prompts/m3-hubs/manifest.json | 67 +++ .../2026-07-18-m3-hub-asset-production.md | 464 ++++++++++++++++++ 9 files changed, 1231 insertions(+), 12 deletions(-) create mode 100644 docs/assets/prompts/m3-hubs/01-environments.md create mode 100644 docs/assets/prompts/m3-hubs/02-npcs.md create mode 100644 docs/assets/prompts/m3-hubs/03-review-and-integration.md create mode 100644 docs/assets/prompts/m3-hubs/README.md create mode 100644 docs/assets/prompts/m3-hubs/manifest.json create mode 100644 docs/superpowers/plans/2026-07-18-m3-hub-asset-production.md diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 1751bc4..36c259e 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,6 @@ # Sector Zero — Master Roadmap -**Updated 2026-07-17** (G0 Atlas implemented; final manual closure playtest pending). +**Updated 2026-07-18** (G0 Atlas merged; final manual closure playtest pending; M3 asset lane specified). This is the single entry point. Every other doc is either DONE, absorbed here, or linked below with its authority noted. @@ -79,7 +79,12 @@ DOOM Phase 1-2 regen at scale via the proven pipeline, in visibility order: 13 s enemies → 8 bosses → FP/boarding billboards (8-yaw via TRELLIS.2→headless Blender + the engine yaw-selector enabler, spec 2026-07-05 §5.4) → hub interior tilesets/props (feeds M3) → backgrounds. Style LoRA once ~30 accepted. Runs alongside systemic work — -different lane, no file conflicts. **Spec status: ready** (pipeline doc + style guide). +different lane, no file conflicts. Each systemic slice declares its asset slots, exact +runtime paths/dimensions, fallback, and visual acceptance evidence before generation; +art is produced in parallel, reviewed at intended renderer size, and registered only when a +real consumer exists. +There is no runtime AI asset generation. **Spec status: operational** (pipeline doc, +master style guide, and `assets/prompts/m3-hubs/`). ### G0 — The Atlas (continuous-galaxy substrate) — IMPLEMENTED, FINAL LIVE CLOSURES PENDING Fresh canonical galaxy run + persistent vessel coordinate + continuous local-sector map @@ -95,15 +100,20 @@ launch, and all three operation presentations were exercised in the production e The remaining acceptance work is the hands-on touch pass plus manually finishing the hostile success/failure/emergency closures, Kepler, Ashfall sortie, and a Region POI; their exact outcomes and idempotency are already covered by deterministic tests. See -`playtests/2026-07-16-g0-atlas.md`. **Spec status: implementation complete on the feature -branch; do not mark DONE until those final live closure paths are recorded.** +`playtests/2026-07-16-g0-atlas.md`. **Spec status: merged via PR #16; do not mark DONE +until those final live closure paths are recorded.** ### M3 — Phase 3: Hubs (places worth entering, now located) Cantina, Marketplace, Town Hall hand-authored interiors + interior NPCs w/ schedules + faction dialog depth + **bulletin board v1**: operations from the spec's §F Quest -types (typed, unused, waiting in colonyTypes.ts 454-466; cycleProcessor step8 stub +types (typed, unused, waiting in colonyTypes.ts 469-482; cycleProcessor step8 stub exists). Marketplace generalizes `marketContext`. **Spec status: ready** (colony spec -Phase 3 + §F). +Phase 3 + §F). Asset production is part of this milestone, not a polish pass: three +reusable hub environment kits (wall/floor/ceiling plus facade/props) and eight paired NPC +portrait/billboard identities ship alongside the code. The first art vertical slice is +the Cantina, then Marketplace, then Town Hall; see +`superpowers/plans/2026-07-18-m3-hub-asset-production.md`. General tier promotion and +district growth remain outside this asset plan and must not be invented while producing art. ### M4 — The Decay Arc & Emergent Antagonists The user's stakes decision, formalized. Colony health drives a staged arc over many cycles: diff --git a/docs/assets/2026-07-12-asset-pipeline-free-options.md b/docs/assets/2026-07-12-asset-pipeline-free-options.md index 1677bf1..1888f07 100644 --- a/docs/assets/2026-07-12-asset-pipeline-free-options.md +++ b/docs/assets/2026-07-12-asset-pipeline-free-options.md @@ -1,12 +1,19 @@ # Asset Pipeline — Free Options (Decision Doc) -**Date:** 2026-07-12 · **Status:** RECOMMENDED, awaiting user sign-off +**Date:** 2026-07-12 · **Status:** ACCEPTED AND OPERATIONAL (roadmap authority updated 2026-07-18) **Question:** "Currently I make my own assets and import them — is there a better way? Can we source or generate them? Free options only (I have Claude Max + Codex/ChatGPT max-tier subs)." Research method: 5 parallel research agents (one per lane, ~200 live page fetches), then an adversarial verification pass re-checking the 10 load-bearing claims against primary sources (GitHub repos, HuggingFace model cards, official pricing pages). Verified July 12, 2026. +The recommendation has since been proven in production on the quartermaster identity/walk +frames, the mine wall, and the first M2 shooter-enemy tranche; the second-tranche work also +proved the rejection/evidence discipline without shipping weak candidates. M3 uses the same +pipeline for hub environments and NPC identity pairs. Generated images are build-time source +material: the browser loads only reviewed static derivatives from `game/public/sprites/`; it +never calls an image model at runtime. + --- ## TL;DR — the recommended pipeline diff --git a/docs/assets/prompts/README.md b/docs/assets/prompts/README.md index d936abc..954699a 100644 --- a/docs/assets/prompts/README.md +++ b/docs/assets/prompts/README.md @@ -6,19 +6,24 @@ Each phase (or asset class) gets its own subfolder. ## How this works 1. Spec/plan author drafts a prompt file per asset class, with: - - Sprite ID (matches entries in `game/app/components/engine/sprites.ts`) + - Planned Sprite ID (becomes a `sprites.ts` entry only when a real consumer exists) - Target filename + path - Dimensions, perspective, alpha - A copy-paste-ready GPT prompt - A negative prompt (what to avoid) - Iteration notes (filled during generation) -2. User runs GPT sessions with the prompts, drops resulting images into - `game/public/sprites//...` at the paths specified. -3. User opens a small PR registering the sprite path constants in `sprites.ts`. -4. Renderer picks them up automatically. Color-tint fallback was used until then. +2. An operator or asset agent generates candidates with the accepted pipeline; rejected + attempts stay outside the repository. +3. Selected candidates are processed to their exact runtime dimensions/alpha contract and + reviewed at their intended renderer size on the required comparison panels. +4. Once a real consumer exists, a small PR registers and consumes the already reviewed PNG; + data modules reference the `sprites.ts` constant rather than hardcoded renderer paths. +5. The color-tint fallback remains until the registered asset is exercised in the game. ## Index - `doom/` — **master style guide** (modern-DOOM art direction; ALL prompts inherit it) - `colony-phase-2/` — 11 assets for Phase 2 FPS descent (walls, environment, interiors); its aesthetic section is superseded by `doom/00-master-style-guide.md` +- `m3-hubs/` — execution-ready Cantina, Marketplace, and Town Hall environment/NPC + contracts, prompts, and review gates; produce in that order diff --git a/docs/assets/prompts/m3-hubs/01-environments.md b/docs/assets/prompts/m3-hubs/01-environments.md new file mode 100644 index 0000000..51c6cfd --- /dev/null +++ b/docs/assets/prompts/m3-hubs/01-environments.md @@ -0,0 +1,200 @@ +# M3 Hubs — Environment Prompts + +For opaque textures, use the positive and negative suffixes from +`../doom/00-master-style-guide.md` verbatim. For transparent props, remove the suffix's +`dark background separation` and painted contact-shadow clauses and use the flat-green, +no-cast-shadow override in `README.md`. Generate at 1024×1024, then derive the exact +production sizes in `README.md`. Never ask an image model to produce several texture views +or props in one sheet. + +## Shared texture rules + +Append this block before the master positive suffix: + +```text +single game texture only, orthographic square-on material view, perfectly seamless on all +four edges, uniform scale and exposure across the entire image, no perspective convergence, +no room corners, no horizon, no vignette, no border, no isolated hero object, no writing, +no letters, no numbers, no symbols that resemble readable language +``` + +Append this block before the master negative suffix: + +```text +room scene, corridor scene, perspective, vanishing point, corner, horizon, frame, border, +vignette, centered object, readable sign, words, logo, watermark, non-tileable edge, lighting +gradient across the whole texture +``` + +The model's claim that a result is seamless is not evidence. Verify with a 2×2 montage and +an offset inspection before accepting it. + +## Cantina kit + +**Role:** A hard-used social refuge assembled from freight modules. It is warmer than the +other frontier interiors without becoming cheerful, clean, or Western-saloon cosplay. + +### Interior wall + +```text +Seamless interior wall texture for an Ashfall frontier cantina: patched gunmetal freight +panels, heat-darkened rivets, shallow dents, soot above recessed vents, old adhesive scars, +small protected amber practical-light housings and a few restrained cyan status diodes. +Human hands have repaired it repeatedly with mismatched plates. No bottles, furniture, +posters, logos, or readable signs. +``` + +### Interior floor + +```text +Seamless top-down floor texture for an Ashfall frontier cantina: worn steel deck plates with +embedded anti-slip strips, chair scuffs, boot wear, tracked ash, old dark spill stains, and +repaired seams. Mostly desaturated gunmetal and concrete; tiny warm reflections only where a +practical light would catch worn edges. No objects, footprints, text, or strong directional +shadow. +``` + +### Interior ceiling + +```text +Seamless overhead ceiling texture for an Ashfall frontier cantina: low armored utility +panels, exposed pipe channels, cable trays, smoke-darkened ventilation grilles, and inset +warm work lights. Dense industrial construction with clear large forms that survive +downscaling. No hanging objects, room perspective, text, or open sky. +``` + +### Exterior facade tile + +Use the wall prompt, remove most interior light housings, add wind-scoured Ashfall dust, +sand abrasion, heat cycling, exterior sealant, and a recessed amber entry beacon. Derive a +64×64 tile from an accepted seamless source; inspect it at exactly 64×64. + +### Props + +Generate each prop separately on a perfectly flat `#00ff00` background with generous +padding, no cast shadow, and no green in the subject. + +- **bar-counter:** wide, waist-high counter welded from cargo plating; thick readable + silhouette, impact scars, dark bottle-storage recesses, one amber edge light. +- **bottle-rack:** compact rack of mismatched sealed canisters and cups; no labels or text; + restrained warm glass highlights. +- **table-cluster:** one heavy bolted table with two fixed stools, asymmetrically repaired; + a single readable ground-level silhouette. +- **rumor-terminal:** person-height battered comms terminal with abstract waveform blocks, + one cyan screen and a tiny amber service light; no readable UI. + +## Marketplace kit + +**Role:** A dense, pragmatic exchange floor. Colder and busier than the Cantina, with modular +stalls and cargo-handling wear rather than luxury retail. + +### Interior wall + +```text +Seamless interior wall texture for an Ashfall frontier marketplace: modular gunmetal stall +panels, sliding cargo rails, bolted repair plates, conduit channels, recessed inventory +sensors, chalky ash in seams, and sparse cyan transaction lights. Dense but readable +industrial rhythm, visibly maintained under scarcity. No goods, posters, prices, lettering, +logos, or readable screens. +``` + +### Interior floor + +```text +Seamless top-down floor texture for an Ashfall frontier marketplace: reinforced cargo deck, +interlocking steel plates, pallet drag scratches, wheel tracks, repair welds, dust gathered +at seams, and small hazard insets expressed only through geometry and wear, not painted text. +No loose objects, arrows, numbers, logos, or directional shadow. +``` + +### Interior ceiling + +```text +Seamless overhead ceiling texture for an Ashfall frontier marketplace: suspended cargo +rails, armored cable runs, rectangular cold work lights, maintenance hatches, patched steel, +and soot-dark ventilation. Strong large-scale structure, cool task-light register with very +small amber accents. No hanging merchandise, text, room perspective, or sky. +``` + +### Exterior facade tile + +Use the wall prompt with exterior blast shutters, cargo-impact wear, Ashfall dust, and a +recessed cyan trade beacon. No readable shop sign. Derive and review at 64×64. + +### Props + +- **vendor-counter:** wide modular cargo counter with locked drawers and one abstract cyan + transaction pad; no text or products fused into the counter. +- **weapon-rack:** tall secured rack holding chunky abstract tool/weapon silhouettes; no + recognizable modern firearm branding or readable labels. +- **supply-crates:** compact stack of three mismatched reinforced containers with broken + stencil shapes that cannot be read as letters or numbers. +- **trade-terminal:** tall armored kiosk with a cyan abstract market graph and physical + controls; no prices, currency symbols, or text. +- **cable-bundle:** thick grounded power/data cables around a rugged junction block; avoid + thin strands that disappear at small size. + +## Town Hall kit + +**Role:** The frontier's first attempt at civic permanence. Severe, repaired, and slightly +more orderly than the other hubs, but still built from survival materials rather than marble. + +### Interior wall + +```text +Seamless interior wall texture for an Ashfall frontier town hall: disciplined vertical +gunmetal panels over cracked structural concrete, reinforced seams, archive access plates, +careful repairs, restrained cyan civic-system light channels, and a small amount of warm +human task light. Imposing through proportion and order, never polished or luxurious. No +flags, heraldry, Earth logo, text, seals, or readable displays. +``` + +### Interior floor + +```text +Seamless top-down floor texture for an Ashfall frontier town hall: broad worn concrete and +steel insets, repaired fractures, orderly plate grid, tracked ash near traffic lanes, and +subtle edge polish from years of petitioners. Severe desaturated palette, no ceremonial +emblem, words, arrows, objects, or directional shadow. +``` + +### Interior ceiling + +```text +Seamless overhead ceiling texture for an Ashfall frontier town hall: armored civic utility +ceiling, symmetrical structural ribs, recessed cyan-white light wells, archive conduits, +maintenance hatches, and visible repair patches. Strong calm geometry that still feels +oppressive and frontier-built. No flags, text, room perspective, or open sky. +``` + +### Exterior facade tile + +Use the wall prompt with heavier wind-scoured reinforcement, a recessed cyan approach light, +and a more ordered panel rhythm than the other hubs. Do not introduce faction heraldry. +Derive and review at 64×64. + +### Props + +- **governor-desk:** wide armored work desk with inset cyan console and thick privacy plates; + no readable papers or UI. +- **petition-terminal:** tall public terminal with abstract queue blocks, scarred hand rests, + and a restrained cyan screen; no numbers or words. +- **holo-atlas:** compact projection pedestal emitting a simple cyan volumetric point-field; + no recognizable real map, text, or free-floating detached fragments. +- **bench:** wide heavy civic bench repaired from steel and dark composite, grounded and + uncomfortable, with a strong single silhouette. +- **archive-cabinet:** tall sealed record cabinet with physical latches and abstract color + tabs that do not resemble letters. + +## Texture rejection rules + +Reject and retry when any of these is visible: + +- a room or corridor instead of a flat material; +- a lighting gradient that repeats as a checkerboard; +- seams in a 2×2 tiling preview; +- readable or pseudo-readable text; +- high-frequency detail that becomes noise at 64×64 or 512×512; +- saturated paint rather than emissive light; +- late-game Fold corruption or mutation; +- three hubs that look like palette swaps of one texture. diff --git a/docs/assets/prompts/m3-hubs/02-npcs.md b/docs/assets/prompts/m3-hubs/02-npcs.md new file mode 100644 index 0000000..82259b1 --- /dev/null +++ b/docs/assets/prompts/m3-hubs/02-npcs.md @@ -0,0 +1,134 @@ +# M3 Hubs — NPC Identity Prompts + +Each role is an **identity pair**: one portrait and one FP idle billboard showing the same +person, clothing, equipment, age cues, and silhouette. Generate the portrait first. Lock the +accepted portrait as the canonical reference for every billboard and later walk frame. + +Do not generate multiple poses in one image. Do not mirror a selected frame to fake a new +pose. Rejected attempts stay outside the repository; selected full-resolution sources are +committed at their manifest `sourcePath`. + +## Shared frontier rules + +- These are living humans near the start of the frontier, not Fold-mutated descendants. +- Clothing is repaired industrial workwear, pressure gear, improvised armor, and practical + role equipment. No clean uniforms, superhero costumes, fantasy robes, or House heraldry. +- Important roles need distinct black silhouettes at 48 px tall. +- Identity must survive changes of framing. Face, age, hair, scars, body build, clothing + layers, and carried equipment remain stable. +- Visible diversity should arise from people, ages, builds, and lived roles—not arbitrary + neon clothing. Surface colors remain desaturated; accent color comes from light. + +## Portrait base prompt + +Append the role brief, then the master positive suffix: + +```text +square 512x512 character portrait for a dark science-fiction game dialog interface, +head and upper torso, three-quarter view looking toward the player, exact single subject, +crisp face and role-defining equipment, worn Ashfall frontier workwear, dark simple +industrial background, strong silhouette, directional rim light, no text or border +``` + +Append the master negative suffix plus: + +```text +full body, multiple people, duplicate face, helmet hiding the entire face, cropped head, +cropped chin, UI frame, nameplate, readable badge, mutation, demonic anatomy, fantasy robe, +royal heraldry +``` + +## Billboard base prompt + +Attach the accepted portrait as the identity reference and append: + +```text +Create the exact same person from the reference as one full-body first-person raycaster NPC +billboard. Preserve face, age, body build, clothing, equipment, materials, and color accents. +Relaxed but alert idle stance, feet fully visible and grounded at the bottom edge, arms and +gear separated enough to read at 48 pixels tall, centered with generous padding, perfectly +flat solid #00ff00 chroma-key background, no cast shadow, no green in the subject, no text. +Production derivative will be 128x256 transparent PNG. +``` + +Walk-frame prompts use the same reference and say `one restrained mid-stride pose, frame 1` +or `frame 2`; preserve scale and ground contact. Reject any result whose limb placement, +costume, or face changes identity. + +## Cantina roles + +### `hub-bartender` + +A broad, middle-aged bartender and former ship engineer. One reinforced prosthetic forearm, +heavy rolled sleeves, heat-scarred apron over pressure-workwear, compact tool belt, patient +but unsentimental face. Warm amber key light. The prosthetic and square shoulder line must +remain legible in the billboard silhouette. No cowboy styling, cocktail glamour, or comedy. + +### `hub-regular` + +An older colony maintenance veteran with a compact build, dust-damaged respiratory collar, +patched insulated jacket, permanently tired posture, and one carefully maintained keepsake +fastened inside the collar. Warm side light with cold shadow. Reads as a person who has kept +the settlement alive for years, not as a soldier or drunk caricature. + +### `hub-signal-chaser` + +A lean itinerant surveyor obsessed with unexplained signals. Asymmetric sensor headset, +folded antenna pack, layered dust cloak over practical pressure gear, alert sleepless eyes, +one cyan instrument glow. Distinct narrow silhouette with one chunky shoulder-mounted sensor; +no mystical robes, alien mutation, or explicit Fold iconography. + +## Marketplace roles + +### `hub-arms-dealer` + +A stocky former convoy guard turned equipment dealer. Reinforced vest, locked sample case, +one heavy mechanical shoulder brace, scarred face, and controlled skeptical expression. +Cold task light with a small amber reflection. The role reads from security posture and gear, +not from holding a gun at the player. + +### `hub-provisioner` + +A practical logistics specialist in layered cargo-handling gear. Compact inventory scanner, +thick gloves, modular pouches, dust scarf, attentive eyes, and a balanced load-bearing +silhouette. Slight cyan scanner light. Avoid shopkeeper stereotypes, aprons, bright trade +colors, or floating merchandise. + +### `hub-contract-broker` + +A precise, difficult-to-read operations broker who converts local needs into located jobs. +Long armored coat over utilitarian workwear, wrist data slate, one damaged optical implant, +careful posture, restrained cyan data light. The silhouette should feel administrative and +dangerous without becoming a spy cliché. No briefcase, sunglasses, or readable contract. + +## Town Hall roles + +### `hub-governor` + +A frontier governor selected from the people rather than a ceremonial ruler. Mature, +weathered face; repaired command coat over pressure workwear; compact emergency respirator; +one old Earth-service pin rendered as an abstract metal shape with no logo. Calm, burdened, +direct gaze. Severe cyan-white key with faint warm fill. No cape, crown, medals, or heraldry. + +### `hub-civic-clerk` + +A younger civic systems clerk who manages petitions, archives, and absent-colony reports. +Practical layered uniform, portable archive module, tired but focused expression, reinforced +gloves, one cyan record-display light. The silhouette needs a chunky side-mounted archive +case. No office suit, paper stack, comedy bureaucracy, or readable badge. + +## Identity-pair rejection rules + +Reject the pair when: + +- portrait and billboard could be two different people; +- body build, age, skin tone, hair, scars, clothing, or equipment changes materially; +- the billboard has halo fog, a ground rectangle, cropped feet, or green spill; +- the role reads only from tiny details lost at 48 px; +- the person looks clean, wealthy, royal, or late-Fold; +- a pose introduces a weapon aimed at the player unless the gameplay role requires it; +- the portrait contains UI chrome, text, a nameplate, or watermarks. + +Record accepted output identifiers, reference inputs, matte method, exact dimensions, and +rejection reasons in the matching review folder. `not exposed` is the correct seed entry when +the generation surface does not expose a seed. diff --git a/docs/assets/prompts/m3-hubs/03-review-and-integration.md b/docs/assets/prompts/m3-hubs/03-review-and-integration.md new file mode 100644 index 0000000..75c7a65 --- /dev/null +++ b/docs/assets/prompts/m3-hubs/03-review-and-integration.md @@ -0,0 +1,163 @@ +# M3 Hubs — Review and Integration Gates + +This checklist distinguishes `PRODUCTION-REVIEWED` static art from `INTEGRATED` runtime art. +Generation is only the first step; neither label may be inferred from a pretty source image. + +## 1. Work in one hub bundle + +Do not generate all three hubs and review them at the end. Complete Cantina through the +production-review gate, then Marketplace, then Town Hall. Keep rejected attempts under a +named `/private/tmp/sector-zero-m3-/` directory. Copy every accepted full-resolution +source into `docs/assets/source/m3-hubs//` before deleting temporary work. + +For each asset, record: + +- output identifier and raw path; +- whether a reference image was attached and what identity it controlled; +- exposed seed, or `not exposed`; +- raw dimensions/channels and committed accepted-source path; +- crop, scale, matte, despill, and edge treatment; +- production dimensions/channels and 5%-alpha bounds for billboards; +- accepted/rejected decision with a concrete reason. + +## 2. Texture processing + +For each wall, floor, ceiling, and facade source: + +1. Inspect all four borders at full size. +2. Create an offset preview that moves the original borders to the center. +3. Create a 2×2 tiling preview. +4. Reject visible seams; do not hide them with aggressive blur. +5. Downscale with a high-quality filter to the exact production size. +6. Confirm the derivative is opaque sRGB PNG and power-of-two. + +Example inspection commands, replacing paths as needed: + +```bash +magick source.png -roll +512+512 /private/tmp/source-offset.png +magick montage source.png source.png source.png source.png -tile 2x2 -geometry +0+0 /private/tmp/source-tile-2x2.png +magick source.png -filter Lanczos -resize 512x512! production.png +magick identify production.png +``` + +Facade derivatives are reviewed as a 2×2 64px tile on neutral dark and bright panels. A good +512px source can still become unreadable noise at 64px. The later integration slice performs +the colony-raycaster review. + +## 3. Billboard processing + +Generate billboards on flat `#00ff00`. Use the established chroma-key/BiRefNet workflow, +then inspect dark and bright composites. Preserve intentional small emissive halos; remove +green spill and opaque fog boxes. + +Required checks: + +- exact 128×256 production canvas for NPCs; +- exact manifest canvas for props; +- transparent corners; +- feet/base touch the intended ground line; +- no meaningful alpha clipped by the canvas; +- face and gear remain legible at expected draw size; +- identity pair matches side by side. + +Do not put clean new assets in `MAT_ALLOWLIST`. That list authorizes the destructive +`remat.ts` pass for known dirty legacy files. Add a new path only if inspection proves it +needs that remediation and the change is reviewed separately. + +## 4. Required production-review evidence + +Commit evidence under: + +```text +docs/assets/reviews/m3-hubs// + provenance.md + textures-2x2.png + props-actual-size.png + npc-identity-pairs.png + billboards-dark-bright.png +``` + +`provenance.md` records attempts and commands. Comparison panels must label the real +production size; enlarged panels use nearest-neighbor scaling only for inspection. + +`billboards-dark-bright.png` contains every required prop and NPC billboard composited at +actual intended draw size on labeled dark and bright fields; this evidence is required +because a halo can disappear against the game's usual dark background. The file may begin +with props during environment production, but it is incomplete until the hub's NPCs are +added. `gameplay-480x854.png` is added only by the later integration slice, after an approved +M3 hub template can display wall/floor/ceiling, a prop, and an NPC together. The asset agent +must not invent that consumer merely to manufacture a screenshot. + +## 5. Runtime integration boundary + +Registration happens in a separately approved M3 code slice after the PNG is +`PRODUCTION-REVIEWED` at the exact contract path. + +1. Add the path constant to `game/app/components/engine/sprites.ts`. +2. Keep the asset single-frame; do not add it to `SHEETS`. +3. Wire the constant through the hub data contract defined by that systemic plan; current + `InteriorTemplate` does not yet own environment-art or NPC-placement fields. +4. Preserve the fallback until the asset resolves successfully. +5. If the consumer needs new data fields, add them to the smallest hub/template data type; + do not add hub-specific conditionals to `firstPersonRenderer.ts`. +6. Keep `window`, `document`, Canvas context creation, and image loading out of module scope. + +The current engine already supports default wall/floor/ceiling textures and FP billboard +paths. It does not yet consume M3 portrait art in the FP dialog box; portrait registration +must not be represented as completed integration until the dialog renderer actually uses +`FPDialogLine.portraitKey`. + +## 6. Verification commands + +For a `PRODUCTION-REVIEWED` asset bundle, run the manifest/schema test and local ImageMagick +audit specified by `2026-07-18-m3-hub-asset-production.md`. They verify every required path, +dimension, PNG color type, transparent corner, and bottom-contact band. + +For an `INTEGRATED` bundle, also run from `game/`: + +```bash +npx tsc --noEmit +yarn colony:test +yarn engine:test +yarn sprites:test +yarn build +NEXT_PUBLIC_DEVTOOLS=1 yarn build +``` + +Then serve the DevPanel export and exercise the real hub at 480×854. Static build success +alone does not prove tiling, scale, identity, interaction visibility, or halo quality. + +## 7. Scope guards + +An asset bundle must not silently: + +- add colony tier promotion or district rules; +- change building costs, power, production, upkeep, or operation rewards; +- redesign first-person rendering; +- alter enemy hitboxes, AI, or balance; +- introduce runtime model calls or network requirements; +- replace unrelated sprites; +- add speculative biome variants before the Ashfall base set is production-reviewed. + +If code integration reaches one of these boundaries, stop the asset slice, commit the +reviewed art/provenance, and hand the remaining decision to the relevant systemic plan. + +## 8. PR shape + +Prefer one small PR per production-reviewed hub bundle. Each PR description names: + +- exact assets added/replaced; +- preserved runtime contracts; +- generation and alpha method; +- actual-size production-review evidence; +- verification commands and results; +- any asset that remains generated but not runtime-consumed. + +The later integration PR adds the 480×854 gameplay evidence; an asset-only PR must state +that this screenshot is intentionally absent. + +Never claim `IN USE` for a file that is merely present or registered. The claim ladder is: + +```text +PROMPTED → GENERATED → PROCESSED → PRODUCTION-REVIEWED → REGISTERED → INTEGRATED/EXERCISED IN GAME +``` diff --git a/docs/assets/prompts/m3-hubs/README.md b/docs/assets/prompts/m3-hubs/README.md new file mode 100644 index 0000000..4a93d7a --- /dev/null +++ b/docs/assets/prompts/m3-hubs/README.md @@ -0,0 +1,169 @@ +# M3 Hubs — Asset Production Contract + +**Date:** 2026-07-18 +**Status:** Approved execution contract for the M3 asset lane +**Order:** Cantina → Marketplace → Town Hall + +This pack turns M3 art into a repeatable production lane rather than a late polish pass. +It governs static assets only. It does not decide colony tier promotion, district growth, +hub gameplay rules, bulletin-board state, interior layouts, or NPC simulation depth. + +Read before generating: + +1. `../doom/00-master-style-guide.md` — authoritative visual language. +2. `../../2026-07-12-asset-pipeline-free-options.md` — generation, alpha, and style-lock pipeline. +3. `01-environments.md` — copy-ready environment prompts. +4. `02-npcs.md` — identity-pair prompts and role briefs. +5. `03-review-and-integration.md` — acceptance and runtime registration gates. + +## Non-negotiable runtime facts + +- The game is a static export. No model or asset-generation service runs in the browser. +- Hub art lands as reviewed PNG derivatives under `game/public/sprites/`. +- `game/app/components/engine/sprites.ts` is the runtime path registry. +- Opaque raycaster textures must be square and power-of-two. +- Most Phase-1 exterior building walls are 64×64; the generated mine is a valid 512×512 + exception. M3 facade derivatives deliberately standardize on 64×64, while hub interior + textures use 512×512. +- Existing FP NPC billboards are 128×256. Dialog portraits are square. +- Current FP props render on a square billboard plane. Every M3 prop therefore uses a + square 256×256 transparent canvas; wide/tall silhouettes live inside that square with + transparent padding. Non-square prop planes require a separate renderer/data design. +- Atlas sheets are width-divided; M3 hub assets are single-frame files. Do not add them to + `SHEETS` unless a later consumer truly slices them by width. +- `MAT_ALLOWLIST` in `game/scripts/sprites/sheets.ts` is a remediation allowlist, not a + general sprite registry. A clean new billboard does not belong there automatically. +- All new art keeps the existing color-tint fallback until an accepted derivative is + present and registered. + +## Prompt precedence for transparent billboards + +For M3 props and NPC billboards, the flat-green and no-cast-shadow instructions in this +pack override the master guide's generic `dark background separation` and painted contact- +shadow language. Preserve believable ground contact by placing the subject at the bottom +edge; do not paint a shadow into the alpha derivative. All other master-guide direction +remains authoritative. + +## Visual chronology + +M3 is the Settlement Era, not the Fold era. The hubs should show difficult human survival: +worn industrial construction, repaired technology, ash, scarcity, and small signs of social +life. Do not introduce bodily mutation, organic Fold growth, Great-House heraldry, ancient +galactic empires, or late-game religious iconography. Those assets must emerge from later +world state rather than appear at the frontier's beginning. + +## Reuse strategy for an effectively infinite world + +The game does not need a unique painting for every colony. M3 creates a reusable Ashfall +base library. Later systems combine: + +- hub kind: Cantina, Marketplace, Town Hall; +- biome material pack; +- settlement tier and maintenance state; +- faction/culture accent set; +- deterministic prop layout and wear decals; +- authored hero assets for exceptional people and places. + +Variation will come from deterministic composition of reviewed assets. Runtime generative +AI is not part of the design. M3 defines only the Ashfall base library; it does not add a +composition key/schema, biome variants, faction accents, or wear decals. Those require a +later systemic design before anyone generates the variant library. + +## Environment manifest + +Each hub kit has three interior textures, one exterior facade tile, and a small prop family. +Rejected attempts stay in `/private/tmp`. Every accepted full-resolution source used to +derive production art is committed under `docs/assets/source/m3-hubs//` together with +its production derivative and review evidence, so a later agent can reproduce the crop, +matte, and scale without relying on an ephemeral tool result. + +| Hub | Sprite constant | Production path | Size | Alpha | Contract | +|---|---|---|---:|---|---| +| Cantina | `HUB_CANTINA_WALL` | `game/public/sprites/interiors/m3/cantina/wall.png` | 512×512 | opaque | seamless square-on wall | +| Cantina | `HUB_CANTINA_FLOOR` | `game/public/sprites/interiors/m3/cantina/floor.png` | 512×512 | opaque | seamless top-down floor | +| Cantina | `HUB_CANTINA_CEILING` | `game/public/sprites/interiors/m3/cantina/ceiling.png` | 512×512 | opaque | seamless overhead ceiling | +| Cantina | `COLONY_WALL_CANTINA` | `game/public/sprites/walls/cantina.png` | 64×64 | opaque | exterior facade wall tile | +| Marketplace | `HUB_MARKET_WALL` | `game/public/sprites/interiors/m3/marketplace/wall.png` | 512×512 | opaque | seamless square-on wall | +| Marketplace | `HUB_MARKET_FLOOR` | `game/public/sprites/interiors/m3/marketplace/floor.png` | 512×512 | opaque | seamless top-down floor | +| Marketplace | `HUB_MARKET_CEILING` | `game/public/sprites/interiors/m3/marketplace/ceiling.png` | 512×512 | opaque | seamless overhead ceiling | +| Marketplace | `COLONY_WALL_MARKETPLACE` | `game/public/sprites/walls/marketplace.png` | 64×64 | opaque | exterior facade wall tile | +| Town Hall | `HUB_TOWN_HALL_WALL` | `game/public/sprites/interiors/m3/town-hall/wall.png` | 512×512 | opaque | seamless square-on wall | +| Town Hall | `HUB_TOWN_HALL_FLOOR` | `game/public/sprites/interiors/m3/town-hall/floor.png` | 512×512 | opaque | seamless top-down floor | +| Town Hall | `HUB_TOWN_HALL_CEILING` | `game/public/sprites/interiors/m3/town-hall/ceiling.png` | 512×512 | opaque | seamless overhead ceiling | +| Town Hall | `COLONY_WALL_TOWN_HALL` | `game/public/sprites/walls/town-hall.png` | 64×64 | opaque | exterior facade wall tile | + +Prop paths follow `game/public/sprites/interiors/m3//.png`. Every prop uses a +256×256 transparent canvas because the current renderer uses a square prop plane. The visible +subject keeps its natural proportions inside that canvas: wide counters may occupy roughly +230×110 pixels and tall terminals roughly 110×230. Every billboard touches the bottom edge +with a believable contact point and contains no cast-shadow rectangle. + +| Hub | Filename | Sprite constant | +|---|---|---| +| Cantina | `bar-counter.png` | `HUB_CANTINA_PROP_BAR_COUNTER` | +| Cantina | `bottle-rack.png` | `HUB_CANTINA_PROP_BOTTLE_RACK` | +| Cantina | `table-cluster.png` | `HUB_CANTINA_PROP_TABLE_CLUSTER` | +| Cantina | `rumor-terminal.png` | `HUB_CANTINA_PROP_RUMOR_TERMINAL` | +| Marketplace | `vendor-counter.png` | `HUB_MARKET_PROP_VENDOR_COUNTER` | +| Marketplace | `weapon-rack.png` | `HUB_MARKET_PROP_WEAPON_RACK` | +| Marketplace | `supply-crates.png` | `HUB_MARKET_PROP_SUPPLY_CRATES` | +| Marketplace | `trade-terminal.png` | `HUB_MARKET_PROP_TRADE_TERMINAL` | +| Marketplace | `cable-bundle.png` | `HUB_MARKET_PROP_CABLE_BUNDLE` | +| Town Hall | `governor-desk.png` | `HUB_TOWN_HALL_PROP_GOVERNOR_DESK` | +| Town Hall | `petition-terminal.png` | `HUB_TOWN_HALL_PROP_PETITION_TERMINAL` | +| Town Hall | `holo-atlas.png` | `HUB_TOWN_HALL_PROP_HOLO_ATLAS` | +| Town Hall | `bench.png` | `HUB_TOWN_HALL_PROP_BENCH` | +| Town Hall | `archive-cabinet.png` | `HUB_TOWN_HALL_PROP_ARCHIVE_CABINET` | + +`manifest.json` is the machine-readable authority for all filenames, constants, dimensions, +alpha classes, full-resolution source paths, and bundle status. Each bundle begins as +`planned` and changes to `production-reviewed` only when its complete environment, prop, and +NPC contract passes review. The tables in this README explain the manifest; they do not +replace it. + +## NPC identity manifest + +The M3 asset lane targets eight role identities. Each role begins with one 512×512 opaque +portrait and one 128×256 transparent idle billboard. Walk frames are a second pass after the +idle identity is production-reviewed. Walk frames are optional enhancements and never block +the initial hub bundle; recurring NPCs may later receive two 128×256 frames generated +separately against the locked reference. + +| Hub | Role ID | Portrait constant | Billboard constant | Initial walk priority | +|---|---|---|---|---| +| Cantina | `hub-bartender` | `PORTRAIT_HUB_BARTENDER` | `NPC_HUB_BARTENDER` | high | +| Cantina | `hub-regular` | `PORTRAIT_HUB_REGULAR` | `NPC_HUB_REGULAR` | low | +| Cantina | `hub-signal-chaser` | `PORTRAIT_HUB_SIGNAL_CHASER` | `NPC_HUB_SIGNAL_CHASER` | medium | +| Marketplace | `hub-arms-dealer` | `PORTRAIT_HUB_ARMS_DEALER` | `NPC_HUB_ARMS_DEALER` | medium | +| Marketplace | `hub-provisioner` | `PORTRAIT_HUB_PROVISIONER` | `NPC_HUB_PROVISIONER` | low | +| Marketplace | `hub-contract-broker` | `PORTRAIT_HUB_CONTRACT_BROKER` | `NPC_HUB_CONTRACT_BROKER` | high | +| Town Hall | `hub-governor` | `PORTRAIT_HUB_GOVERNOR` | `NPC_HUB_GOVERNOR` | high | +| Town Hall | `hub-civic-clerk` | `PORTRAIT_HUB_CIVIC_CLERK` | `NPC_HUB_CIVIC_CLERK` | medium | + +Portrait paths use `game/public/sprites/portraits/.png`. Billboard paths use +`game/public/sprites/boarding/npc-.png`. Optional walk frames append +`-walk-1.png` and `-walk-2.png`. + +Role IDs are stable content identities, not guaranteed story names. Dialog may assign a +save-specific name later without changing the asset path. + +## Claim ladder and bundle completion + +A hub bundle is `PRODUCTION-REVIEWED` when: + +- every required file has exact dimensions and expected alpha semantics; +- wall/floor/ceiling textures tile without a visible seam; +- NPC portrait and billboard unmistakably depict the same person; +- every billboard reads at the renderer's actual small size on dark and bright fields; +- accepted full-resolution sources, derivative commands, comparison evidence, and generation + provenance are committed under `docs/assets/source/m3-hubs/` and + `docs/assets/reviews/m3-hubs//`. + +It becomes `INTEGRATED` only after a separately approved M3 code slice supplies a real hub +template/consumer, registers the files, passes the relevant tests/static exports, and records +a 480×854 production-export playtest showing the textures, prop, and NPC together. Only then +may roadmap/PR copy call the bundle `ACCEPTED` or `IN USE`. + +This asset plan is independently complete at `PRODUCTION-REVIEWED`; it must not invent hub +layouts or NPC wiring to reach `INTEGRATED`. An attractive 1024px source image that fails any +production-review gate is rejected. diff --git a/docs/assets/prompts/m3-hubs/manifest.json b/docs/assets/prompts/m3-hubs/manifest.json new file mode 100644 index 0000000..9f0f229 --- /dev/null +++ b/docs/assets/prompts/m3-hubs/manifest.json @@ -0,0 +1,67 @@ +{ + "schemaVersion": 1, + "scope": "m3-ashfall-base", + "bundles": { + "cantina": { + "status": "planned", + "environment": [ + { "constant": "HUB_CANTINA_WALL", "path": "game/public/sprites/interiors/m3/cantina/wall.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/wall-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "HUB_CANTINA_FLOOR", "path": "game/public/sprites/interiors/m3/cantina/floor.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/floor-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "HUB_CANTINA_CEILING", "path": "game/public/sprites/interiors/m3/cantina/ceiling.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/ceiling-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "COLONY_WALL_CANTINA", "path": "game/public/sprites/walls/cantina.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/facade-source.png", "width": 64, "height": 64, "alpha": "opaque", "kind": "seamless-texture" } + ], + "props": [ + { "constant": "HUB_CANTINA_PROP_BAR_COUNTER", "path": "game/public/sprites/interiors/m3/cantina/bar-counter.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/bar-counter-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_CANTINA_PROP_BOTTLE_RACK", "path": "game/public/sprites/interiors/m3/cantina/bottle-rack.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/bottle-rack-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_CANTINA_PROP_TABLE_CLUSTER", "path": "game/public/sprites/interiors/m3/cantina/table-cluster.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/table-cluster-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_CANTINA_PROP_RUMOR_TERMINAL", "path": "game/public/sprites/interiors/m3/cantina/rumor-terminal.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/rumor-terminal-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true } + ], + "npcs": [ + { "roleId": "hub-bartender", "portrait": { "constant": "PORTRAIT_HUB_BARTENDER", "path": "game/public/sprites/portraits/hub-bartender.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/hub-bartender-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_BARTENDER", "path": "game/public/sprites/boarding/npc-hub-bartender.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/hub-bartender-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } }, + { "roleId": "hub-regular", "portrait": { "constant": "PORTRAIT_HUB_REGULAR", "path": "game/public/sprites/portraits/hub-regular.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/hub-regular-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_REGULAR", "path": "game/public/sprites/boarding/npc-hub-regular.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/hub-regular-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } }, + { "roleId": "hub-signal-chaser", "portrait": { "constant": "PORTRAIT_HUB_SIGNAL_CHASER", "path": "game/public/sprites/portraits/hub-signal-chaser.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/hub-signal-chaser-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_SIGNAL_CHASER", "path": "game/public/sprites/boarding/npc-hub-signal-chaser.png", "sourcePath": "docs/assets/source/m3-hubs/cantina/hub-signal-chaser-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } } + ] + }, + "marketplace": { + "status": "planned", + "environment": [ + { "constant": "HUB_MARKET_WALL", "path": "game/public/sprites/interiors/m3/marketplace/wall.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/wall-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "HUB_MARKET_FLOOR", "path": "game/public/sprites/interiors/m3/marketplace/floor.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/floor-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "HUB_MARKET_CEILING", "path": "game/public/sprites/interiors/m3/marketplace/ceiling.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/ceiling-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "COLONY_WALL_MARKETPLACE", "path": "game/public/sprites/walls/marketplace.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/facade-source.png", "width": 64, "height": 64, "alpha": "opaque", "kind": "seamless-texture" } + ], + "props": [ + { "constant": "HUB_MARKET_PROP_VENDOR_COUNTER", "path": "game/public/sprites/interiors/m3/marketplace/vendor-counter.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/vendor-counter-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_MARKET_PROP_WEAPON_RACK", "path": "game/public/sprites/interiors/m3/marketplace/weapon-rack.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/weapon-rack-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_MARKET_PROP_SUPPLY_CRATES", "path": "game/public/sprites/interiors/m3/marketplace/supply-crates.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/supply-crates-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_MARKET_PROP_TRADE_TERMINAL", "path": "game/public/sprites/interiors/m3/marketplace/trade-terminal.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/trade-terminal-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_MARKET_PROP_CABLE_BUNDLE", "path": "game/public/sprites/interiors/m3/marketplace/cable-bundle.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/cable-bundle-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true } + ], + "npcs": [ + { "roleId": "hub-arms-dealer", "portrait": { "constant": "PORTRAIT_HUB_ARMS_DEALER", "path": "game/public/sprites/portraits/hub-arms-dealer.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/hub-arms-dealer-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_ARMS_DEALER", "path": "game/public/sprites/boarding/npc-hub-arms-dealer.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/hub-arms-dealer-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } }, + { "roleId": "hub-provisioner", "portrait": { "constant": "PORTRAIT_HUB_PROVISIONER", "path": "game/public/sprites/portraits/hub-provisioner.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/hub-provisioner-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_PROVISIONER", "path": "game/public/sprites/boarding/npc-hub-provisioner.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/hub-provisioner-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } }, + { "roleId": "hub-contract-broker", "portrait": { "constant": "PORTRAIT_HUB_CONTRACT_BROKER", "path": "game/public/sprites/portraits/hub-contract-broker.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/hub-contract-broker-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_CONTRACT_BROKER", "path": "game/public/sprites/boarding/npc-hub-contract-broker.png", "sourcePath": "docs/assets/source/m3-hubs/marketplace/hub-contract-broker-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } } + ] + }, + "town-hall": { + "status": "planned", + "environment": [ + { "constant": "HUB_TOWN_HALL_WALL", "path": "game/public/sprites/interiors/m3/town-hall/wall.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/wall-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "HUB_TOWN_HALL_FLOOR", "path": "game/public/sprites/interiors/m3/town-hall/floor.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/floor-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "HUB_TOWN_HALL_CEILING", "path": "game/public/sprites/interiors/m3/town-hall/ceiling.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/ceiling-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "seamless-texture" }, + { "constant": "COLONY_WALL_TOWN_HALL", "path": "game/public/sprites/walls/town-hall.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/facade-source.png", "width": 64, "height": 64, "alpha": "opaque", "kind": "seamless-texture" } + ], + "props": [ + { "constant": "HUB_TOWN_HALL_PROP_GOVERNOR_DESK", "path": "game/public/sprites/interiors/m3/town-hall/governor-desk.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/governor-desk-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_TOWN_HALL_PROP_PETITION_TERMINAL", "path": "game/public/sprites/interiors/m3/town-hall/petition-terminal.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/petition-terminal-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_TOWN_HALL_PROP_HOLO_ATLAS", "path": "game/public/sprites/interiors/m3/town-hall/holo-atlas.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/holo-atlas-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_TOWN_HALL_PROP_BENCH", "path": "game/public/sprites/interiors/m3/town-hall/bench.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/bench-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true }, + { "constant": "HUB_TOWN_HALL_PROP_ARCHIVE_CABINET", "path": "game/public/sprites/interiors/m3/town-hall/archive-cabinet.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/archive-cabinet-source.png", "width": 256, "height": 256, "alpha": "transparent", "kind": "square-billboard", "bottomContact": true } + ], + "npcs": [ + { "roleId": "hub-governor", "portrait": { "constant": "PORTRAIT_HUB_GOVERNOR", "path": "game/public/sprites/portraits/hub-governor.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/hub-governor-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_GOVERNOR", "path": "game/public/sprites/boarding/npc-hub-governor.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/hub-governor-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } }, + { "roleId": "hub-civic-clerk", "portrait": { "constant": "PORTRAIT_HUB_CIVIC_CLERK", "path": "game/public/sprites/portraits/hub-civic-clerk.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/hub-civic-clerk-portrait-source.png", "width": 512, "height": 512, "alpha": "opaque", "kind": "portrait" }, "billboard": { "constant": "NPC_HUB_CIVIC_CLERK", "path": "game/public/sprites/boarding/npc-hub-civic-clerk.png", "sourcePath": "docs/assets/source/m3-hubs/town-hall/hub-civic-clerk-billboard-source.png", "width": 128, "height": 256, "alpha": "transparent", "kind": "npc-billboard", "bottomContact": true } } + ] + } + } +} diff --git a/docs/superpowers/plans/2026-07-18-m3-hub-asset-production.md b/docs/superpowers/plans/2026-07-18-m3-hub-asset-production.md new file mode 100644 index 0000000..f01ab81 --- /dev/null +++ b/docs/superpowers/plans/2026-07-18-m3-hub-asset-production.md @@ -0,0 +1,464 @@ +# M3 Hub Asset Production Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Produce and verify the reusable Ashfall Cantina, Marketplace, and Town Hall environment kits plus eight NPC portrait/billboard identities that M3 code can consume without runtime AI or renderer-specific hacks. + +**Architecture:** Treat art as three independent hub bundles, completed in the order Cantina → Marketplace → Town Hall. Rejected generations remain temporary; selected full-resolution sources, production derivatives, and evidence are committed. This plan ends at `PRODUCTION-REVIEWED`; runtime registration and `INTEGRATED` status belong to a separate M3 code plan with a real hub consumer, preserving fallbacks and keeping asset work independent from unresolved tier, district, and bulletin-board decisions. + +**Tech Stack:** Codex `image_gen`, Sector Zero master prompt guide, ImageMagick, BiRefNet/chroma-key alpha, PNG/sRGB, Next.js 15 static export, Canvas 2D raycaster, `sprites.ts`, `tsx --test` sprite/colony/engine gates. + +--- + +## Authority and scope + +Read in order: + +1. `docs/ROADMAP.md` — milestone order and G0/M3 status. +2. `docs/assets/prompts/doom/00-master-style-guide.md` — authoritative aesthetic. +3. `docs/assets/2026-07-12-asset-pipeline-free-options.md` — accepted production pipeline. +4. `docs/assets/prompts/m3-hubs/README.md` — exact paths, dimensions, and manifest. +5. `docs/assets/prompts/m3-hubs/01-environments.md`. +6. `docs/assets/prompts/m3-hubs/02-npcs.md`. +7. `docs/assets/prompts/m3-hubs/03-review-and-integration.md`. +8. `game/CLAUDE.md` — static-export and engine constraints. + +This plan does **not** implement M3 hub gameplay. Do not decide colony tier promotion, +district layout, bulletin-board persistence, market economy, policy systems, or deep NPC +schedules while executing it. Those require their own reviewed systemic plan. M3 art may +land before its consumer and retain a tint/legacy fallback. + +At plan authoring, `origin/main` is merge commit `6744a49` with G0 Atlas merged. The last +verified gates were TypeScript clean, colony 284/284, engine 282/282, sprites 4/4, and a +successful static export. Re-verify live state before execution; these counts are evidence, +not permanent expectations. + +## File structure + +Generated production files: + +```text +game/public/sprites/interiors/m3/cantina/ +game/public/sprites/interiors/m3/marketplace/ +game/public/sprites/interiors/m3/town-hall/ +game/public/sprites/walls/{cantina,marketplace,town-hall}.png +game/public/sprites/boarding/npc-hub-*.png +game/public/sprites/portraits/hub-*.png +``` + +Review evidence: + +```text +docs/assets/reviews/m3-hubs/cantina/ +docs/assets/reviews/m3-hubs/marketplace/ +docs/assets/reviews/m3-hubs/town-hall/ +``` + +Reproducible selected sources and asset validation: + +```text +docs/assets/source/m3-hubs/{cantina,marketplace,town-hall}/ +docs/assets/prompts/m3-hubs/manifest.json +game/scripts/sprites/validateM3HubAssets.ts +game/tests/sprites/m3HubAssets.test.ts +``` + +Do not modify `sprites.ts`, `buildingTiles.ts`, `colonyLayout.ts`, renderers, or +`game/scripts/sprites/sheets.ts` in this asset-production plan. A later M3 integration plan +owns those seams and must test the real runtime consumer. + +### Task 1: Establish a clean asset branch and baseline + +**Files:** +- Read: authority files above +- Do not modify: the user's existing checkout + +- [ ] **Step 1: Record the primary checkout and create an isolated worktree** + +Run exactly: + +```bash +cd /Users/nichalasbarnes/Desktop/projects/sector-zero +git status -sb +git fetch origin main +git worktree add /private/tmp/sector-zero-m3-hub-assets -b feat/m3-hub-assets origin/main +cd /private/tmp/sector-zero-m3-hub-assets +git status -sb +``` + +Expected: the primary checkout's pre-existing dirty files are recorded and unchanged; the +new worktree is clean on `feat/m3-hub-assets` based on current `origin/main`. + +- [ ] **Step 2: Install the locked game dependencies without repository drift** + +From the new worktree: + +```bash +cd game +yarn install --immutable +git diff --exit-code -- ../package.json package.json ../yarn.lock yarn.lock +``` + +Expected: install exits 0 and the package/lock files are unchanged. If Corepack adds a local +`packageManager` field, remove only that generated line, rerun the diff check, and do not +commit it. + +- [ ] **Step 3: Record live baseline identity** + +Run: + +```bash +git status -sb +git rev-parse HEAD +git log -5 --oneline +``` + +Expected: clean feature worktree based on the current merged `main`. + +- [ ] **Step 4: Verify the relevant baseline** + +From `game/` run: + +```bash +npx tsc --noEmit +yarn sprites:test +``` + +Expected: both exit 0. Also run `magick -version`; asset production requires ImageMagick. +If `tsx` cannot create its local IPC pipe in a managed sandbox, rerun the identical command +outside that restriction before treating it as a product bug. + +- [ ] **Step 5: Add the manifest regression test and local visual validator** + +Create `game/tests/sprites/m3HubAssets.test.ts`. It reads +`docs/assets/prompts/m3-hubs/manifest.json`, always asserts unique constants/paths/source +paths, positive integer production dimensions, and a status of exactly `planned` or +`production-reviewed` for every bundle. For each production-reviewed bundle, it asserts each +selected source exists and is a readable PNG, without applying derivative dimensions or alpha +rules to that source. It separately reads every production PNG's IHDR: width at byte 16, +height at byte 20, bit depth at byte 24, and color type at byte 25. Production files must +match manifest dimensions and use 8-bit RGB (`2`) when opaque or 8-bit RGBA (`6`) when +transparent. + +Create `game/scripts/sprites/validateM3HubAssets.ts`. Its CLI is: + +```bash +npx tsx scripts/sprites/validateM3HubAssets.ts --hub cantina +``` + +It reads the same manifest, invokes ImageMagick with `spawnSync` argument arrays (no shell), +and fails on a missing file, wrong dimensions/channels, non-transparent corners, empty bottom +contact band for `bottomContact: true`, or missing required review evidence. Seam quality +remains a visual-review decision recorded in the required 2×2 panel. The validator supports an +optional `--category environment|props|npcs` during partial production; without that flag it +validates the complete hub bundle. Category mode requires only that category's files and +evidence (`textures-2x2.png` for environment; `props-actual-size.png` and the current +`billboards-dark-bright.png` for props; `npc-identity-pairs.png` and the completed dark/bright +panel for NPCs). Full mode also requires `provenance.md` and all four panels. With all bundles +still `planned`, `yarn sprites:test` passes; the direct Cantina CLI fails with +`missing production asset` until Tasks 2 and 3 supply the complete bundle. + +- [ ] **Step 6: Create temporary attempt directories** + +Use `/private/tmp/sector-zero-m3-cantina/{raw,processed,evidence}`. Do not commit rejected +sources or tool caches. + +### Task 2: Produce the Cantina environment kit + +**Files:** +- Create: `game/public/sprites/interiors/m3/cantina/wall.png` +- Create: `game/public/sprites/interiors/m3/cantina/floor.png` +- Create: `game/public/sprites/interiors/m3/cantina/ceiling.png` +- Create: `game/public/sprites/interiors/m3/cantina/{bar-counter,bottle-rack,table-cluster,rumor-terminal}.png` +- Create: `game/public/sprites/walls/cantina.png` +- Create: `docs/assets/source/m3-hubs/cantina/*-source.png` +- Create: `docs/assets/reviews/m3-hubs/cantina/provenance.md` +- Create: Cantina review panels listed in the review contract + +- [ ] **Step 1: Generate wall, floor, ceiling, and facade separately** + +Use the exact Cantina prompts in `01-environments.md` and the master suffixes. Generate one +texture per request at 1024×1024; the facade is its own exterior-modified request, not a crop +of the interior wall. Keep at least one rejected candidate with its rejection reason in +`provenance.md`, but do not commit the rejected PNG. Copy all four selected sources to the +manifest's `docs/assets/source/m3-hubs/cantina/` paths. + +- [ ] **Step 2: Prove every texture tiles** + +For each candidate, create offset and 2×2 previews. Expected: no central cross, exposure +checkerboard, hard material discontinuity, room perspective, or readable marks. + +- [ ] **Step 3: Derive exact opaque production textures** + +Downscale selected interior sources to 512×512 and the selected facade source to 64×64. Run `magick identify`. +Expected: exact sizes, PNG, sRGB, no alpha channel required. + +- [ ] **Step 4: Generate and matte four props separately** + +Use the flat-green directive. Every production prop is a 256×256 RGBA canvas; preserve wide +or tall visible-subject proportions with transparent padding. Copy every selected raw source +to its manifest source path. Expected: transparent corners, non-empty bottom contact, no +green spill, no fog rectangle, and a readable small-size silhouette. + +- [ ] **Step 5: Build Cantina review evidence** + +Create `textures-2x2.png`, `props-actual-size.png`, and the prop portion of +`billboards-dark-bright.png`. Enlarge actual-size props with nearest neighbor only for the +labeled inspection panel. + +- [ ] **Step 6: Prove the component validators pass while the bundle remains planned** + +Keep Cantina `planned` because its NPC contract does not exist yet. Run: + +```bash +npx tsx scripts/sprites/validateM3HubAssets.ts --hub cantina --category environment +npx tsx scripts/sprites/validateM3HubAssets.ts --hub cantina --category props +yarn sprites:test +``` + +Expected: all exit 0. This proves the two completed component contracts; the manifest test +does not treat the incomplete Cantina bundle as production-reviewed. + +- [ ] **Step 7: Commit the reviewed environment component** + +```bash +git add game/public/sprites/interiors/m3/cantina game/public/sprites/walls/cantina.png docs/assets/source/m3-hubs/cantina docs/assets/reviews/m3-hubs/cantina game/scripts/sprites/validateM3HubAssets.ts game/tests/sprites/m3HubAssets.test.ts +git commit -m "art(hubs): add Cantina environment kit" +``` + +Do not register unused paths merely to make this commit look integrated. + +### Task 3: Produce the Cantina NPC identities + +**Files:** +- Create: `game/public/sprites/portraits/hub-{bartender,regular,signal-chaser}.png` +- Create: `game/public/sprites/boarding/npc-hub-{bartender,regular,signal-chaser}.png` +- Create: `docs/assets/source/m3-hubs/cantina/hub-*-source.png` +- Modify: `docs/assets/reviews/m3-hubs/cantina/provenance.md` +- Create/modify: `docs/assets/reviews/m3-hubs/cantina/npc-identity-pairs.png` + +- [ ] **Step 1: Generate and select one portrait at a time** + +Order: bartender, regular, signal-chaser. Use the role brief plus shared portrait prompt. +Expected: square single-subject identity, no late-game mutation or readable marks. + +- [ ] **Step 2: Generate each idle billboard from its selected portrait** + +Attach the portrait as the identity reference. Do not proceed when face, build, clothing, or +equipment drifts. The production derivative is 128×256 RGBA. Commit selected full-resolution +portrait and billboard sources at the exact manifest source paths. + +- [ ] **Step 3: Matte and inspect identity pairs** + +Complete `billboards-dark-bright.png` with the NPCs and create the side-by-side identity +panel. Inspect at 48px character height as well as 128×256. + +- [ ] **Step 4: Record walk frames as deferred, not missing** + +Do not generate walk frames in this plan: they have no M3 manifest or runtime consumer. +Record the bartender as the first future candidate without adding files or weakening the +idle-pair gate. + +- [ ] **Step 5: Promote the complete Cantina bundle and commit** + +Change only Cantina's manifest status from `planned` to `production-reviewed`, then run: + +```bash +npx tsx scripts/sprites/validateM3HubAssets.ts --hub cantina +yarn sprites:test +``` + +Expected: both exit 0 and the complete hub contract—including all required review panels—is +present. Then commit: + +```bash +git add game/public/sprites/portraits/hub-bartender.png game/public/sprites/portraits/hub-regular.png game/public/sprites/portraits/hub-signal-chaser.png game/public/sprites/boarding/npc-hub-bartender.png game/public/sprites/boarding/npc-hub-regular.png game/public/sprites/boarding/npc-hub-signal-chaser.png docs/assets/source/m3-hubs/cantina docs/assets/reviews/m3-hubs/cantina docs/assets/prompts/m3-hubs/manifest.json +git commit -m "art(hubs): add Cantina NPC identities" +``` + +Stop here for review if the first complete bundle does not meet the actual-size gate. Do not +multiply an unresolved style or alpha problem across two more hubs. + +### Task 4: Produce the Marketplace bundle + +**Files:** +- Create: `game/public/sprites/interiors/m3/marketplace/*` +- Create: `game/public/sprites/walls/marketplace.png` +- Create: `game/public/sprites/portraits/hub-{arms-dealer,provisioner,contract-broker}.png` +- Create: `game/public/sprites/boarding/npc-hub-{arms-dealer,provisioner,contract-broker}.png` +- Create: `docs/assets/source/m3-hubs/marketplace/*-source.png` +- Create: `docs/assets/reviews/m3-hubs/marketplace/*` + +- [ ] **Step 1: Repeat the production-reviewed Cantina workflow using Marketplace prompts** + +Expected: a colder, denser trade floor that is structurally distinct from the Cantina, not +a cyan palette swap. + +- [ ] **Step 2: Generate the five manifest props separately** + +Every prop uses a 256×256 RGBA canvas with its natural visible-subject proportions preserved +inside transparent padding. Generate the exterior facade separately from the interior wall. + +- [ ] **Step 3: Produce the three identity pairs** + +Generate portrait first, then reference-locked 128×256 billboard. Contract broker is the +first walk-frame candidate after all idle pairs pass. + +- [ ] **Step 4: Verify and commit** + +Run `magick identify` over every production file and complete the Marketplace review panels. + +```bash +git add game/public/sprites/interiors/m3/marketplace game/public/sprites/walls/marketplace.png game/public/sprites/portraits/hub-arms-dealer.png game/public/sprites/portraits/hub-provisioner.png game/public/sprites/portraits/hub-contract-broker.png game/public/sprites/boarding/npc-hub-arms-dealer.png game/public/sprites/boarding/npc-hub-provisioner.png game/public/sprites/boarding/npc-hub-contract-broker.png docs/assets/source/m3-hubs/marketplace docs/assets/reviews/m3-hubs/marketplace docs/assets/prompts/m3-hubs/manifest.json +git commit -m "art(hubs): add Marketplace asset bundle" +``` + +Before this commit, mark only Marketplace `production-reviewed` and pass its direct validator +plus `yarn sprites:test`: + +```bash +npx tsx scripts/sprites/validateM3HubAssets.ts --hub marketplace +yarn sprites:test +``` + +Stage explicit paths; do not restage Cantina or unrelated art. + +### Task 5: Produce the Town Hall bundle + +**Files:** +- Create: `game/public/sprites/interiors/m3/town-hall/*` +- Create: `game/public/sprites/walls/town-hall.png` +- Create: `game/public/sprites/portraits/hub-{governor,civic-clerk}.png` +- Create: `game/public/sprites/boarding/npc-hub-{governor,civic-clerk}.png` +- Create: `docs/assets/source/m3-hubs/town-hall/*-source.png` +- Create: `docs/assets/reviews/m3-hubs/town-hall/*` + +- [ ] **Step 1: Produce and tile-check the severe civic environment kit** + +Expected: more ordered and permanent than the other hubs, but made from the same frontier +materials. Reject flags, heraldry, polished luxury, and readable seals. Generate the exterior +facade separately from the interior wall and copy every selected source to its manifest path. + +- [ ] **Step 2: Produce five props and two identity pairs** + +Use the exact manifest dimensions. The governor is the first walk-frame candidate after both +idle pairs pass. + +- [ ] **Step 3: Build the complete review evidence and commit** + +Before committing, change only Town Hall's manifest status to `production-reviewed`, then run +its complete direct validator and `yarn sprites:test`: + +```bash +npx tsx scripts/sprites/validateM3HubAssets.ts --hub town-hall +yarn sprites:test +``` + +Both must exit 0. + +```bash +git add game/public/sprites/interiors/m3/town-hall game/public/sprites/walls/town-hall.png game/public/sprites/portraits/hub-governor.png game/public/sprites/portraits/hub-civic-clerk.png game/public/sprites/boarding/npc-hub-governor.png game/public/sprites/boarding/npc-hub-civic-clerk.png docs/assets/source/m3-hubs/town-hall docs/assets/reviews/m3-hubs/town-hall docs/assets/prompts/m3-hubs/manifest.json +git commit -m "art(hubs): add Town Hall asset bundle" +``` + +### Task 6: Prepare the systemic integration handoff + +**Files:** +- Modify: each hub's `provenance.md` +- Do not modify: game runtime source + +- [ ] **Step 1: Record exact claim status** + +For every manifest entry record `PRODUCTION-REVIEWED, NOT REGISTERED, NOT INTEGRATED`. +List any optional walk frame separately; its absence does not block the initial bundle. + +- [ ] **Step 2: Record the live integration gaps** + +The handoff must state that current `InteriorTemplate` has no environment-art or NPC-placement +fields, `generateInteriorState` hardcodes its default wall/floor and no ceiling, FP props use +a square plane, and the FP dialog renderer does not draw `portraitKey`. Do not propose an +unreviewed patch in this asset branch. + +- [ ] **Step 3: Name the next required document** + +The next systemic artifact is an M3 Cantina code design/plan defining layout, interior asset +fields, interior NPC placement/schedules, interaction, DevPanel fixture, normal player access, +and Atlas/bulletin-board boundaries. Runtime registration belongs there. + +### Task 7: Full verification and publication + +**Files:** +- Modify: each hub's `provenance.md` with final results + +- [ ] **Step 1: Validate production files** + +Run: + +```bash +npx tsx scripts/sprites/validateM3HubAssets.ts --hub cantina +npx tsx scripts/sprites/validateM3HubAssets.ts --hub marketplace +npx tsx scripts/sprites/validateM3HubAssets.ts --hub town-hall +yarn sprites:test +``` + +Expected: no missing production or source files, wrong production dimensions/color type, +accidental non-PNG sources, opaque corners, empty contact bands, duplicate manifest +identifiers, unknown bundle statuses, or missing review panels. + +- [ ] **Step 2: Run repository gates from `game/`** + +```bash +npx tsc --noEmit +yarn colony:test +yarn engine:test +yarn sprites:test +yarn build +NEXT_PUBLIC_DEVTOOLS=1 yarn build +``` + +Expected: all exit 0. Record current counts rather than copying the counts in this plan. + +- [ ] **Step 3: Confirm the honest visual boundary** + +Inspect the committed 2×2, dark/bright, actual-size, and identity-pair evidence. Do not create +a fake hub screenshot or claim a production-export playtest: these assets have no runtime +consumer in this plan. The later integration PR owns the 480×854 gameplay evidence. + +- [ ] **Step 4: Inspect scope** + +```bash +git diff --check origin/main...HEAD +git diff --stat origin/main...HEAD +git status -sb +git -C /Users/nichalasbarnes/Desktop/projects/sector-zero status -sb +``` + +Expected: no unrelated runtime source, balance, renderer, generated cache, `.DS_Store`, lockfile, or +Corepack `packageManager` changes. Compare the primary-checkout output with Task 1 and confirm +the user's pre-existing files and branch are unchanged. + +- [ ] **Step 5: Request independent visual/code review** + +The reviewer compares the contract, exact production/source files, review panels, validators, +and claim levels. Fix blocking findings before publication. + +- [ ] **Step 6: Commit the final claim-status and verification handoff** + +```bash +git add docs/assets/reviews/m3-hubs/cantina/provenance.md docs/assets/reviews/m3-hubs/marketplace/provenance.md docs/assets/reviews/m3-hubs/town-hall/provenance.md +git commit -m "docs(hubs): record asset integration handoff" +``` + +Expected: all Task 6/7 provenance updates are tracked and `git status -sb` is clean. + +- [ ] **Step 7: Push and open a draft PR** + +The PR body lists generated assets, processing/provenance, exact gates, visual evidence, and +states every file is `PRODUCTION-REVIEWED, NOT INTEGRATED`. Do not merge without explicit +user approval. + +## Handoff rule + +If the work stops mid-bundle, leave a dated `provenance.md` with selected/rejected state, +raw temporary directory, exact next asset, and commands already run. A later agent should +resume the next unchecked step rather than regenerate accepted work.