diff --git a/src/AcDream.Core/Rendering/CameraDiagnostics.cs b/src/AcDream.Core/Rendering/CameraDiagnostics.cs
index e95683d..0ceb5ee 100644
--- a/src/AcDream.Core/Rendering/CameraDiagnostics.cs
+++ b/src/AcDream.Core/Rendering/CameraDiagnostics.cs
@@ -37,6 +37,17 @@ public static class CameraDiagnostics
public static bool AlignToSlope { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_CAMERA_ALIGN_SLOPE") != "0";
+ ///
+ /// When true (default), the chase camera sweeps a 0.3 m collision
+ /// sphere from the head-pivot to the desired eye and stops it at the
+ /// first wall (retail SmartBox::update_viewer spring arm), so
+ /// the eye never sits behind/inside geometry. Initial state from
+ /// ACDREAM_CAMERA_COLLIDE; default-on if unset, off only when
+ /// explicitly set to "0".
+ ///
+ public static bool CollideCamera { get; set; } =
+ Environment.GetEnvironmentVariable("ACDREAM_CAMERA_COLLIDE") != "0";
+
///
/// Per-frame translation damping rate. Retail default 0.45. Higher
/// (→ 1.0) snaps faster; lower (→ 0.0) lags more. Formula per frame:
diff --git a/tests/AcDream.Core.Tests/Rendering/CameraDiagnosticsTests.cs b/tests/AcDream.Core.Tests/Rendering/CameraDiagnosticsTests.cs
index 28323f3..d89d1ad 100644
--- a/tests/AcDream.Core.Tests/Rendering/CameraDiagnosticsTests.cs
+++ b/tests/AcDream.Core.Tests/Rendering/CameraDiagnosticsTests.cs
@@ -46,4 +46,16 @@ public class CameraDiagnosticsTests
CameraDiagnostics.TranslationStiffness = 0.45f;
CameraDiagnostics.UseRetailChaseCamera = true;
}
+
+ [Fact]
+ public void CollideCamera_DefaultOn_AndPersistsRuntimeChanges()
+ {
+ CameraDiagnostics.CollideCamera = true;
+ Assert.True(CameraDiagnostics.CollideCamera);
+
+ CameraDiagnostics.CollideCamera = false;
+ Assert.False(CameraDiagnostics.CollideCamera);
+
+ CameraDiagnostics.CollideCamera = true; // reset so other tests aren't poisoned
+ }
}