namespace AcDream.Core.Physics; /// /// R4-V5 (#160 fix, 2026-07-03): the minimal weenie every REMOTE entity's /// carries — standing in for retail's /// per-object ACCWeenieObject, which every placed physics object has. /// /// /// The load-bearing behavior is the RUN-RATE FALLBACK CHAIN: /// apply_run_to_command (0x00527be0, raw 305062-305076) reads /// weenie ? (InqRunRate() ?: my_run_rate) : 1.0. Remote weenies in /// retail FAIL InqRunRate (no local skill data), landing on /// my_run_rate — exactly the field the mt-6/7 unpack writes with the /// wire's MoveToRunRate (M13). Our remote interps previously had NO /// weenie at all, taking the degenerate else 1.0 branch retail /// reserves for detached objects — so an observer-side moveto dispatched /// RunForward at speed 1.0 instead of the wire rate: the run cycle played /// in slow motion and the chase velocity crawled (walk was unaffected — /// walk speed isn't rate-scaled). /// /// /// /// stays default false — the A3 /// dual dispatch routes remotes through apply_interpreted_movement, ending /// the fragile "null weenie counts as the player" reading of that gate. /// stays default true; static /// animated objects (doors) also carry this weenie — retail would say /// non-creature there, but their RemoteMotion bodies force-assert Contact, /// so the creature ground-gate is satisfied either way (noted, not a /// behavior difference today). /// /// public sealed class RemoteWeenie : IWeenieObject { /// Remote objects have no local skill data — fail, so the /// retail fallback chain lands on /// (the wire-fed rate). public bool InqRunRate(out float rate) { rate = 0f; return false; } /// Remotes never locally compute jump arcs (server-broadcast /// VectorUpdate velocities drive them). public bool InqJumpVelocity(float extent, out float vz) { vz = 0f; return false; } /// Remotes never locally initiate jumps. public bool CanJump(float extent) => true; }