Skip to content

Make the editor run, open shooter worlds, and edit water/rivers/lights#1

Merged
proggeramlug merged 4 commits into
mainfrom
editor/windows-bringup
Jul 12, 2026
Merged

Make the editor run, open shooter worlds, and edit water/rivers/lights#1
proggeramlug merged 4 commits into
mainfrom
editor/windows-bringup

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

The editor had never actually started on Windows. It does now, and it opens arena_02 from the shooter project with every entity visible and editable.

Why it never ran

Four independent causes, each surfacing as TypeError: Expected number for native f64 parameter when an undefined reached a native call. Perry does not type-check missing members on the engine's const enums, so none of this failed at compile time:

  1. Key constants were camelCaseKey.LeftControl, Escape, Delete, Space, LeftShift. The engine spells them LEFT_CONTROL, ESCAPE, DELETE, SPACE, LEFT_SHIFT. Plain letters (Key.Z) happened to be correct, which hid the pattern.
  2. MouseButton.Left/Right/Middle → the engine has LEFT/RIGHT/MIDDLE.
  3. drawLine aritywidgets.ts:separator() splatted the colour's four channels as loose numbers; the signature takes a Color. It only fires on the first panel that draws a separator, which is why it surfaced last.
  4. setSceneNodeTransform / updateSceneNodeGeometry were unreachable from TypeScript — fixed engine-side (Scene FFI reachable from TS; water/rivers render; point lights become schema (v2) engine#90).

Perry's reported stack line was flatly wrong throughout (it blamed sync.ts:383 for a fault in main.ts's input block). Trust console.error breadcrumbs — and note Perry's stdout is block-buffered and lost on a native crash.

Beyond bring-up

  • Placeholder rendering. Entities whose model is missing or is the _gizmo_box.glb sentinel now draw as coloured, pickable cubes sized from the halfExtents convention. Without this, ~20 of arena_02's gameplay entities (spawners, pickups, colliders) were invisible and unselectable.
  • userData editing — key/value rows with add/delete, undoable and coalesced. This is the bridge for game-defined data; the editor stays game-agnostic.
  • Water and rivers are first-class: rendered through the engine's shared spawnWaterVolume/spawnRiver (so the editor shows what the game will show), selectable, inspectable, deletable. Selection carries a kind (entity | water | river | light) because ids are only unique within their own array; entity-only paths go through selectedEntityId(), so a selected river can never reach code that assumes world.entities.
  • Lights — placeable, selectable, and they light the preview for real (applyWorldLights runs every frame). A light has no mesh, so markers are drawn, plus a range sphere when selected.
  • Bugs fixed that the audit missed: sky colour and fog edits were silently ignored; the sun accumulated a new directional light on every edit; water/river ids reset per launch, so reopening a world and adding a volume could mint a duplicate id and make undo delete the wrong one; Backspace doubled as Delete; entity tints were passed 0-1 into a 0-255 API.
  • Ctrl+Y only redoes; terrain creation is explicit and undoable (a stray brush click used to add a 128×128 heightmap to worlds that ship with terrain: null).

A real Perry bug, documented

AssetCatalog and HandleMap are classes, not interfaces, and that is load-bearing: Perry 0.5.x miscompiles Map fields declared on an interface once a program declares more than one. Reading .size access-violates. Full repro table and the rules to work within: docs/perry-map-size-av.md. Worth reporting upstream.

That bug was not what broke the editor — it was introduced by a debug line printing map.size while chasing cause #1, and then masked it for hours. Recorded so nobody re-pays for it.

Verification

62 self-tests pass (commands, id counters, userData semantics, water edit-coalescing, index-preserving removal, the selection guard, and the full v1→v2 light migration). Verified visually against the shooter's arena_02.

Known gaps

Startup blocks ~20 s loading every GLB synchronously. Gizmo-dragging a water volume and per-control-point river handles are not wired (both are editable numerically today). See PLAN.md.

Ralph Kuepper added 4 commits July 11, 2026 16:29
- Declare perry.allow.nativeLibrary so the editor compiles without the
  PERRY_ALLOW_PERRY_FEATURES escape hatch.
- Wire the promised --test flag (Perry does expose process.argv/process.exit).
  runSelfTests now prints failing assertions plus a summary and exits nonzero.
