diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 79a333b1..6bb93d10 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -7724,6 +7724,15 @@ public sealed class GameWindow : IDisposable datBundle.Setups.TryGetValue(src, out var datSetup); if (datSetup is not null && datSetup.Lights.Count > 0) { + // #176 site-A light-stacking leak: a landblock can RE-apply + // without an unload in between (#168 ForceReloadWindow, Far→Near + // promotion), and static entity ids are deterministic — so each + // re-apply appended another copy of the same lights under the + // same owner (observed ×2→×4 per session; the wash intensifies + // over time, and the stacked ties destabilize the 128-cap pool + // sort). Clear the owner's previous registration first: the + // re-apply becomes idempotent, and a first apply is a no-op. + _lightingSink.UnregisterOwner(entity.Id); var loaded = AcDream.Core.Lighting.LightInfoLoader.Load( datSetup, ownerId: entity.Id,