Finish the editor: F2/F3/I/H/G, gizmos, streaming catalog, any-game CLI + production hardening#7
Conversation
…ef, undoable environment (PLAN F2/F3-part/I) - Outliner: the list is a scroll region (wheel + scrollbar) with a filter box pinned above it, matching name OR id across all four sections. A 500-entity world is now navigable; before, the panel could not scroll at all. - Widgets: clip window (clipTop/clipBottom) + beginScrollRegion/endScrollRegion; clipped widgets skip draw/hit-test but still advance layout, so content height measures true. - Inspector: entity name is editable (rename coalesces per entity), tint can be added/dragged/removed (add and remove stay DISCRETE undo entries — only value->value drags merge), tags have add/remove rows, and modelRef edits via a draft + Apply button (no per-keystroke rebuild into a magenta placeholder). Tint/tags/modelRef changes destroy+rebuild the scene node — sync only updates transform+tint on existing nodes, so a swap would not show otherwise. - Environment panel: full schema coverage (sunColor, ambientColor, fogColor added) and every edit goes through SetEnvironmentCommand — the last mutation path that bypassed undo. Merge is scoped per FIELD, so Ctrl+Z steps back field by field, not the whole tweaking session. - 148 self-tests pass (entity-edit + environment command tests added). Claude-Session: https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K
…set catalog (PLAN §C-tail/H/P5) - point-gizmo.ts: axis-drag movement for the non-entity selectables the entity gizmos bail on. Water: move center, scale mode drags size out symmetrically. Rivers: per-control-point wire-sphere handles — click to pick the active point, drag axes to move it. Lights: move position. Commits through the existing Edit*Commands on release: one drag, one undo entry. A handle-pick click is consumed so it cannot fall through to handleSelectClick and deselect the river it just touched. - Recent projects (H): toolbar Recent button opens the read UI that never existed for recent.json; clicking an entry switches project wholesale (openProject: project file -> catalog relist -> default world -> title). - Asset catalog streams (P5): loadAssetCatalog only LISTS models now; pumpAssetCatalog loads one GLB per frame in the main loop. The ~20 s black window at startup is gone — the world appears immediately as placeholder boxes and meshes pop in as they arrive. Unreadable GLBs mark failed and are never retried. Catalog reset on reload makes project switching sound. - --project/--world CLI args + dxcompiler.dll/dxil.dll beside the exe (see README): the editor now starts from ANY directory pointed at ANY world — it previously crashed at surface creation unless launched from a directory that happened to carry the DX12 compiler DLLs (the shooter root). - 148 self-tests pass; 45 s live smoke against the shooter project. Claude-Session: https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K
pumpThumbnails renders each loaded GLB once into a 128x128 render texture —
one per frame, inside the normal frame, and only after the streaming catalog
finishes so the two pumps never fight. The Models tab is now a 64px thumbnail
grid (scroll region, hover/selection borders, name below each cell); cells
show a placeholder until their model streams in. Falls back to text-free
placeholder cells permanently if render targets are unavailable.
Requires the engine-side getRenderTextureTexture fix (returned { id } after
the v0.5 rename to Texture.handle — drawing any render texture fed undefined
into a native f64 param).
Prefab-tab thumbnails remain text rows — noted in PLAN.
Claude-Session: https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K
…README truth pass syncEnvironment now delegates to applyWorldEnvironment — the same call the world-viewer example and any instantiateWorld consumer makes — keeping only the shadow-pass toggle behind the explicit dirty flag. PLAN.md Part 4 marks P2/P3a/P4/P5 done with what was learned; README rewritten to match reality (feature-complete, streaming startup, game-agnostic CLI). Claude-Session: https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K
…project; visible asset cells
Screenshot-diagnosed (2026-07-16): with --project ../shooter/editor.project.json
the catalog was keyed by LOAD path ('../shooter/assets/models/x.glb') while
worlds reference 'assets/models/x.glb' — every lookup missed and the whole
arena rendered as placeholder boxes. The exact identity bug joinPath's comment
documents, reintroduced one level up by the --project flag. ModelEntry now
carries relPath (project-relative KEY, byte-equal to modelRef) and filePath
(resolved load path); texture listing and the playtest --world argument get
the same projectRelative treatment (the game's cwd is the project root).
Pinned by four new path-identity asserts (152 self-tests pass).
Also: the thumbnail render pass is DISABLED — the engine's begin_texture_mode
is a per-frame override consumed at end_frame, not the mid-frame raylib idiom,
so the thumbnails stayed empty and drew as invisible images (also screenshot-
verified). The grid now draws clearly visible category-colored cells with the
model's initial (dimmed while its GLB streams in); the drawTexturePro path
stays wired for the day the engine grows a real render-mesh-to-texture call.
Claude-Session: https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K
…jection (load from absolute address 8) Clicking to place (or grabbing a gizmo) died with 0xc0000005 at mouseToWorldRay. Disassembly of the faulting instruction shows 'vmovq 0x8, %xmm6' — an element load whose BASE REGISTER was dropped, i.e. a read from absolute address 8. Layout-sensitive: adding console.error lines made it vanish, which is why every earlier build and smoke test (none of which ever clicked in the viewport) was green over a binary that crashed on the first placement click. Repro pair kept: main-repro.exe + crash_main_10580_6a59eadc.dmp + main-repro.pdb. Dodge, same family as shooter perry-quirks #8: hoist all 16 elements of the inverse view-projection into named scalars first, then do only scalar arithmetic — the idiom mat4Invert itself uses, which has always compiled correctly. The inlined unprojectPoint helper (two 16-element indexed mega-expressions) is gone. Pinned by testMouseRay, which EXECUTES mouseToWorldRay headless — in the broken binary it takes the --test run down with the same AV, which is exactly the alarm we want. Verified live: 13 injected placement clicks + camera drags + move/rotate/scale gizmo drags, no crash; 158 self-tests pass. Claude-Session: https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K
…ry, ui-smoke script (PLAN Part 5) - Scroll-wheel zoom dollies toward the point under the CURSOR (min distance 0.2, multi-notch aware) instead of forever approaching the world center — 'get close to that house' no longer requires discovering middle-drag pan first. Gated on the viewport so scrolling a panel no longer also zooms. cameraEyePosition moved to editor-state to break the orbit-camera<->ray import cycle this created. - Text fields have a real caret: click places it, Left/Right/Home/End move it, Backspace/Delete work on both sides, typing inserts in place. (Paste and selection remain engine-blocked: no clipboard FFI, no key repeat.) - Closing the window with unsaved changes parks them in <world>.recover — never silently lost, never silently overwriting — and opening that world later announces the recovery file. - tools/ui-smoke.ps1: the interaction test. Launches the real binary on a scratch fixture, injects placements/orbit/gizmo-drag/Ctrl+S, asserts alive + entity delta + safe-save siblings. First run: PASS (8 -> 13). --test cannot see input-path miscompiles; this can, and would have caught both of yesterday's shipped bugs. 158 self-tests pass. Companion engine PR: safe saves (engine#120). Claude-Session: https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K
|
Warning Review limit reached
Next review available in: 49 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (30)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Replaces #6 (auto-closed when its base branch was deleted after #5 merged). Everything from #6 plus the fixes real use demanded since:
158 self-tests + ui-smoke green. Companion engine PRs #104/#120 already merged.
https://claude.ai/code/session_01PmL9WgNMkAgvpYSHEZga8K