From 1f8ad13ed65a303ccf250fc999f958da566961c0 Mon Sep 17 00:00:00 2001 From: type-two Date: Sat, 18 Jul 2026 18:36:16 +1000 Subject: [PATCH] [sync1] wire TimelineUI to real Stage, null-mixer guard, M2 unlock + orchestrator updates - index.html: mount TimelineUI, setMixerAuto(false) when timeline present - timeline.js: _evalClips guards no-blocks / null-mixer (real Stage returns null for non-characters; the stub never did) - tldev.html removed; stagestub.js kept as the node-test fixture - lane files: M1 accepted for all three, answers to open questions, M2 priorities (A: clipdrop event, PiP; B: row/scene-bar refresh; C: straight into M3 render pipeline) - SCENEGOD launch.json (informational; preview uses MESHGOD's entry) SYNC 1 verified in-browser: character+backdrop+retargeted clip scene loads, scrub interpolates frame-exact, scene save/load round-trips via server. Co-Authored-By: Claude Fable 5 --- .claude/launch.json | 11 ++++++++ lanes/A-stage.md | 24 +++++++++++++++- lanes/B-timeline.md | 28 ++++++++++++++++++- lanes/C-server.md | 21 +++++++++++++- scenegod/web/index.html | 5 +++- scenegod/web/timeline.js | 2 ++ scenegod/web/tldev.html | 59 ---------------------------------------- 7 files changed, 87 insertions(+), 63 deletions(-) create mode 100644 .claude/launch.json delete mode 100644 scenegod/web/tldev.html diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 0000000..3bf8db6 --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "scenegod", + "runtimeExecutable": "/Users/johnking/Documents/SCENEGOD/.venv/bin/uvicorn", + "runtimeArgs": ["scenegod.server:app", "--port", "8020", "--app-dir", "/Users/johnking/Documents/SCENEGOD"], + "port": 8020 + } + ] +} diff --git a/lanes/A-stage.md b/lanes/A-stage.md index f8bcb68..13c8ba9 100644 --- a/lanes/A-stage.md +++ b/lanes/A-stage.md @@ -97,4 +97,26 @@ disposeRoot). Port rules: - Page loads clean with timeline.js absent AND with server absent (mock=1). ## ORCHESTRATOR UPDATES -(none yet — check back each session) + +### 2026-07-18 — M1 ACCEPTED, SYNC 1 done. **M2 is UNLOCKED.** +M1 verified end-to-end in-browser by the orchestrator (character + backdrop + +retargeted clip + timeline scrub, all through the real Stage). Answers + M2 order: + +1. **/assets/tree item shape confirmed** (from Lane C's server): + `{name, path, formats: ["fbx", ...], thumb: relpath|null}` — rigroom-style, + no `files` array. Drop your bare-string fallback. `/web/*` absolute imports + are confirmed correct as served. +2. **Priority 1 — eventize clip drops.** `stage.setMixerAuto(false)` is now + active whenever the timeline mounts, so your drop-clip-to-preview path is + dead in the integrated page. Replace it: on clip-drop onto a character, + dispatch `window CustomEvent 'scenegod:clipdrop'` with + `{detail: {id, path, clipIndex}}` (Lane B adds the block at the playhead). + Keep bake-and-preview ONLY when no timeline is present. +3. **Priority 2 — make sure `onChange` fires for every entity added via + `applyState`** (SYNC finding: tlui's names column stayed empty after a + programmatic scene load — fix on both sides; B is doing theirs). +4. Then per plan: multiple cameras + PiP overlay (`renderActiveCamera` needs + to work as the M3 final-render target — treat that contract as hard), + backdrop rebuild-on-param-change, drag-from-dock onto viewport. +Test assets now live in `assets/{characters,animations,backdrops}/test/` +(man.fbx, hiphop.fbx, carrying.fbx, street.jpg — gitignored, on ultra). diff --git a/lanes/B-timeline.md b/lanes/B-timeline.md index 28a1092..db612ac 100644 --- a/lanes/B-timeline.md +++ b/lanes/B-timeline.md @@ -78,4 +78,30 @@ Clip crossfades polish, params lanes UI, camera-cut lane UI, snapping config, undo wiring, box-select + multi-drag of keys. ## ORCHESTRATOR UPDATES -(none yet — check back each session) + +### 2026-07-18 — M1 ACCEPTED, SYNC 1 done. **M2 is UNLOCKED.** +Your model survived integration with the real Stage; transform interp and +clip retarget playback verified frame-exact via `step()`. Notes: + +1. **Fix applied by orchestrator** (in your file, keep it): `_evalClips` now + early-returns when the entity has no clip blocks or no mixer — the real + Stage returns `null` from `entityMixer` for backdrops/props/cameras; your + stub always returned an object, which hid the crash. Lesson for the stub: + mirror the contract's nullable returns. +2. **stagestub.js was NOT deleted** — `timeline_test.mjs` imports it. It's + now a permanent test fixture, not dev scaffolding. tldev.html is gone. +3. **SYNC findings, fix first in M2:** (a) after `load()` + `applyState`, + your track-name rows never appeared (only "Cameras") — rebuild rows on + `load()` and on `stage.onChange`; (b) the scene-bar name/duration fields + don't refresh after `load()` — bind them. Verified repro: load a 2-entity + scene programmatically, rows stay empty. +4. **New event:** Lane A will dispatch `scenegod:clipdrop` + `{detail:{id, path, clipIndex}}` when a clip is dropped on a character — + add a clip block on that entity at the playhead (default out = clip + duration after preload, fade 0.25 when it abuts a neighbor). +5. rAF note: in the embedded preview the tab can be `document.hidden` → + rAF fully suspended → `play()` appears frozen. Not a bug in your clock + (verified); don't "fix" it. `step()` is the deterministic path and works. +6. Injected ` -
Lane B dev harness — stub stage. Double-click a lane to add a key, - drag keys, ▶ to play, drag the ruler to scrub. setTransform/param calls log below.
-
-
- -