You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(ecs): take the renderer-streamed bound from the container, not the default
Review follow-up (P2). Engine.removeEntity called isRendererStreamedNumber with
the module default of RESERVED_STATIC_ENTITIES, so the purge decision and the
id-release decision could disagree whenever a custom container is injected via
the public IEngineOptions.entityContainer seam. They are two halves of one
question and have to use the same bound.
Confirmed reachable, and it breaks in BOTH directions — the more damaging one
being the opposite of what you might expect:
createEntityContainer({ reservedStaticEntities: 64 }), entity #100 v0
container released the id? true
components purged? false
getEntitiesWith(C) after removal: 1 entry, still yields 100 = {"v":111}
The id goes back into the recycling pool while the entity stays visible to
component queries with its data intact — engine.removeEntity returns true and
the entity is not removed. A caller cannot detect that.
The other direction is the narrower one: with reservedStaticEntities: 1024,
entity #700 is renderer-owned per the container (release refused) yet the purge
ran anyway, reopening for 512..1024 exactly the corruption this branch fixes.
Fix: IEntityContainer exposes the bound it enforces, and Engine.removeEntity
uses it. The member is OPTIONAL, so a third-party IEntityContainer stays
source-compatible; when absent the engine falls back to the module default,
which is correct for any container that also uses it. Public API grows by one
line:
+ readonly reservedStaticEntities?: number;
Tests cover both directions and fail 3/21 without the change. Note the named
static entities stay at numbers 0-2 regardless of the bound — root, player and
camera are fixed by the protocol, not by the reserved range — and a bound below
3 degenerates safely to "always purge", matching a container that reserves
nothing.
Snapshots regenerated. Full suite: 160 suites, 1223 tests.
0 commit comments