fix(render #53): key cache by (entityId, landblockHint) to defeat ID collision
User confirmed via A/B test (ACDREAM_DISABLE_TIER1_CACHE=1) that the
visual bug — buildings rendering up in the air outside Holtburg — is in
the cache wiring, not elsewhere. The matrix math (restPose * entityWorld
== model) was provably correct, so the bug had to be cache key collision.
Stabs were namespaced in commit 71d0edc, but scenery (0x80LLBB00 +
localIndex) and interior (0x40LLBB00 + localCounter) still have the
same 256-overflow risk. Dense LBs outside Holtburg (forest, urban) push
localIndex past 255, wrapping into the lbY byte and creating cross-LB
collisions.
Fix: change the cache key from uint entityId to (uint, uint) tuple of
(EntityId, LandblockHint). The cache is now correct-by-construction
regardless of any hydration path's Id-generation strategy. Defensive
against future regressions in any ID namespace.
InvalidateEntity becomes a sweep (was O(1)), but it's called rarely
(only on live-entity despawn). InvalidateLandblock was already a sweep.
Updated 14 existing cache tests + 1 dispatcher integration test to thread
landblockHint through TryGet / DebugCrossCheck calls.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
71d0edc3d7
commit
95ebbf3004
4 changed files with 78 additions and 49 deletions
|
|
@ -461,7 +461,7 @@ public sealed unsafe class WbDrawDispatcher : IDisposable
|
|||
// ApplyCacheHit, sets lastHitEntityId, and continues. Subsequent
|
||||
// tuples of the same entity short-circuit at the top of the loop
|
||||
// body via the lastHitEntityId == entity.Id check above.
|
||||
if (!isAnimated && _cache.TryGet(entity.Id, out var cachedEntry))
|
||||
if (!isAnimated && _cache.TryGet(entity.Id, landblockId, out var cachedEntry))
|
||||
{
|
||||
ApplyCacheHit(cachedEntry!, entityWorld, AppendInstanceToGroup);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue