recordstoreguy/EDITOR.md
m3ultra ebdbe6db9a EDITOR.md: Pressing Plant editor/assembler spec + BEYONDMORP.md concept
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 18:09:25 +10:00

6.4 KiB
Raw Blame History

PRESSING PLANT — the engine editor / prompt assembler (spec for build)

The tool that turns "describe an idea" into consistent Flow clips wired into a playable game. One editor, many game projects (Record Store Guy, Beyond Morp: The Movie: The Game, ...). Name: a pressing plant is where records get made.

Architecture (match house style: zero-build, stdlib only)

  • editor/server.py — python3 stdlib HTTP server. Static-serves editor/ UI + the active project dir, plus JSON API:
    • GET /api/projects — list projects (see registry below)
    • GET /api/project/<name>/<path> / POST .../save — read/write JSON + files inside that project only (path-traversal guarded, .json/.md/media only)
    • POST /api/llm — proxy to LLM for the assistant (see LLM section; keeps keys server-side, avoids CORS)
    • POST /api/flux — submit a still to MODELBEAST flux_local and poll (uses MB_TOKEN from env/.env on disk; concept art + ingredient stills stay free)
    • POST /api/clip — accept an uploaded/downloaded Flow clip, run ffmpeg normalize (tools/postprocess.sh behaviour inline: 1280x720/24fps/h264+aac, +faststart), store to engine/clips/<scene>_<kind>.mp4, return duration
  • editor/index.html + editor.js + editor.css — vanilla SPA, tabs below. Reuses the game's arcade styling language so it feels like one product.

Project registry

projects.json at repo root: { "recordstoreguy": ".", "beyondmorp": "../beyondmorp" }. A project dir must contain: production/prompts/{blocks.json,looks/,shots/}, engine/scenes.json, engine/clips/, bible/concept/. POST /api/projects/new scaffolds that tree (this is how beyondmorp gets born; its seeder — see BEYONDMORP.md — imports morpquest room JSONs into location blocks).

Tabs (build in this order — each is independently useful)

1. Cast & Places (blocks.json editor)

Card grid of characters and locations/sets. Each card: name, the verbatim prompt block (textarea), and attached reference images (from bible/concept/, displayed; "Generate still" button → /api/flux with the block + chosen look via promptc logic; "this is the Flow ingredient" checkbox per look — tracks which ingredient stills exist per look, warns when a shot uses a character with no ingredient for the active look). Images can also be dragged IN (John's own refs/sketches) — they become inputs: "Describe this into a block" button sends the image to the LLM (vision-capable route) to draft the prompt block.

2. Map (story graph)

Node canvas (drag boxes, draw arrows — SVG, no lib): nodes = scenes, arrows = onSuccess flow; death branches implicit. Node color = status: idea → shot-spec'd → generated → inserted → tuned. This IS the game's structure editor: saving writes both map.json (positions) and the scene skeletons into engine/scenes.json. Adventure-game projects (beyondmorp) can import an existing room map as the starting graph.

3. Shot desk (the assembler — the heart)

Left: shot list (from production/prompts/shots/). Middle: the shot JSON as a form (world, set, characters, action sentence, camera, duration, qte windows, kind action|death, notes). Right, live-updating:

  • Compiled Flow prompt for the active look (port promptc.py's compile to JS — same blocks, identical output; keep promptc.py the CLI twin)
  • Flow checklist: which ingredient stills to attach (by name, with thumbnails), Veo tier to use (fast/quality per shot flag), "copy prompt" button, and a "log gen" mini-form that appends to production/SHOTLOG.csv (scene, take, credits, verdict) so the budget ledger stays honest without leaving the editor.
  • Alt-look preview: dropdown re-compiles the same shot in any look.

4. Ingest & QTE tuner

Drop a downloaded Flow clip onto a shot → /api/clip normalizes + names + wires it into scenes.json → embedded <video> opens with the SAME debug timeline the engine has (share that code): scrub, frame-step, then click-drag on the timeline to paint each QTE window; pick input direction per window; set per-scene cueLead (the flash-before-window; engine default CUE_LEAD, expose 00.5s) and per-window cue on/off. "Test" button opens the real engine at that scene (?debug=1&scene= — add that query param to player.js). This tab is where "insert the clips" happens.

5. Writers' room (LLM assist)

Chat panel with the project loaded as context (blocks.json + WORLDS/BEYONDMORP doc

  • shot list). Modes, each returning STRICT JSON the UI applies as a diff-preview (nothing auto-saves; John approves each):
  • "draft shots for this beat" → shot JSONs (action sentence, camera, windows guess)
  • "draft a character/location block" (from text OR an attached image)
  • "punch up deaths" → death-shot variants for a scene LLM routing in server.py: default tailnet Ollama http://100.69.21.128:11434/v1 (qwen2.5:7b, free, fine for drafts); optional ANTHROPIC_API_KEY from .env for a "quality pass" button (claude-sonnet-5; vision for image→block). Prompt templates live in editor/prompts/*.md so John can tune the assistant's taste without code.

Consistency contract (why this produces coherent video)

Shots never contain style or character text — only ids. The compiler injects the verbatim blocks; the checklist pins which ingredient stills accompany the prompt into Flow. One place to edit a character; every future prompt inherits it. Looks stay swappable per RSG's system. The editor enforces: no compile if a referenced character/set id is missing; warn if ingredient still absent for active look.

Flow reality check (no API)

Google Flow has no public API — generation stays manual in the browser. The editor optimizes the human loop to: copy prompt → attach listed ingredients → gen → download → drop file on shot. Everything else (spec, compile, log, normalize, insert, tune, test) is automated. If Flow ever exposes an API, /api/flow slots in next to /api/flux.

Build order for Opus

  1. server.py (static + save + project registry) — 2h
  2. Shot desk with JS compiler + copy button (immediately useful for Phase 3 style test) — first
  3. Cast & Places (+ /api/flux once MB_TOKEN is sorted)
  4. Ingest & QTE tuner (share engine debug code; add ?scene= to player.js)
  5. Map; 6. Writers' room (Ollama first, Claude optional) Definition of done per tab: round-trips real recordstoreguy project files with no hand-editing needed for the Phase 3 style test and Phase 5 production loop.