diff --git a/src/AcDream.Core/Rendering/CameraDiagnostics.cs b/src/AcDream.Core/Rendering/CameraDiagnostics.cs
new file mode 100644
index 0000000..01349f1
--- /dev/null
+++ b/src/AcDream.Core/Rendering/CameraDiagnostics.cs
@@ -0,0 +1,64 @@
+using System;
+
+namespace AcDream.Core.Rendering;
+
+///
+/// Runtime-tunable knobs for the retail-faithful chase camera. Mirrors
+/// the pattern:
+/// static fields seeded from env vars at process start, runtime-settable
+/// via property setters that the DebugPanel writes to.
+///
+///
+/// Spec: docs/superpowers/specs/2026-05-18-retail-chase-camera-design.md.
+///
+///
+public static class CameraDiagnostics
+{
+ ///
+ /// Master toggle. When false (default) the legacy
+ /// AcDream.App.Rendering.ChaseCamera is the active camera;
+ /// when true, the retail-faithful RetailChaseCamera is.
+ /// Initial state from ACDREAM_RETAIL_CHASE=1.
+ ///
+ public static bool UseRetailChaseCamera { get; set; } =
+ Environment.GetEnvironmentVariable("ACDREAM_RETAIL_CHASE") == "1";
+
+ ///
+ /// When true (default), the camera basis follows the player's
+ /// 5-frame averaged velocity vector — tilts with the terrain on
+ /// hills. When false, the basis is built from a flat (yaw, 0) vector
+ /// and the camera stays horizontal even on slopes. Initial state
+ /// from ACDREAM_CAMERA_ALIGN_SLOPE; default-on if unset.
+ ///
+ public static bool AlignToSlope { get; set; } =
+ Environment.GetEnvironmentVariable("ACDREAM_CAMERA_ALIGN_SLOPE") != "0";
+
+ ///
+ /// Per-frame translation damping rate. Retail default 0.45. Higher
+ /// (→ 1.0) snaps faster; lower (→ 0.0) lags more. Formula per frame:
+ /// alpha = clamp(TranslationStiffness * dt * 10, 0, 1).
+ ///
+ public static float TranslationStiffness { get; set; } = 0.45f;
+
+ ///
+ /// Per-frame rotation damping rate. Independent of translation —
+ /// can be tuned higher so the camera swings to look at you faster
+ /// than it physically catches up. Retail default 0.45.
+ ///
+ public static float RotationStiffness { get; set; } = 0.45f;
+
+ ///
+ /// Mouse-delta low-pass window (seconds). Mouse deltas spaced
+ /// closer than this are averaged with the previous delta before
+ /// being fed to pitch/yaw adjustments. Smooths out jitter on
+ /// high-DPI mice. Retail default 0.25.
+ ///
+ public static float MouseLowPassWindowSec { get; set; } = 0.25f;
+
+ ///
+ /// Per-second rate that held-key offset adjustments
+ /// (CameraZoomIn/Out, CameraRaise/Lower) integrate into the
+ /// camera's Distance / Pitch. Retail default 40.0.
+ ///
+ public static float CameraAdjustmentSpeed { get; set; } = 40.0f;
+}
diff --git a/tests/AcDream.Core.Tests/Rendering/CameraDiagnosticsTests.cs b/tests/AcDream.Core.Tests/Rendering/CameraDiagnosticsTests.cs
new file mode 100644
index 0000000..d3d3251
--- /dev/null
+++ b/tests/AcDream.Core.Tests/Rendering/CameraDiagnosticsTests.cs
@@ -0,0 +1,46 @@
+using AcDream.Core.Rendering;
+using Xunit;
+
+namespace AcDream.Core.Tests.Rendering;
+
+public class CameraDiagnosticsTests
+{
+ // NOTE: These tests assume the env vars ACDREAM_RETAIL_CHASE and
+ // ACDREAM_CAMERA_ALIGN_SLOPE are NOT set when running the test
+ // suite. Static class is initialised on first access; values reflect
+ // the env state at that time.
+
+ [Fact]
+ public void Defaults_AreRetailValues()
+ {
+ // Reset to defaults explicitly (test isolation; another test may
+ // have flipped these earlier in the run).
+ CameraDiagnostics.TranslationStiffness = 0.45f;
+ CameraDiagnostics.RotationStiffness = 0.45f;
+ CameraDiagnostics.MouseLowPassWindowSec = 0.25f;
+ CameraDiagnostics.CameraAdjustmentSpeed = 40.0f;
+ CameraDiagnostics.AlignToSlope = true;
+ CameraDiagnostics.UseRetailChaseCamera = false;
+
+ Assert.Equal(0.45f, CameraDiagnostics.TranslationStiffness);
+ Assert.Equal(0.45f, CameraDiagnostics.RotationStiffness);
+ Assert.Equal(0.25f, CameraDiagnostics.MouseLowPassWindowSec);
+ Assert.Equal(40.0f, CameraDiagnostics.CameraAdjustmentSpeed);
+ Assert.True(CameraDiagnostics.AlignToSlope);
+ Assert.False(CameraDiagnostics.UseRetailChaseCamera);
+ }
+
+ [Fact]
+ public void Setters_PersistRuntimeChanges()
+ {
+ CameraDiagnostics.TranslationStiffness = 0.8f;
+ CameraDiagnostics.UseRetailChaseCamera = true;
+
+ Assert.Equal(0.8f, CameraDiagnostics.TranslationStiffness);
+ Assert.True(CameraDiagnostics.UseRetailChaseCamera);
+
+ // Reset so other tests aren't poisoned.
+ CameraDiagnostics.TranslationStiffness = 0.45f;
+ CameraDiagnostics.UseRetailChaseCamera = false;
+ }
+}