diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 6bb93d10..0995a872 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -3714,7 +3714,18 @@ public sealed class GameWindow : IDisposable ownerId: entity.Id, entityPosition: entity.Position, entityRotation: entity.Rotation, - isDynamic: true, // #143: server-object lights take the D3D dynamic path (1/d att, range×1.5) + // A7 fix #2 (#176/#181): isDynamic is decided by whether the light + // MOVES, not by weenie-vs-dat origin. Server-spawned FIXTURES + // (lanterns, braziers) are stationary — they take retail's STATIC + // curve (calc_point_light 0x0059c8b0: 1/d³ beyond 1 m, range×1.3, + // per-channel colour clamp), not the D3D dynamic path (1/d, + // range×1.5) the former #143 flag forced — which burned every + // fixture ~10× hotter than retail at 3 m: the magenta wash that + // zebra-striped the Facility Hub walls. Site-A lights are all + // stationary today (AP-44: they don't follow bearers); genuinely + // moving lights (projectiles, portal swirls) re-earn isDynamic + // when they exist. + isDynamic: false, cellId: entity.ParentCellId ?? 0u); // A7 #176/#177: scope to the owning cell's visibility foreach (var ls in loaded) _lightingSink.RegisterOwnedLight(ls);