Skip to content

fix(nodes/wall): let a hovered wall out of its batch so it can outline - #687

Merged
wass08 merged 2 commits into
mainfrom
fix/batched-wall-hover-outline
Aug 19, 2026
Merged

fix(nodes/wall): let a hovered wall out of its batch so it can outline#687
wass08 merged 2 commits into
mainfrom
fix/batched-wall-hover-outline

Conversation

@wass08

@wass08 wass08 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Hovering a wall on a finished floor lights up nothing — no hover outline in select mode, and in paint mode no preview of the surface the next click will paint. Selection looks fine, which is what makes it confusing.

Why

Hover feedback for a wall is an outline and nothing else. SelectionMaterialSync skips walls outright, and the cutaway pass tints only a selection or a delete hover — so default, paint-ready and paint-disabled all reduce to outliner.hoveredObjects plus a colour.

MergedOutlineNode draws that mask with renderer.render(scene, camera) on the main camera, which enables no BATCHED_LAYER. Once #608 sews a level's walls (wall mode up, 8+ walls, 180ms quiet) every wall on the floor is on that layer alone, so it reaches neither the depth pass nor a mask pass.

Selection escapes this only because collectTintedWalls already pulls a selected wall back out of the batch: the click lands, the wall starts drawing itself, and the outline appears. Hover had no such release.

Worth noting for anyone tracing this from #686: wall picking was never affected. The pointer handlers live on the collision-mesh child, which batching never moves off SCENE_LAYER, and R3F raycasts each interaction object directly — so clicks always landed. Only the feedback was missing.

Fix

Release on any hover, not just a delete one. Same mechanism, one more reason: selection and delete tint through materials the merged mesh never reads, a plain hover outlines through a camera that never sees it, and both are answered by the wall drawing its own geometry while it is lit. One wall is lit at a time, so the cost is the one extra draw call the delete path already accepted.

Verification

12-wall single-level project in the community editor, headless Chromium against a local dev server:

Wall mode hover outline before after
Full height (batching on) none outlines, select + paint + erase
Cutaway (batching stands down) outlines unchanged

bun test src in packages/nodes: 1052 pass. Regression test added over collectTintedWalls for all four hover modes.

🤖 Generated with Claude Code


Note

Low Risk
Small, localized change to wall batch exclusion logic with regression tests; no auth, data, or API impact.

Overview
Fixes missing hover outlines on batched walls when wall mode is up and a level’s walls are merged into the batch mesh.

collectTintedWalls now treats any hovered wall ID like a lit wall (not only delete-mode hovers), so the batch system releases that wall to draw its own geometry again. That matches how selection already worked and is required for default/paint hovers, where feedback is an outline rendered through the main camera—which does not see walls on the batched layer.

The function is exported for tests. New regression tests cover all four hoverHighlightMode values plus hovers on non-wall nodes (no release).

Reviewed by Cursor Bugbot for commit e555cf6. Bugbot is set up for automated code reviews on this repo. Configure here.

wass08 and others added 2 commits August 19, 2026 10:58
Hover feedback for a wall is an outline, nothing else: `SelectionMaterialSync`
skips walls outright and the cutaway pass tints only a selection or a delete
hover, so `default`, `paint-ready` and `paint-disabled` all reduce to
`outliner.hoveredObjects` and a colour.

`MergedOutlineNode` draws that mask with `renderer.render(scene, camera)` on the
main camera, which enables no `BATCHED_LAYER`. Once #608 sews a level's walls
(wall mode `up`, 8+ walls, 180ms quiet) every wall on the floor is on that layer
alone, so it reaches neither the depth pass nor a mask pass and hovering it
lights up nothing at all. Selection looks fine only because `collectTintedWalls`
already pulls a selected wall back out of the batch — the click lands, the wall
starts drawing itself, and the outline appears. Hover had no such release, so on
any finished floor the wall you point at goes dark: no hover outline in select
mode, and in paint mode no preview of the surface the next click will paint.

Release on any hover, not just a delete one. Same mechanism, one more reason:
selection and delete tint through materials the merged mesh never reads, a plain
hover outlines through a camera that never sees it, and both are fixed by the
wall drawing its own geometry while it is lit. One wall is lit at a time, so the
cost is the one extra draw call the delete path already accepted.

Verified on a 12-wall level in the community editor: before, hovering a wall in
`Full height` produced no outline in select or paint mode while `Cutaway` (where
batching stands down) outlined correctly; after, both modes outline in
`Full height`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@wass08
wass08 merged commit bab7ff1 into main Aug 19, 2026
3 checks passed
@wass08
wass08 deleted the fix/batched-wall-hover-outline branch August 19, 2026 17:34
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