# V2 Maya Character Controller Tuning Guide

`TODOS.phase-72.72.24.1.15` is the source guide for tuning the `maya-physics`
capsule character controller. The implementation lives in
`libs/maya/engine-core/crates/maya-physics/src/character_controller.rs`; this
document explains how to choose presets, change individual subsystem configs,
verify behavior, and collect debug evidence before shipping a movement tuning
change.

## Source Of Truth

- Runtime crate: `libs/maya/engine-core/crates/maya-physics`.
- Public entry points: `CapsuleCharacterController::new`,
  `CapsuleCharacterController::from_preset`,
  `CapsuleCharacterControllerPreset::for_kind`,
  `CapsuleCharacterController::move_capsule`,
  `CapsuleCharacterController::probe_ground`,
  `CapsuleCharacterController::resolve_slope_movement`,
  `CapsuleCharacterController::plan_step_climb`,
  `CapsuleCharacterController::detect_ledge`,
  `CapsuleCharacterController::resolve_moving_platform`,
  `CapsuleCharacterController::resolve_swimming`,
  `CapsuleCharacterController::resolve_climbable_surface`,
  `CapsuleCharacterController::plan_stance_transition`,
  `CapsuleCharacterController::resolve_character_collisions`,
  `CapsuleCharacterController::resolve_gravity`,
  `CapsuleCharacterController::predict_movement`,
  `CapsuleCharacterController::reconcile_movement_prediction`, and
  `CapsuleCharacterController::build_debug_snapshot`.
- CI contract:
  `V2/ue/Content/V2/Gameplay/Character/MayaCharacterControllerTuningGuide_V2_Contract.json`.
- Checker: `V2/ue/Tools/check-v2-maya-character-controller-tuning-guide.py`.

The Rust API is the authoritative behavior contract. UE-side movement code may
adapt these values into native component properties, but it should not fork the
meaning of any field listed here.

## Runtime Surface

The controller is split into small, explicit configs so teams can tune one
movement behavior without accidentally changing another:

- `CapsuleCharacterControllerConfig` controls capsule radius, half height, skin
  width, minimum move distance, depenetration iterations, and sweep iterations.
- `CapsuleGroundProbeConfig` controls up vector, ground stick distance, probe
  distance, walkable slope angle, and ray start offset.
- `CapsuleSlopeHandlingConfig` controls walkable slope projection, steep slope
  sliding, slide speed, and speed preservation.
- `CapsuleStepClimbConfig` controls max step height and smooth elevation time.
- `CapsuleLedgeDetectionConfig` controls edge search, walk-off prevention,
  auto-grab, probe distance, and hang offset.
- `CapsuleMovingPlatformConfig` controls platform attachment, velocity
  inheritance, angular velocity inheritance, and inherited speed clamping.
- `CapsuleSwimmingConfig` controls trigger-volume water detection, buoyancy,
  drag, and vertical swim speed.
- `CapsuleClimbableSurfaceConfig` controls climbable probe distance, climb
  speed, and whether climbable surfaces must be triggers.
- `CapsuleStanceConfig` controls standing, crouch, and prone capsule heights.
- `CapsuleGravityConfig` controls gravity acceleration, low-gravity scale, jump
  height, and max fall speed.
- `CapsuleMovementPredictionConfig` controls prediction tolerances, smoothing,
  and replay input limits.

All configs have validation paths. If a tool or data table generates values, run
the checker and Rust tests before exposing the values to designers.

## Preset Selection

Start from `CapsuleCharacterControllerPresetKind` instead of hand-copying values
for a new mode:

- `Platformer`: larger step height, stronger jump, auto-grab ledges, wider
  replay window, and generous platform support. Use for authored traversal with
  visible jump arcs and forgiving ledges.
- `RealisticFps`: moderate step height, conservative ledge policy, grounded
  slope limits, and lower jump height. Use for first-person movement where
  geometry should feel physically plausible.
- `Arcade`: high assist, high walkable slope limit, larger steps, quick
  smoothing, non-trigger climb/water allowances, and larger replay buffers. Use
  for high-speed traversal, stylized combat spaces, and prototype maps.
- `Vr`: low step height, low fall speed, small jump height, disabled angular
  platform inheritance, slower climbing, and longer correction smoothing. Use
  when camera comfort matters more than traversal aggression.

Treat presets as starting points. Record any mode-specific overrides in the
owning gameplay config asset and keep the base preset name with the override set
so QA can reproduce the movement stack.

## Tuning Workflow

1. Pick the closest preset with `CapsuleCharacterControllerPreset::for_kind`.
2. Validate the preset using `CapsuleCharacterControllerPreset::validate`.
3. Build a controller with `CapsuleCharacterController::from_preset` or
   `CapsuleCharacterController::new(preset.controller)` when overriding values.
4. Tune one subsystem at a time: capsule, ground, slope, step, ledge, platform,
   swimming, climbing, stance, gravity, prediction, then debug display.
5. Capture before/after debug snapshots with
   `CapsuleCharacterController::build_debug_snapshot`.
6. Run the validation commands in this guide and attach the command output to
   the tuning review.

Never compensate for bad level collision by inflating `skin_width`,
`max_step_height`, or `max_ground_distance` globally. Fix the collision asset or
create a local override for that movement mode.

## Capsule And Grounding

Use `CapsuleCharacterControllerConfig` for collision shape and sweep behavior:

- Increase `radius` for broad, stable characters; lower it only when narrow
  spaces are intentional.
