CC Package and Physics
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
---
|
||||
date: 2026-06-01
|
||||
type: session
|
||||
tags: [session, dots, netcode, physics, prediction, m5]
|
||||
permalink: gamevault/07-sessions/2026/2026-06-01-m5-physics-in-prediction
|
||||
---
|
||||
|
||||
# Session 2026-06-01 — M5 physics-in-prediction (velocity-driven character)
|
||||
|
||||
## Goal
|
||||
|
||||
Start **M5 — Home base + physics** ([[Milestones]]). Operator scoped this pass to **physics-in-prediction first**: bring Unity Physics (1.4.6) into Netcode's predicted loop as a deterministic, rollback-safe foundation before base-streaming. Deliverable: the player becomes a dynamic physics body driven by input velocity, colliding with static world geometry + other players, replicating server→client with no desync. Projectiles stay kinematic. Architecture locked in [[DR-006_M5_Physics_In_Prediction]].
|
||||
|
||||
## Done
|
||||
|
||||
- **Velocity-driven movement.** `PlayerMoveSystem` rewritten from teleporting `LocalTransform.Position` → writing `PhysicsVelocity.Linear = dir * EffectiveCharacterStats.MoveSpeed` (Y zeroed, angular zeroed); Unity Physics integrates + resolves contacts. Kept in `PredictedSimulationSystemGroup` (the predicted physics group is OrderFirst, so velocity applies on the next step — a 1-tick offset that is consistent across server/client/rollback). `Unity.Transforms`/`Unity.Physics.Systems` usings dropped.
|
||||
- **Player physics body (built-in authoring).** `Player.prefab` got a `CapsuleCollider` (r 0.5, h 2) + `Rigidbody` (`useGravity=false`, dynamic, `FreezeRotation`, `interpolation=Interpolate`) → bakes `PhysicsCollider`/`PhysicsVelocity`/`PhysicsMass`/`PhysicsGravityFactor`(0)/`PhysicsGraphicalSmoothing`. Unity Physics 1.x bakes built-in colliders + `Rigidbody`; the old `PhysicsShape/BodyAuthoring` are gone.
|
||||
- **Planar pin.** New `PlayerPlanarConstraintSystem` (after the fixed-step physics group) clamps player Y to `PlayerSpawner.SpawnPoint.y` + zeroes vertical velocity — stops gravity-free capsules from riding up box edges and floating away (the actual cause of the first "tunnelling" symptom; see below).
|
||||
- **Subscene content.** `Gameplay.unity` gained a `NetCodePhysicsConfig` singleton (`PhysicGroupRunMode = LagCompensationEnabledOrAnyPhysicsEntities`, `EnableLagCompensation = false`) and 3 static box-collider obstacles (`Pillar_Center`, `Wall_East`, `Wall_North`, red). Re-baked.
|
||||
- **Tests.** `ProjectM.Tests.EditMode` asmdef gained `Unity.Physics`; `PlayerMoveSystemTests` rewritten from teleport-position asserts → velocity-mapping asserts (cardinal, diagonal unit-clamp, sub-unit proportional, determinism + angular-zero).
|
||||
|
||||
## Validation
|
||||
|
||||
- **EditMode 51/51 green** (47 prior suites + 4 rewritten PlayerMove tests); M1–M4 suites unaffected.
|
||||
- **Runtime (single in-editor client, 6.4.7):** player baked with all physics components on **server + client**; CollisionWorld holds 4 collider bodies (player + 3 static), raycast confirms solid walls. Driving +X into `Wall_East` (face x≈5.75) → capsule **stops at x=5.25 = face − radius** on both worlds, **holds under continuous push** (no tunnel, no creep), **Y pinned at 1.00** (no climb-over), and **releases to free movement** on reverse. **Server == client exactly** (prediction in sync). Console clean of all five M2/M4 cascade signatures + Burst "not a known entry point"; only the known unfocused-editor `Server Tick Batching` artifact remains.
|
||||
|
||||
## Diagnosis notes (for future me)
|
||||
|
||||
- **First symptom looked like tunnelling; it was climb-over.** Colliders were solid (raycast hit), but with gravity off the capsule took a vertical contact impulse, rose above the short (y[0,1]) walls, and floated away at constant velocity. Fix = planar pin + taller walls. Not a collision-detection bug.
|
||||
- **A whole detour was caused by `Write`-tool edits to `.cs` not triggering a Unity recompile** on this unfocused editor — tests/`execute_code` ran a **stale assembly** (velocity showed `MoveSpeed*dt`, angular not zeroed: code that existed in neither old nor new source). Switching to MCP `apply_text_edits` (Unity's own scripting pipeline) fixed it immediately. **Always edit Assets `.cs` via `apply_text_edits`/`create_script`, never the raw `Write` tool.**
|
||||
|
||||
## Decisions
|
||||
- [[DR-006_M5_Physics_In_Prediction]] — implicit predicted physics (no toggle); built-in collider+Rigidbody authoring; velocity-driven move; `PhysicsVelocity` auto-replication; planar pin; baked static world. Physics-first ordering (1-tick offset); `FreezeRotation` not baked → angular-zero held in code.
|
||||
|
||||
## Open / deferred
|
||||
- **Base subscene streaming** — the other half of M5 (persistent home base, stream in/out around players). Not started this pass.
|
||||
- **Lag compensation** — `EnableLagCompensation=false`; revisit if/when physics-based hit detection replaces the swept-segment server check.
|
||||
- **Same-tick movement** — currently a 1-tick velocity offset (physics group is OrderFirst). Move `PlayerMoveSystem` into the fixed-step group `[UpdateBefore(PhysicsSystemGroup)]` if responsiveness needs it (costs 2 cosmetic warnings).
|
||||
- **Projectiles as physics bodies** — still kinematic + swept-hit; convert if projectile-vs-world collision is wanted.
|
||||
- **Rotation lock** — relying on per-tick angular-zero + aim write; set `PhysicsMass.InverseInertia=0` if a hard lock is needed.
|
||||
- **Player-vs-player collision** is server-authoritative (both dynamic on server); on clients others are interpolated, so peer collisions are approximate and server-corrected — fine for 2–4.
|
||||
|
||||
## Next
|
||||
Either (a) the **base subscene streaming** half of M5, or (b) layer **Unity Relay** onto M4's `ConnectionConfig` to make co-op remote-playable. Recommend (a) to complete M5.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
date: 2026-06-01
|
||||
type: session
|
||||
tags: [session, dots, netcode, physics, character-controller, prediction, m5]
|
||||
permalink: gamevault/07-sessions/2026/2026-06-01-m5b-character-controller
|
||||
---
|
||||
|
||||
# Session 2026-06-01 — M5b: adopt the Unity Character Controller package
|
||||
|
||||
## Goal
|
||||
|
||||
Operator decision: replace the M5 dynamic-Rigidbody player ([[DR-006_M5_Physics_In_Prediction]]) with Unity's **Character Controller package** (kinematic, collide-and-slide, DOTS, netcode-predicted) as the player's movement foundation. Run via `/dots-dev` with a multi-agent research workflow. Architecture locked in [[DR-007_M5b_Character_Controller_Package]].
|
||||
|
||||
## Process
|
||||
|
||||
- **Read-only research workflow** (6 parallel Explore agents → synthesis): compatibility (two angles), CC netcode setup, CC core API, codebase impact. Returned a unified plan + a hard compatibility verdict.
|
||||
- **Compatibility gate (the make-or-break):** research said CC 1.4.2 declares `entities/physics@1.3.15` vs our Entities 6.4.0 (Unity-6 renumber) — *likely incompatible*. Resolved by an **empirical install probe** (operator-gated): added the package, confirmed the lock kept Entities 6.4.0 / Physics 1.4.6 / Netcode 1.13.2 (no downgrade) and compiled clean. The floors were satisfied → **it works**. Probe → pause → operator "go".
|
||||
- **Port:** a sub-agent fetched the OnlineFPS netcode-character sample verbatim; I reconciled its API against the **installed** 1.4.2 via `unity_reflect` (the canonical path is `IKinematicCharacterProcessor<T>` + `KinematicCharacterDataAccess` + static `KinematicCharacterUtilities.Update_*`; the legacy `KinematicCharacterAspect` also exists but isn't what the samples use). Authored a minimal top-down adaptation.
|
||||
|
||||
## Done
|
||||
|
||||
- **New (`ProjectM.Simulation`):** `CharacterComponent` + `CharacterControl` (CharacterComponents.cs); `CharacterControlMath.DesiredMovement` (unit-test seam); `CharacterProcessor` (the IKinematicCharacterProcessor running the Update_* sequence, gravity-free, velocity-controlled); `CharacterPhysicsUpdateSystem` (`KinematicCharacterPhysicsUpdateGroup`); `PlayerControlSystem` (PlayerInput × MoveSpeed → CharacterControl); `CharacterGhostVariants` (CharacterInterpolation → PredictedClient-only).
|
||||
- **New (`ProjectM.Authoring`):** `PlayerCharacterAuthoring` — baker calls `KinematicCharacterUtilities.BakeCharacter` (top-down props) + adds CharacterComponent/CharacterControl.
|
||||
- **Modified:** `ProjectM.Simulation.asmdef` + `ProjectM.Authoring.asmdef` (+`Unity.CharacterController`, Authoring +`Unity.Physics`); `Player.prefab` (removed M5 Rigidbody, kept CapsuleCollider, added PlayerCharacterAuthoring, scale 1); `StatRecomputeSystem` (dropped the now-dangling `[UpdateBefore(PlayerMoveSystem)]`).
|
||||
- **Deleted:** `PlayerMoveSystem`, `PlayerPlanarConstraintSystem` (CC + no-gravity stays planar — no constraint needed); `PlayerMoveSystemTests` → `CharacterControlMathTests`.
|
||||
- **Kept:** PlayerInput + input gather + DebugInputInjectionSystem, EffectiveCharacterStats/StatRecompute, GhostOwner/spawn/co-op ring, PlayerAimSystem, combat/health, the `NetCodePhysicsConfig` + baked static walls from DR-006.
|
||||
|
||||
## Validation
|
||||
|
||||
- **EditMode 47/47 green** (4 new CharacterControlMath tests replace the 4 old PhysicsVelocity-mapping tests).
|
||||
- **Runtime (single in-editor client, 6.4.7):** player bakes the full CC set (`KinematicCharacterBody/Properties`, `PhysicsCollider`, `CharacterControl`, `CharacterComponent`, `CharacterInterpolation`, the 4 CC buffers) on **both** worlds; spawns at the ring slot (2.5,1,0). Driving +X stops the capsule at **x=5.24** (= `Wall_East` face − radius) on **server and client**; diagonal input **slides along** the wall and rounds its finite end (collide-and-slide, no tunnel); **Y holds 1.00 with no planar-pin system**; **server == client**. `CharacterInterpolation` confirmed on the client ghost, **absent on the server** (predicted-only variant works). Console clean of CC/Burst/cascade signatures — only the known unfocused-editor tick-batching artifact.
|
||||
|
||||
## Decisions
|
||||
- [[DR-007_M5b_Character_Controller_Package]] — CC 1.4.2 resolves on our stack (SemVer floors, no downgrade); kinematic collide-and-slide owner-predicted character via the static-utilities pattern; data-driven velocity from existing PlayerInput/stats; CharacterInterpolation predicted-only; do NOT globally DontSerialize LocalTransform (protects non-character ghosts); supersedes the DR-006 dynamic-Rigidbody mover, keeps the DR-006 predicted-physics infra.
|
||||
|
||||
## Diagnosis notes (for future me)
|
||||
- **The compatibility "no" was a false alarm** — a package declaring an older `entities@1.3.x` dependency still resolves against the renumbered Entities 6.4.0 (SemVer floor); always **probe** rather than trust the version-string mismatch. Verify the lock didn't downgrade + the package compiles.
|
||||
- **Trust `unity_reflect` over sub-agent package-cache reads** for the installed API shape: reflect showed both the aspect (legacy) and the static-utilities path; the samples use the latter, which compiled first-try.
|
||||
- Continued to edit Assets `.cs` exclusively via MCP `create_script`/`apply_text_edits` (see [[2026-06-01_M5_Physics_In_Prediction]] / the Write-tool stale-assembly trap).
|
||||
|
||||
## Open / deferred
|
||||
- **Multi-client co-op interpolation** — validate remote-peer smoothness with a live two-build / thin-client run (predicted-only `CharacterInterpolation` variant is in place; single-client validated).
|
||||
- **Player-vs-player non-physical** (`SimulateDynamicBody=false`); **gravity-free/no floor** (planar); **CC declares older deps** (revisit on CC bump); optional **KinematicCharacterBody velocity ghost variant** for tighter reconciliation under latency.
|
||||
|
||||
## Next
|
||||
Recommend a **real two-build LAN co-op smoke test** (also closes the M4 deferral) to validate remote CC interpolation, then resume the **base subscene streaming** half of M5.
|
||||
Reference in New Issue
Block a user