feat(input): full controller support, rebindable controls, and rotation fixes

Playing with a gamepad did not work: all six move_* actions had no joypad
event at all, so a pad could yaw/pitch/roll/turbo but could not translate.
Nothing caught it because every action existed and the game booted fine —
no assertion checked that an action is reachable on *both* devices.

Controller layout, on the 6DOF convention (left stick aims, right stick
translates), using all six of the pad's analog axes for the ship's six
degrees of freedom:

  left stick   yaw + pitch        right stick  strafe + vertical
  LB / RB      roll               RT / LT      forward / back
  L3           turbo              R3           ball camera

Input is now read with Input.get_axis instead of is_action_pressed, so
triggers and sticks are proportional. Keyboard values are unchanged.

Three rotation bugs found by measuring a real Ship rather than reading the
code:

- apply_torque() is world-space and the torque was never rotated into the
  hull's frame (unlike thrust, which uses -ship_basis.z). Roll input became
  pitch after a 90 degree turn and inverted at 180, so the controls were
  correct flying up-field and backwards flying back.
- ship.tscn's inertia is Vector3(7, 1, 7) but a flat torque was applied to
  every axis, giving yaw 7x the angular acceleration of pitch and roll
  (172 deg/s vs 52). Torque is now scaled per-axis by inertia, so
  rotation_acceleration means rad/s^2 and all three axes match. Yaw is
  unchanged.
- pitch_down pitched the nose UP: get_axis's arguments were reversed, so
  the I/K keys and the stick each did the opposite of their label.

Menus were unusable on a pad for a separate reason: Godot 4.7 gives
ui_up/down/left/right joypad events by default but leaves ui_accept and
ui_cancel with none (verified against a pristine project), so a controller
could move the highlight and never press anything. A confirms and B goes
back. Gameplay exits on a new leave_gameplay action (Escape / Start) rather
than ui_cancel, so carrying B for menus cannot abandon a live match.

Bindings for both devices are rebindable in Settings -> Controls, persisted
to user://input.cfg — a separate file from settings.cfg because
VideoSettings.save() rewrites that file wholesale and would drop any
section it does not know about. project.godot stays the source of truth for
defaults; overrides are only ever a delta on top of a boot-time snapshot.

Verified: 268 unit tests, the ENet integration gate, and a 16-sample
before/after comparison of networked prediction residuals showing the
physics change does not regress them (median 0.083m -> 0.065m).

Note for follow-up: every policy in Game/bots/ was trained against the old
sluggish, world-axis rotation and will over-rotate until retrained.
This commit is contained in:
Josh Creek
2026-09-06 20:41:20 +01:00
parent 00b900d864
commit 076d27a564
17 changed files with 1430 additions and 87 deletions
+52 -12
View File
@@ -27,18 +27,58 @@ Welcome to space, pilot! This guide will teach you everything you need to know a
### Controller Controls
#### Translation
Button names are the Xbox layout; a PlayStation pad maps the same physical
positions (A = ✕, B = ○, X = □, Y = △).
- Left Stick - Strafe (Left/Right) + Thrust (Forward/Back)
- Right Trigger - Forward Thrust
- Left Trigger - Reverse Thrust
- Face Buttons - Up/Down Thrust
**The left stick points the nose, the right stick moves the hull.** Your ship has
six degrees of freedom and a pad has exactly six analog axes, so every one gets a
real axis rather than an on/off button.
#### Rotation
#### Rotation — left stick and shoulders
- Right Stick - Pitch/Yaw
- Shoulder Buttons - Roll
- `A Button` - Turbo Boost
- Left Stick (left/right) - Yaw
- Left Stick (up/down) - Pitch. Flight-sim polarity by default: **push the
stick forward and the nose goes down.** Flip it with "Invert pitch" in
Settings → Controls.
- `LB` - Roll Left (Bank Left)
- `RB` - Roll Right (Bank Right)
#### Translation — right stick and triggers
- `RT` - Forward Thrust (Main Engines)
- `LT` - Reverse Thrust (Retro Engines)
- Right Stick (left/right) - Strafe (Port/Starboard Thrusters)
- Right Stick (up/down) - Thrust Up/Down (Dorsal/Ventral Thrusters)
- `L3` (click the left stick) - Turbo Boost
`X` and `Y` are deliberately unused in flight, and `A`/`B` are menu-only, so a
reflexive face-button press never does anything mid-match.
#### Menus
- D-Pad or Left Stick - move the highlight
- `A` - select
- `B` - back
- `Start` - leave a match in progress (deliberately not `B`, which is too easy
to press by accident mid-game)
#### Other
- `R3` (click the right stick) - Toggle ball camera
- `D-Pad Up` - Reset the ball (Free Play only)
The triggers and sticks are **analog**: a half-pulled trigger gives half thrust,
and a gentle stick lean gives a gentle turn. Keyboard keys are all-or-nothing,
which is the main reason a pad is easier to fly precisely.
### Rebinding
Every control above — keyboard and controller alike — can be remapped in
**Settings → Controls**. Pick the device with the Keyboard/Controller toggle,
click the binding you want to change, and press the key or button to assign.
Binding an input that is already in use unbinds it from the action that had it,
and the screen tells you which. "Reset all bindings to defaults" restores this
table.
## 🛸 Basic Flight Principles
@@ -69,7 +109,7 @@ Your ship is a **realistic space vehicle** with the following characteristics:
#### Camera Control
- **Ball Cam**: Press `Enter` to toggle ball tracking camera
- **Ball Cam**: Press `Space` (or `R3` on a controller) to toggle ball tracking camera
- **Ship Cam**: Normal follow camera that looks where your ship points
### Intermediate Maneuvers
@@ -115,7 +155,7 @@ Your ship is a **realistic space vehicle** with the following characteristics:
## 🎮 Ball Cam vs Ship Cam
### Ball Cam Mode (`Enter` to toggle)
### Ball Cam Mode (`Space` / `R3` to toggle)
- **Camera**: Always looks toward the ball
- **Ship Control**: Based on ship orientation (NOT camera view)
@@ -133,7 +173,7 @@ Your ship is a **realistic space vehicle** with the following characteristics:
### Turbo System
- **Activation**: Hold `Shift` (keyboard) or `A` (controller) while thrusting forward
- **Activation**: Hold `Shift` (keyboard) or `L3` (controller) while thrusting forward
- **Effect**: 2.5x thrust multiplier on main engines only
- **Strategy**: Use for quick acceleration or emergency maneuvers