re(flight): the throttle is a target-speed selector, measured against the definition
speed_law.py locks onto the player entity once and samples its position while holding each throttle input, differentiating over 1-second windows. no throttle -> ~420 (CruisingVelocity 350) RT held -> ~1 530 (MaximumVelocity 1200) LT held -> ~125 (MinimumVelocity 100) release -> back to cruise, from either direction So the throttle SELECTS a target speed rather than adding thrust — which is what a reimplementation would most likely have assumed from Acceleration/Deceleration alone. Those govern the convergence rate instead: ~440 units/s^2 measured on release (Deceleration 500) and ~470-560 under RT (Acceleration 600). Recorded as 🟡: measured world speeds run ~1.2-1.3x the definition numbers in all three regimes while the HUD shows the definition value exactly (350 at cruise), so world coordinates are a constant multiple (~1.25) of the definition's velocity unit; the spread is wider than the constant is precise because the craft manoeuvres while sampled. Three traps documented: RT/LT are analogue triggers (the button verb is a silent no-op and the first run measured an unflown craft), per-sample differentiation aliases against the guest's update rate (0, 1519, 1985, 0, 2681 for smooth flight), and the player entity only enters the typed scan ~15 s in while the craft dies within minutes if nobody flies it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
This commit is contained in:
56
docs/re/flight-speed-law.md
Normal file
56
docs/re/flight-speed-law.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# 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 (~470–560 units/s², against `Acceleration` 600).
|
||||
|
||||
## 🟡 The unit scale
|
||||
|
||||
Measured world-space speeds run **≈1.2–1.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).
|
||||
Reference in New Issue
Block a user