- gitignore the Windows binaries; refresh the README build/status sections.
The editor had never started on Windows. Four independent causes, each
surfacing as `TypeError: Expected number for native f64 parameter` when an
`undefined` reached a native call (Perry does not type-check missing members
on the engine's const enums, so none of this failed at compile time):

- Key constants were camelCase (Key.LeftControl, Escape, Delete, Space,
  LeftShift/RightShift); the engine spells them LEFT_CONTROL, ESCAPE, DELETE,
  SPACE, LEFT_SHIFT, RIGHT_SHIFT. Plain letters were correct, which hid it.
- MouseButton.Left/Right/Middle -> LEFT/RIGHT/MIDDLE.
- widgets.ts:separator() called drawLine with the colour's four channels
  splatted as loose numbers; the signature takes a Color.
- setSceneNodeTransform/updateSceneNodeGeometry were unreachable from
  TypeScript (fixed engine-side; see engine fix/scene-scalar-ffi).

Beyond bring-up:

- Entities whose model is missing or is the `_gizmo_box.glb` sentinel now
  render as colored, pickable placeholder cubes sized from the halfExtents
  userData convention — without this, ~20 of arena_02's gameplay entities were
  invisible and unselectable.
- userData is editable: key/value rows with add/delete, undoable and coalesced.
  This is the bridge for game-defined data (spawners, wave plans, colliders).
- Ctrl+Y only redoes; tool hotkeys no longer fire under a chord or while a
  text field has focus. Delete no longer doubles as Backspace.
- Terrain creation is explicit and undoable (a stray brush click used to add a
  128x128 heightmap to worlds that ship with terrain: null).
- Environment edits apply: sky colour and fog were silently ignored, and the
  sun accumulated a new directional light on every edit.
- Water/river ids persist in world.metadata, so reopening a world and adding a
  volume can no longer mint a duplicate id and make undo delete the wrong one.
- Entity tints were passed 0-1 into a 0-255 API; prefab registry is cached.

AssetCatalog and HandleMap are classes, not interfaces: Perry 0.5.x
miscompiles Map fields on an interface. Full repro table and the rules to work
within: docs/perry-map-size-av.md.

Self-tests extended to cover the new commands, id counters, and userData
semantics: 41 passing.
Placed water volumes and rivers used to be undoable-only: drawn as debug cubes
and line strips, impossible to select, inspect, edit, or delete once created,
with every parameter frozen at whatever the tool hardcoded.

- Render through the engine's shared spawnWaterVolume/spawnRiver, the same
  helpers instantiateWorld uses, so the editor shows what the game will. The
  tools now draw only the in-progress preview.
- Selection carries a kind ('entity' | 'water' | 'river') — ids are only unique
  within their own array. Entity-only paths (gizmos, entity inspector,
  duplicate, frame-on-selection, selection outline) go through
  selectedEntityId(), which returns null for a water/river selection, so a
  selected river can never reach code that assumes world.entities.
- Outliner gets Water and Rivers sections, listed above Entities: the panel does
  not scroll, and a world with 66 entities would bury them below the fold.
- Inspector gets water and river property panels (center, size, surface height,
  wave amplitude/speed, depth, flow, width, colour, opacity), all undoable and
  coalesced per drag.
- Delete removes the selected volume or river; undo restores it at its original
  index so ordering round-trips through the file unchanged.
- Toolbar gains Water and River buttons (previously hotkey-only), and creation
  defaults replace the hardcoded parameters.

Self-tests cover edit coalescing, index-preserving removal, and the selection
guard: 50 passing.
Follows the engine's schema v2, where point lights moved out of userData and
into world.lights.

- Light tool: click the ground to place a point light.
- Lights section in the outliner; inspector for position, colour, intensity and
  range; delete with index-preserving undo; edits coalesce per drag.
- applyWorldLights runs every frame alongside sun/ambient/fog, so the editor
  previews a world's actual lighting instead of guessing at it.
- A light has no mesh, so draw a marker at each one, plus a wire sphere at its
  range when selected — otherwise you cannot see or click a light, and "how far
  does this reach" needs arithmetic on the inspector numbers.

Self-tests cover the v1 -> v2 migration end to end (light lifted out of
entities, colour/range/intensity parsed from the old userData strings, non-light
entities untouched, v2 worlds left alone, migrated world validates): 62 passing.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@proggeramlug, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 59 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ab0be6c5-eb18-4e4b-9f5e-825651e1dfd2

📥 Commits

Reviewing files that changed from the base of the PR and between d0a6f46 and f5358de.

📒 Files selected for processing (44)
  • .gitignore
  • PLAN.md
  • README.md
  • docs/perry-map-size-av.md
  • package.json
  • src/gizmos/move-gizmo.ts
  • src/gizmos/rotate-gizmo.ts
  • src/gizmos/scale-gizmo.ts
  • src/io/asset-catalog.ts
  • src/main.ts
  • src/playtest/playtest.ts
  • src/state/commands/create-terrain.ts
  • src/state/commands/duplicate-entity.ts
  • src/state/commands/edit-water.ts
  • src/state/commands/set-userdata.ts
  • src/state/editor-state.ts
  • src/tests/self-tests.ts
  • src/tools/brush-tool.ts
  • src/tools/light-tool.ts
  • src/tools/prefab-tool.ts
  • src/tools/river-tool.ts
  • src/tools/select-tool.ts
  • src/tools/water-tool.ts
  • src/ui/layouts/brush-panel.ts
  • src/ui/layouts/environment-panel.ts
  • src/ui/layouts/inspector.ts
  • src/ui/layouts/outliner.ts
  • src/ui/layouts/toolbar.ts
  • src/ui/text-input.ts
  • src/ui/ui-context.ts
  • src/ui/widgets.ts
  • src/viewport/frame.ts
  • src/viewport/orbit-camera.ts
  • src/viewport/picking.ts
  • src/world-sync/sync.ts
  • tools/.testout/dumps/crash_main_21568_6a51d0e7.dmp
  • tools/.testout/dumps/crash_main_24380_6a51cfa4.dmp
  • tools/.testout/dumps/crash_main_25908_6a51cf9f.dmp
  • tools/.testout/dumps/crash_main_27960_6a51d309.dmp
  • tools/.testout/dumps/crash_main_28228_6a51cf98.dmp
  • tools/.testout/dumps/crash_main_28608_6a51d089.dmp
  • tools/.testout/dumps/crash_main_29408_6a51d2cc.dmp
  • tools/.testout/dumps/crash_main_8268_6a51d170.dmp
  • tools/.testout/dumps/crash_main_8880_6a524cba.dmp
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch editor/windows-bringup

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug proggeramlug merged commit 808dca0 into main Jul 12, 2026
1 check passed
@proggeramlug proggeramlug deleted the editor/windows-bringup branch July 12, 2026 07:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant