fix(plugin-trees): consume dirty marks so scene-ready fires for plant scenes#476
Merged
Conversation
… scenes Instanced plant kinds (trees/grass/flowers) never cleared their dirty marks: FloorElevationSystem deliberately leaves the mark for kinds with a def.system, expecting that system to clear it after its own work, but InstancedKindSystem never participated in the dirty protocol. The marks lived forever, hasPendingSceneBuildWork() never went false, and the Viewer's scene-ready signal stalled at SCENE_READY_MAX_WAIT_FRAMES on every plant-containing scene — measured on the headless bake worker as ~190s (180 frames x ~1s SwiftShader frames) of pure cap-wait per bake. Clear the marks in a priority-2 useFrame pass: after the priority-1 floor-elevation lift in the same frame, and only for nodes whose proxy is registered (instances rebuild synchronously from the store, so a rendered node is already built). Validated by baking Wawa House locally: settle 22.5s -> 11.6s (the remainder is genuine asset loading), exported GLB byte-identical with and without the fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Instanced plant kinds (
trees:tree,trees:grass,trees:flower) never cleared their scene-store dirty marks.FloorElevationSystemdeliberately leaves the mark for any kind with adef.system("the downstream consumer will clear it"), butInstancedKindSystemnever participated in the dirty protocol — so the marks lived forever,hasPendingSceneBuildWork()never went false, and the Viewer's scene-ready signal stalled atSCENE_READY_MAX_WAIT_FRAMES(180 frames) on every scene containing a plant.The visible cost: on the headless bake worker (SwiftShader, ~1s frames) every plant-containing scene paid ~190s of pure cap-wait per bake — measured as
pageSettleMs ≈ 193son prod bakes of a plant-heavy scene, regardless of warm caches.The fix adds a priority-2
useFramepass toInstancedKindSystemthat clears this kind's dirty marks:FloorElevationSystem's priority-1 lift pass in the same frame, so the mark survives long enough for the lift to apply (same contractGeometrySystem/ItemSystemrely on);sceneRegistryyet keeps its mark for a later frame;useMemochain), so a rendered node is already "built" — there is no async work the mark needs to outlive.How to test
bun dev, open a scene containing trees/grass — verify plants render, hover/selection outlines work, and moving a plant on an elevated slab still sits at the right height.bun apps/community/scripts/bake.ts <id>from private-editor) and check the[bake:timing]line:pageSettleMsshould be actual load time (~seconds), not ~180 × frame-time.Screenshots / screen recording
N/A — non-visual change (render output and exported GLB verified byte-identical; only the readiness signal timing changes).
Checklist
bun devbun checkto verify)mainbranch🤖 Generated with Claude Code
Note
Low Risk
Small, localized change to dirty-mark lifecycle timing; no auth/data paths and render output is intended to stay identical.
Overview
Instanced plant kinds (
trees:tree, grass, flowers) now participate in the scene dirty-node protocol by clearing their own marks after each frame, instead of leaving them set indefinitely.InstancedKindSystemgains a priority-2useFramepass that callsclearDirtyfor dirty nodes of this kind that are already insceneRegistry. That runs afterFloorElevationSystem’s priority-1 lift (same ordering otherdef.systemconsumers use). Nodes without a mounted proxy keep their mark until registration catches up.Effect:
hasPendingSceneBuildWork()can go false when only plants were dirty, so the viewer scene-ready signal and headless bakes no longer sit at the ~180-frame cap; rendering is unchanged because instances already rebuild synchronously from the store.Reviewed by Cursor Bugbot for commit 93bcdae. Bugbot is set up for automated code reviews on this repo. Configure here.