From 700abad94c00b561a0f36564ac13a85e3bfb6b11 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 20 May 2026 12:00:47 +0200 Subject: [PATCH] fix(physics): skip Setup CylSphere/Sphere shadows for landblock stabs (A1.6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISSUES #83 Phase A1.6. Phase A1 gated the mesh-AABB-fallback path on !_isLandblockStab, but Setup-derived CylSphere/Sphere/Radius-fallback registrations (lines 5910-6005) still ran for stabs. A landblock stab whose source is a Setup (0x02xxxxxx) with defined CylSpheres got BOTH per-part BSP shadows AND a CylSphere shadow with id=entity.Id, producing an invisible collision cylinder at the stab origin alongside the correct BSP walls. User reported this as "thin air" hits outside specific Holtburg buildings. Retail's CBuildingObj uses BSP exclusively. Setup CylSphere/Sphere data is for scenery (trees with trunk cylinders) and creatures. Fix: extend A1's _isLandblockStab gate to wrap the Setup-derived registration block (cylsphere, sphere, radius-fallback). One AND clause on the outer `if (setup is not null)`. Probe evidence (launch-a15-verify.utf8.log): - 0xC0A9B45D (6 hits in outdoor cell 0xA9B40029) — Setup CylSphere on stab. src=0x020002FC. Pre-A1.5 it would also have been registered in adjacent landcells. - 0xC0A9B463 (2 hits) — Setup Sphere on stab. src=0x020000E6. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 4d5f26c..18f1beb 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -5921,7 +5921,17 @@ public sealed class GameWindow : IDisposable // clobber entries via Deregister. { var setup = _physicsDataCache.GetSetup(entity.SourceGfxObjOrSetupId); - if (setup is not null) + // ISSUES #83 / Phase A1.6 (2026-05-21): landblock stabs use BSP + // collision exclusively (retail CBuildingObj). Skip Setup-derived + // CylSphere/Sphere/Radius shadow registrations for stabs to + // prevent the same doubled-collision bug A1 fixed for the + // mesh-AABB-fallback — but on the Setup path instead. Without + // this gate, a stab whose source is 0x02xxxxxx (Setup) with + // defined CylSpheres registers BOTH per-part BSP shadows AND a + // CylSphere shadow with id = entity.Id, producing an invisible + // collision cylinder at the stab origin alongside the correct + // BSP walls. + if (setup is not null && !_isLandblockStab) { float entScale = entity.Scale > 0f ? entity.Scale : 1f; uint shapeIndex = 0;