using System;
namespace AcDream.Core.Physics;
///
/// L.2a slice 1 (2026-05-12) — runtime-toggleable physics probe flags.
/// Initialized from env vars at process start; flippable at runtime via
/// the DebugPanel mirror (or by direct assignment). Log call sites read
/// these statics so a checkbox toggle takes effect on the next resolve
/// without relaunching.
///
///
/// L.2d slice 1 (2026-05-13) adds +
/// the diagnostic side-channel. Future
/// slices may fold the older ACDREAM_DUMP_* env vars into this
/// class for unified runtime toggling. Until then, those older flags
/// remain sticky-at-startup per their original implementation.
///
///
public static class PhysicsDiagnostics
{
///
/// When true, emits
/// one structured [resolve] line per call: input + target +
/// output position/cell, grounded state, contact-plane status,
/// collision-normal validity, walkable polygon status, moving entity
/// id. Initial state from ACDREAM_PROBE_RESOLVE=1.
///
public static bool ProbeResolveEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_RESOLVE") == "1";
///
/// When true, every change to PlayerMovementController.CellId
/// emits one [cell-transit] line: old → new cell, current
/// world position, reason tag (resolver / teleport).
/// Initial state from ACDREAM_PROBE_CELL=1.
///
public static bool ProbeCellEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_CELL") == "1";
///
/// L.2d slice 1 (2026-05-13). When true, every BSP-shadow-entry hit
/// attributed by TransitionTypes.FindObjCollisions emits a
/// multi-line [resolve-bldg] entry: which part (partIdx vs 0),
/// physics-BSP root radius vs visual AABB radius, world-space entity
/// origin, and the specific hit polygon's vertices in both
/// object-local and world space. Designed to distinguish the three
/// L.2d hypotheses (wrong BSP loaded / over-registered parts /
/// BSPQuery flaw) from a single Holtburg-doorway capture.
///
///
/// Also gates a one-time [entity-source] log line at every
/// ShadowObjects.Register(...) call site in GameWindow
/// — makes entityId=0xA9B479 in a probe line greppable to its
/// source registration within the same log file.
///
///
///
/// Initial state from ACDREAM_PROBE_BUILDING=1. Mirrorable
/// via DebugVM.ProbeBuilding when ACDREAM_DEVTOOLS=1.
///
///
///
/// Spec: docs/superpowers/specs/2026-05-13-l2d-cbuildingobj-collision-design.md.
///
///
public static bool ProbeBuildingEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_BUILDING") == "1";
///
/// L.2d slice 1 (2026-05-13). Diagnostic side-channel: the
/// that
/// recorded for the most recent collision-normal write.
/// clears this to
/// before each shadow-entry test and reads it
/// back after, so emitting the [resolve-bldg] probe line can
/// reference the actual hit poly without plumbing an out-param
/// through BSPQuery's recursive private methods.
///
///
/// Written by only when
/// is true, so this stays
/// zero-cost in normal play. Cylinder collisions leave this
/// — the probe line emits
/// hitPoly: n/a (cylinder) in that case.
///
///
///
/// Not threadsafe — physics runs on a single thread. If that
/// changes, this needs [ThreadStatic] or rethink. Deviation
/// from spec component 4 (which described an out-param); the
/// side-channel keeps BSPQuery's signature stable and the diagnostic
/// path off the production code surface.
///
///
public static ResolvedPolygon? LastBspHitPoly { get; set; }
///
/// B.6 slice 1 (2026-05-14) — baseline trace for the local-player
/// server-initiated auto-walk path (issue #63). When true, the
/// following events emit one-line [autowalk-*] logs:
///
/// - [autowalk-out] on every SendUse
/// / SendPickUp the local player issues — these are the
/// packets that may trigger ACE's server-side CreateMoveToChain
/// when the target is out of WithinUseRadius.
/// - [autowalk-mt] on every inbound
/// UpdateMotion for the local player — captures the
/// MovementType + MoveToPath + speed/runRate ACE sends.
/// - [autowalk-up] on every inbound
/// UpdatePosition for the local player — answers "what's
/// ACE's broadcast cadence during auto-walk?"
///
/// Initial state from ACDREAM_PROBE_AUTOWALK=1.
///
///
/// Spec: docs/superpowers/specs/2026-05-14-phase-b6-design.md
/// §"Required investigation".
///
///
public static bool ProbeAutoWalkEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_AUTOWALK") == "1";
///
/// 2026-05-16. Logs one line per `IsUseableTarget` call that takes
/// the null-useability fallback path (creature pass / BF_DOOR pass /
/// BF_LIFESTONE pass / etc.). Used to measure how often ACE's seed
/// DB ships entities without `_useability` set — settles whether
/// the fallback is live code or theoretical defense.
///
///
/// Retail has NO fallback; null/zero useability blocks Use entirely
/// (acclient_2013_pseudo_c.txt:402923 ItemHolder::UseObject —
/// IsUseable==0 falls through to "cannot be used" branch). Our
/// fallback exists because ACE genuinely sends null for many seed
/// weenies. The probe quantifies "many".
///
///
/// Toggle via env var ACDREAM_PROBE_USEABILITY_FALLBACK=1
/// or DebugPanel checkbox.
///
public static bool ProbeUseabilityFallbackEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_USEABILITY_FALLBACK") == "1";
///
/// L.4-diag (2026-04-30) → promoted into
/// 2026-05-16 per CLAUDE.md "Code Structure Rules" §5 (diagnostic owner
/// classes, not per-call-site env reads). Gates the [steep-roof]
/// trace family that fires from four sites during the rooftop-bounce
/// investigation:
///
/// - PhysicsEngine.ResolveWithTransition —
/// [steep-roof] KILL-VELOCITY-APPLIED when retail-faithful
/// kill_velocity zeroes the body's velocity on steep-slope
/// impact.
/// - TransitionTypes (FindEnvCollisions
/// post-step) — per-frame plane-normal trace on the active
/// .
/// - PlayerMovementController — two sites
/// emitting [steep-roof] + the per-frame bounce trace when
/// the post-collision velocity disagrees with retail.
///
/// Initial state from ACDREAM_DUMP_STEEP_ROOF=1. Runtime-toggleable
/// via the property setter; not yet wired to a DebugPanel checkbox (open
/// follow-up if a debugging session calls for it).
///
public static bool DumpSteepRoofEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_DUMP_STEEP_ROOF") == "1";
///
/// Indoor walking Phase 1 (2026-05-19). When true, emits one
/// [indoor-bsp] line per
/// call made from 's indoor
/// cell-BSP branch. Captures the cell id, sphere local position,
/// resulting , and the hit poly's id,
/// local-normal, and side-type — pinpoints why indoor collision
/// returns spurious collisions (#84) and helps cross-check the
/// outdoor-in approach path (#85).
///
///
/// While true, this also un-gates the diagnostic
/// side-channel inside
/// — see the OR'd condition at every poly
/// write site. Zero-cost when off.
///
///
///
/// Initial state from ACDREAM_PROBE_INDOOR_BSP=1.
/// Runtime-toggleable via DebugPanel.
///
///
///
/// Spec: docs/superpowers/specs/2026-05-19-indoor-walking-phase1-bsp-cluster-design.md.
///
///
public static bool ProbeIndoorBspEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_BSP") == "1";
///
/// Indoor walking Phase D follow-up (2026-05-19). When true, emits one
/// [cell-cache] line each time
/// caches a new EnvCell. Reports per-cell polygon counts and BSP root
/// structure so the caller can cross-reference with [indoor-bsp]
/// lines to distinguish between:
///
/// - Empty data (physicsPolyCount=0 or resolvedCount=0)
/// — candidate (a)/(c) in the poly=n/a investigation.
/// - Non-zero polygon counts but bspRootPolyCount=0 at
/// root + tree has children — correct structure for non-leaf root,
/// leaves hold the poly refs; not a bug.
/// - Non-zero polygon counts but bspRootPolyCount=0 at
/// root AND root is a leaf (bspRootHasChildren=false) — BSP leaf with
/// zero poly refs, candidate (b)/(d).
///
/// This diagnostic fires at most once per EnvCell (cache is no-op after
/// first population). It does NOT have a DebugPanel mirror yet — this is
/// a one-shot capture tool, not a persistent toggle. Promote to full
/// infrastructure after the root cause is identified.
///
/// Initial state from ACDREAM_PROBE_CELL_CACHE=1.
///
public static bool ProbeCellCacheEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_CELL_CACHE") == "1";
}