- Increase `half_height` with camera height; do not use it to fake jump height.
- Keep `skin_width` small enough that the controller does not visibly hover.
- Increase `max_depenetration_iterations` only for dense collision scenes.
- Increase `max_sweep_iterations` when repeated slide clipping is expected.

Use `CapsuleGroundProbeConfig` for grounded state:

- `max_ground_distance` is the stick-to-ground tolerance.
- `probe_distance` must cover the largest expected drop that still needs a
  grounded decision.
- `max_walkable_slope_degrees` should match the locomotion mode, not the art
  angle of a single ramp.
- `ray_start_offset` should be high enough to escape numerical skin overlap and
  low enough that it does not skip thin floors.

## Slope Step Ledge Tuning

Use `CapsuleSlopeHandlingConfig` when the player can push into ramps:

- `max_walkable_slope_degrees` must align with `CapsuleGroundProbeConfig`.
- `steep_slide_speed` is a game-feel value. Raise it for obvious rejection,
  lower it for VR and careful traversal.
- Keep `preserve_walk_speed_on_slope` enabled unless uphill speed changes are a
  deliberate design requirement.

Use `CapsuleStepClimbConfig` for small obstacles:

- `max_step_height` should be below the smallest intentional jump-only obstacle.
- `smooth_elevation_seconds` should be short for platformer/arcade movement and
  longer for VR comfort.
- Step tuning must be reviewed with low sweep, raised sweep, and landing probe
  debug markers visible.

Use `CapsuleLedgeDetectionConfig` for edges:

- Enable `prevent_walking_off` for realistic FPS and VR movement.
- Enable `auto_grab` only for modes that promise authored traversal assists.
- Tune `edge_search_iterations` with deterministic replay in mind; more
  iterations improve edge precision but increase query cost.
- Use `grab_hang_offset` to place the hang pose, not to hide bad ledge geometry.

## Platforms Swimming And Climbing

Use `CapsuleMovingPlatformConfig` for attached floors:

- Keep `inherit_linear_velocity` enabled for almost every mode.
- Disable `inherit_angular_velocity` for VR when rotating platforms create
  camera discomfort.
- Clamp `max_inherited_speed` so moving platforms cannot inject unbounded player
  velocity.
- Use `stay_attached` when elevators or boats need stable contact through small
  frame-to-frame gaps.

Use `CapsuleSwimmingConfig` for water volumes:

- Keep `require_trigger_volume` enabled for production water unless arcade mode
  intentionally treats any overlapping water collider as swimmable.
- Raise `water_drag` for heavier swimming and lower it for arcade movement.
- Clamp `max_vertical_swim_speed` before changing buoyancy acceleration.

Use `CapsuleClimbableSurfaceConfig` for ladders and climb surfaces:

- Keep `require_trigger_surface` enabled for authored climb volumes.
- Raise `surface_probe_distance` only when player-facing geometry is offset from
  the climb trigger.
- Tune `climb_speed` separately from ground speed so ladders do not inherit
  sprint balance.

## Stance Gravity Prediction Debugging

Use `CapsuleStanceConfig` to keep stance transitions readable:

- `prone_half_height` must stay less than or equal to `crouch_half_height`.
- Preserve foot position when shrinking or expanding the capsule.
- Always run stand-up clearance checks when raising the capsule.

Use `CapsuleGravityConfig` for jump and fall feel:

- `jump_height` is the designer-facing value; the controller derives impulse.
- `low_gravity_scale` should be mode-specific and nonnegative.
- `max_fall_speed` is both a game-feel and safety value.

Use `CapsuleMovementPredictionConfig` for networked movement:

- `position_tolerance` and `velocity_tolerance` define when local prediction can
  stay in sync.
- `correction_smoothing_seconds` controls visual correction speed.
- `max_replay_inputs` must be large enough for expected latency and small enough
  to bound reconciliation cost.

Use `CapsuleCharacterDebugRequest` and `CapsuleCharacterDebugSnapshot` for
review captures. Required debug evidence for movement tuning reviews includes
capsule axis, ground normal, slope normal, step displacement and elevation
markers, contact points, contact normals, slope angle metrics, contact count,
and blocked state.

## Validation Commands

```bash
python3 V2/ue/Tools/check-v2-maya-character-controller-tuning-guide.py
python3 V2/ue/Tools/check-v2-maya-character-controller-presets.py
python3 V2/ue/Tools/check-v2-maya-character-controller-debugging.py
python3 V2/ue/Tools/check-v2-ci-workflow.py
python3 V2/ue/Tools/check-v2-buildgraph.py
python3 -m json.tool V2/ue/Content/V2/Gameplay/Character/MayaCharacterControllerTuningGuide_V2_Contract.json
python3 -m json.tool V2/ue/Build/Horde/v2-buildgraph-job.json
cargo fmt --manifest-path libs/maya/engine-core/Cargo.toml -p maya-physics -- --check
CARGO_BUILD_JOBS=1 cargo test --locked --manifest-path libs/maya/engine-core/Cargo.toml -p maya-physics character_controller -- --nocapture
```

## Release Checklist

- The selected preset and all overrides are listed in the tuning review.
- Debug snapshot captures show capsule, ground, step, slope, and contact
  evidence for the changed traversal path.
- Networked movement changes include prediction tolerance and replay evidence.
- VR changes explicitly review step height, fall speed, angular platform
  inheritance, and correction smoothing.
- CI has run the guide checker, preset checker, debug checker, workflow checker,
  BuildGraph checker, JSON validation, Rust format check, and focused
  character-controller tests.
