Files
Syplheed-Reborn/docs/re/flight-speed-law.md
Claude (auto-RE) 86fcfcc8b0 re(flight): turn rates confirm AV_* are rate caps and _Min/_Max mean at min/max speed
turn_law.py pins the speed regime with a throttle, holds a stick axis and
differentiates the craft's own forward vector over 1-second windows.

  slow + nose down  ~87 deg/s   (AV_PitchMinus_Min 75)
  fast + nose down  ~54         (AV_PitchMinus_Max 40)
  slow + nose up   ~175         (AV_PitchPlus_Min 150)
  fast + nose up   ~136         (AV_PitchPlus_Max 70)

So agility falls with speed (_Min/_Max are at minimum/maximum speed, not rate
bounds) and pitching up is ~2x pitching down, exactly as the field pairs say.

Control mapping measured: LX is roll (forward vector barely moves, 3-5 deg/s), LY is
pitch (+1 = nose down per vgamepad's LY: -1 = up), and the right stick does not steer
at all.

The ~1.2x overshoot seen in the speed law appears again here (1.16-1.35x), and a
unit scale cannot explain both m/s and deg/s — a TIME BASE can: if the guest's
simulated second is shorter than the wall-clock second the probe measures against,
every rate reads high by the same factor. So the definition numbers are
self-consistent and these measurements confirm the shape of the law, not a scale.

Recorded 🟡: no yaw input found (AV_Yaw_* exists but neither stick yaws), which with
roll on LX and MaximumBank_Normal points at a bank-to-turn model.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 15:30:00 +00:00

103 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The throttle is a TARGET-SPEED selector — measured against the definition (2026-08-13)
**Status: ✅ for the shape of the law, 🟡 for the unit scale.**
The unit definition gives `MinimumVelocity 100`, `CruisingVelocity 350`,
`MaximumVelocity 1200`, `Acceleration 600` and `Deceleration 500` for
`UN_f001_TCAF_DeltaSaber_T_Player` ([values](captures/unit-runtime-fields.csv)),
but not **how** the game applies them. This measures it.
Method — [`tools/re-capture/speed_law.py`](../../tools/re-capture/speed_law.py):
lock onto the player entity once, then sample its own position triple in guest RAM
while holding each throttle input in turn (8 s per phase, 20 Hz). Speed is
differentiated over **1-second windows**, never per sample.
## Result
| phase | measured speed (1 s windows) | settles to | definition field |
|---|---|---|---|
| no throttle | 367 403 471 365 463 463 365 | **~420** | `CruisingVelocity` 350 |
| `RT` held | 1041 1376 1551 1379 1596 1510 1620 | **~1 530** | `MaximumVelocity` 1200 |
| release | 1314 672 432 452 432 450 408 | back to **~440** | — |
| `LT` held | 203 121 135 121 115 146 122 | **~125** | `MinimumVelocity` 100 |
| release | 369 451 427 425 445 390 465 | back to **~430** | — |
So the throttle **selects a target speed** — minimum / cruise / maximum — and the
craft converges to it; releasing either trigger returns it to cruise. It is not a
force model with the throttle adding thrust, which is what a reimplementation would
most likely have assumed from `Acceleration`/`Deceleration` alone. Those two fields
govern the **convergence rate**: the release phase falls ~1 314 → ~432 in about two
seconds (~440 units/s², against `Deceleration` 500) and the `RT` phase climbs ~420 →
~1 550 in two to three seconds (~470560 units/s², against `Acceleration` 600).
## 🟡 The unit scale
Measured world-space speeds run **≈1.21.3× the definition numbers** in all three
regimes (cruise 1.21, maximum 1.28, minimum 1.32). The HUD, meanwhile, reads
**350** at cruise — the definition value exactly. So the definition's velocity unit
is the HUD's, and entity world coordinates are a constant multiple of it, close to
**1.25**. The spread across regimes is larger than the constant itself is precise,
because the craft is manoeuvring under fire while sampled (straight-line
displacement per window under-reads a curving path), so this is recorded as a
measured range rather than a pinned constant.
## Traps
* **`RT`/`LT` are analogue triggers**, so `vgamepad trig RT 1.0` holds the throttle;
the button verb `hold RT` is a **silent no-op**. The first run of this probe
measured the drift of a craft nobody was flying.
* **Do not differentiate per sample.** The guest updates the position slower than
20 Hz, so per-sample differences alternate between 0 and a double step —
`0, 1519, 1985, 0, 2681…` for a craft flying smoothly.
* **Bind late, measure fast.** The player entity is not in the typed-entity scan
for the first ~15 s of a mission, and the craft dies within a few minutes if
nobody is flying it — one earlier attempt ended at `GAME OVER` mid-probe.
Raw samples: [`captures/speed-law-throttle-phases.csv`](captures/speed-law-throttle-phases.csv).
---
# Turn rates: `AV_*` are rate caps, and `_Min`/`_Max` mean *at minimum/maximum speed*
`tools/re-capture/turn_law.py` pins the speed regime with a throttle, holds a stick
axis, and differentiates the craft's **own forward vector** over 1-second windows.
**Control mapping, measured**`LX` is **roll** (the forward vector barely moves
under it: 35 °/s residual), `LY` is **pitch** (`vgamepad` documents `LY: -1 = up`,
so `+1` is nose down = the `PitchMinus` family), and the **right stick does not
steer at all** (0 °/s).
| phase | measured (1 s windows) | definition |
|---|---|---|
| slow + nose down | 85 · 96 · 82 → **~87** | `AV_PitchMinus_Min` **75** |
| fast + nose down | 55 · 45 · 63 → **~54** | `AV_PitchMinus_Max` **40** |
| slow + nose up | 181 · 164 · 181 → **~175** | `AV_PitchPlus_Min` **150** |
| fast + nose up | 103 · 130 · 175 → **~136** | `AV_PitchPlus_Max` **70** |
Two claims of the field names are confirmed:
* **Agility falls with speed** — every rate drops when the throttle goes from `LT`
to `RT`, so `_Min`/`_Max` are *at minimum / maximum speed*, not floor/ceiling of
the rate.
* **Pitching up is about twice as fast as pitching down**, exactly as the pair
150/75 (slow) and 70/40 (fast) says.
## The ~1.2× factor is a TIME BASE, not a unit scale
The speed law measured 1.21 / 1.28 / 1.32 × its definition values; the pitch rates
measure 1.16 / 1.35 / 1.17 / 1.94 × theirs. A **unit scale** would have to differ
between metres-per-second and degrees-per-second — it cannot explain both. A **time
base** does: if the guest's simulated second is shorter than the wall-clock second
this probe measures against, every rate reads high by the same factor. So the
definition numbers are self-consistent and a reimplementation should take them at
face value; these measurements confirm the **shape** of the law (which field governs
what, and how the regimes switch), not a scale correction.
🟡 **No yaw input was found.** `AV_Yaw_{Min,Max}` (45 / 25 °/s) exists, but neither
stick yaws the craft. With `MaximumBank_Normal` (60) and roll on `LX`, a
**bank-to-turn** model is the obvious reading — sustained turns come from rolling and
pitching — but the yaw fields may equally belong to the AI or to an input this probe
has not driven.
Raw samples: [`captures/turn-law-pitch-phases.csv`](captures/turn-law-pitch-phases.csv).