# FPS Character Controller — Tactical Shooter

First-person character controller for the tactical shooter GDExtension simulation core.

## Architecture

The character controller is a **GDScript bridge** between Godot's input/physics system and the C++ `SimulationServer` (built in task `t_aca0f251`).

```
Godot Input
  │
  ├─► FPSCharacterController._physics_process()
  │      ├─ capture input (WASD, mouse, jump, sprint, crouch, shoot)
  │      ├─ build EntityInput Dictionary
  │      ├─ SimulationServer.apply_input(entity_id, input_dict)
  │      ├─ SimulationServer.fire_weapon(entity_id)  [if shoot]
  │      ├─ read entity position from server → apply to CharacterBody3D
  │      └─ apply mouse look (yaw on body, pitch on camera)
  │
  ├─► FpsCamera._process()
  │      ├─ view bobbing (head bob from movement)
  │      ├─ weapon sway
  │      └─ sprint FOV kick
  │
  └─► SimulationServer (C++ GDExtension)
         ├─ process_tick() @ 128Hz
         ├─ MovementComponent.update()
         ├─ HitDetection.process_shot()
         └─→ returns serialized snapshot
```

## Files

| File | Purpose |
|------|---------|
| `character/fps_character_controller.gd` | Main controller (CharacterBody3D). Input capture, simulation bridge, walk toggle, crouch, jump. |
| `character/fps_camera.gd` | First-person camera (Camera3D). Mouse look pitch, view bobbing, weapon sway, FOV kick. |
| `input/input_handler.gd` | Documentation of expected input map bindings. |

## Scene Setup

1. **Create a CharacterBody3D scene:**
   ```
   FPSCharacterController (CharacterBody3D)    — script: fps_character_controller.gd
   ├── FpsCamera (Camera3D)                     — script: fps_camera.gd
   ├── CollisionShape3D (CapsuleShape3D)        — radius: 0.4, height: 1.8
   └── Weapon (Node3D, optional)                — child of camera, rest transform tracked
   ```

2. **Configure exports** on the root node:
   - `mouse_sensitivity`: 0.1–0.2 for typical tactical feel
   - `walk_toggle`: `true` = tap Shift to toggle sprint (CS-style)
   - `crouch_toggle`: `false` = hold Ctrl to crouch (tactical-style)
   - `eye_height_stand` / `eye_height_crouch`: match your capsule height

3. **Set up Input Map** in Project Settings:
   - `move_forward` → W
   - `move_backward` → S
   - `move_left` → A
   - `move_right` → D
   - `jump` → Space
   - `sprint` → Shift
   - `crouch` → Ctrl
   - `shoot` → Mouse LMB
   - `aim` → Mouse RMB
   - `ui_cancel` → Esc (built-in, releases mouse capture)

4. **Integration with SimulationServer:**

   ```gdscript
   # In your game manager (autoload or scene root):
   var server = SimulationServer.new()
   server.set_tick_rate(128)
   server.start()
   var player_id = server.spawn_entity(Vector3(0, 0, 0))

   # When player scene is ready:
   $Player/FPSCharacterController.set_entity_id(player_id)

   # In _process(delta):
   while server.can_tick(delta):
       var snapshot = server.tick()
       # send snapshot to network layer
   ```

## Walk Toggle Behavior

- **`walk_toggle = true`** (default): Press Shift to toggle between walk and sprint. Press again to toggle off. Same feel as Counter-Strike's walk/run toggle.
- **`walk_toggle = false`**: Hold Shift for temporary sprint. Release to decelerate to walk speed.

## Crouch Behavior

- **`crouch_toggle = false`** (default): Hold Ctrl to crouch. Release to stand up.
- **`crouch_toggle = true`**: Press Ctrl once to crouch, press again to stand.

Crouch transitions are smooth lerps over `crouch_transition_time` seconds. The collision capsule height and camera eye height both lerp simultaneously.

## Standalone Mode

When no `SimulationServer` singleton is available, the controller falls back to built-in `CharacterBody3D` movement (`_move_local()`). This is useful for:
- Testing the character controller in isolation
- Prototyping without the GDExtension compiled
- Single-player scenarios without the full simulation stack

Configure `local_walk_speed`, `local_sprint_speed`, `local_crouch_speed`, etc. for standalone tuning.

## Dependencies

- **Godot 4.2+** (for `Input.get_vector`, `move_toward`, `StringName` literals)
- **SimulationServer GDExtension** (from task `t_aca0f251`) for server-authoritative mode
- Input map actions listed above

## See Also

- Scaffold: `t_aca0f251` — `src/movement_component.h` (C++ Quake/CS movement physics)
- Greybox map: `t_p1_greybox` — test environment for this controller
- Hitscan weapon: `t_p1_hitscan` — weapon firing + lag compensation
- Client prediction: `t_p1_pred` — client-side prediction + server reconciliation
- Round system: `t_p1_round` — win/loss/sudden death on top of character controller
