Docs sweep: README + KB catch up with the full session's work
Coverage audit of this session's ~30 commits against the docs found
gaps; fixed:
- README §Multiplayer was stale (only the old mesh flow, 'combat in
progress'): now leads with the relay + operator-console path
(internet play, join.bat/play_solo.bat, patient wait) and lists what
the mesh path has verified (4-pod, camera seat, callsigns, clock);
README controls line updated (turn/twist/pitch, pad, CONTROLS.MAP)
- decomp-reference env table: added BT_CAM_LOG, BT_SPEC_LOG (were in
code, not the hub); BT_INPUT_LOG note gains the twist/elev axis
- pod-hardware §input remap: the AXIS SIGN CONVENTION finding
(positive sim = CCW/left; bridge negates once per channel;
screenshot-forensics lesson) was only in commit cb82d8c -- now durable
- multiplayer.md: PATIENT WALK-UP + MISSION CLOCK sections (features
shipped in f9f230c/f57d25f, only incidentally referenced before)
checkctx CLEAN (20 topics, 68 glossary keys). All session features
now have topic-file coverage.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
ff5260ce98
commit
d26d0375ae
@@ -97,10 +97,31 @@ The authentic stack (gait, collision, real controls) is **default-on**; set `=0`
|
||||
Debug/harness flags: `BT_FORCE_THROTTLE=1` (auto-walk), `BT_SPAWN_ENEMY=1` (spawn a target dummy),
|
||||
`BT_FORCE_FIRE=1` (auto-fire), `BT_HEAPCHECK=1` (whole-heap validation — slow), `BT_BSL=0` (legacy
|
||||
texture decode), `BT_DEV_GAUGES=1` (render the cockpit MFDs in a dev window), `BT_LOG=<file>`.
|
||||
Interactive: **WASD** drive, **Space/Ctrl** fire, **X** all-stop. The complete env-gate table is in
|
||||
`context/decomp-reference.md` §6 (routed from `CLAUDE.md`).
|
||||
Interactive: **WASD** drive, **A/D** turn, **Q/E** torso twist, **R/F** torso pitch aim,
|
||||
**Space / 1-4** fire, **X** all-stop, **V** view, **M** control mode. An Xbox-type controller
|
||||
works out of the box. All bindings are user-editable in **`content/CONTROLS.MAP`** (delete it to
|
||||
restore the compiled-in WASD default; `content/CONTROLS_NUMPAD.MAP` is an alternate profile). The
|
||||
complete env-gate table is in `context/decomp-reference.md` §6 (routed from `CLAUDE.md`);
|
||||
controls/pad details in `context/pod-hardware.md`.
|
||||
|
||||
## Multiplayer (two instances, one box)
|
||||
## Multiplayer
|
||||
|
||||
**Modern path (relay + operator console).** Pods make ONE outbound connection to a relay/console,
|
||||
so internet play needs no per-player port forwarding and CGNAT-safe LAN discovery just works. Run
|
||||
the operator station:
|
||||
|
||||
```
|
||||
python tools/btoperator.py # PySide6 GUI: build the mission egg (validated dropdowns),
|
||||
# start the relay, watch pods arrive, assign seats, LAUNCH,
|
||||
# end the timed mission, export player join.bat scripts
|
||||
```
|
||||
|
||||
Players run one universal `join.bat` (internet, seat assigned by the relay) or `join_lan.bat`
|
||||
(same LAN, auto-discovers the console) or `play_solo.bat` (offline practice) — see `players/`.
|
||||
The pod waits patiently if the session isn't up yet. Full architecture, wire format, and the
|
||||
D1 relay/UDP design: `context/multiplayer.md`.
|
||||
|
||||
**Legacy mesh (two instances, one box), still supported:**
|
||||
|
||||
```
|
||||
instance A: btl4.exe -egg MP.EGG -net 1501 (BT_LOG=mp_a.log)
|
||||
@@ -108,8 +129,10 @@ instance B: btl4.exe -net 1601 (BT_LOG=mp_b.log)
|
||||
console: python tools/btconsole.py MP.EGG 127.0.0.1:1501 127.0.0.1:1601
|
||||
```
|
||||
|
||||
`-net <port>` enables networked mode; the console emulator delivers the mission egg and the launch
|
||||
command. Entity + movement replication works; cross-pod combat is in progress.
|
||||
`-net <port>` enables networked mode. Verified end-to-end: full entity/movement replication,
|
||||
cross-pod combat + kills, per-pilot paint + callsigns, timed missions, 4-pod live sessions, and a
|
||||
spectator/broadcast **camera seat** (`hostType=1 vehicle=camera`) with auto-directed coverage and
|
||||
a live ranking window.
|
||||
|
||||
## Status & continuing the work
|
||||
|
||||
|
||||
@@ -268,7 +268,9 @@ default-ON (`'0'` disables).
|
||||
| `BT_RELAY=<host:port\|auto>` | **D1 relay mode** — dial the relay/operator console instead of the P2P mesh; `auto` = LAN UDP-broadcast discovery on udp/15999 ([[multiplayer]] D1) |
|
||||
| `BT_SELF=<[pilots] tag>` | claim a specific roster seat in relay mode; absent/`auto` = the relay assigns one (SEAT_REQUEST) |
|
||||
| `BT_RELAY_TCP_ONLY=1` | disable the relay UDP channel (all unreliable traffic rides the TCP relay conn) |
|
||||
| `BT_INPUT_LOG` | binding-engine trace: CONTROLS.MAP load, button/keypad emissions, pad connect ([[pod-hardware]] §Desktop input remap) |
|
||||
| `BT_INPUT_LOG` | binding-engine trace: CONTROLS.MAP load, button/keypad emissions, pad connect, torso twist/elev axis ([[pod-hardware]] §Desktop input remap) |
|
||||
| `BT_CAM_LOG` | camera-seat/broadcast trace: streamed camera network count, director pick + Players-group census, ship follow state, PlayerLink dispatch/receive, ranking-window render ([[multiplayer]] camera seat) |
|
||||
| `BT_SPEC_LOG` | manual spec-audit dump at subsystem ctor: torso speed/limits, heat-sink count, reservoir capacity, per-subsystem coolant loop ([[pod-hardware]] §Spec cross-check) |
|
||||
|
||||
Full render/locomotion gates (BT_RAMP, BT_MATPRI, BT_CULL, BT_SHADOW_*, BT_LODSEL, BT_ADDLOD,
|
||||
BT_PUNCH, …) are catalogued in [[rendering]]. Warp visuals: [[translocation-warp]].
|
||||
|
||||
@@ -326,6 +326,22 @@ phase). Plan: `~/.claude/plans/partitioned-snuggling-piglet.md`.
|
||||
SEAT_REQUEST branch (btconsole.py). Verified: 8/8 stub tests (distinct seats, FULL on
|
||||
exhaustion, claim clears reserve, duplicate-HELLO refused) + 2-node localhost e2e with NO
|
||||
BT_SELF on either pod → both seated, full ladder, launch, UDP flowing.
|
||||
- **PATIENT WALK-UP (2026-07-18) [T2]**: a pod dialed at a relay that isn't up yet no longer
|
||||
aborts (release `Fail()` is a bare `abort()` = looked like a "crash", field report). Both the
|
||||
seat request (`RelayRequestSeat`) and LAN discovery (`BT_RELAY=auto`) now RETRY (2s dials, 30
|
||||
min cap) with live status into the join.bat console window (`BTRelayWaitStatus` attaches to the
|
||||
parent cmd via `AttachConsole(ATTACH_PARENT_PROCESS)`): a banner + progress dots, a distinct
|
||||
"game is FULL, waiting for a free seat" state, "seat assigned — joining!" on success. The pod
|
||||
joins automatically the moment the operator starts the session; the unreachable MessageBox only
|
||||
fires at the 30-min give-up. Removes the session-before-join ordering requirement. Verified:
|
||||
pod launched at a dead relay, waited 20+s, relay started, pod seated + reached RunningMission
|
||||
with no user action.
|
||||
- **MISSION CLOCK (2026-07-18) [T2]**: the egg `[mission] length=` (600 = the 10-min pod mission)
|
||||
drives the pod countdown + the final-30s ranking window; the relay now SENDS
|
||||
`Application::StopMissionMessage` (clientID 4, msgID 6, exitCode 0) at length+2s grace, or on
|
||||
the operator's ⏹ END MISSION button (stdin `stop`). Was half-implemented — nothing fired it in
|
||||
1995 the console owned the stop. Pod runs the authentic fade → mission-loop exit → clean
|
||||
process exit. Verified live (40s test mission ended on the clock).
|
||||
- **OPERATOR CONSOLE (2026-07-18)**: `tools/btoperator.py` (PySide6) — the lost 1995 operator
|
||||
station recreated: mission editor with ALL values validated live from BTL4.RES
|
||||
(`tools/eggmodel.py`: maps=type14∩26, colors/badges/patches from the type-25 vehicletable,
|
||||
|
||||
+10
-1
@@ -47,7 +47,16 @@ Axes: Throttle (lever, rate-walks + sticks), LeftPedal/RightPedal/Pedals (turn,
|
||||
JoystickX (torso twist), **JoystickY (torso ELEVATION — pitch aim; every 1995 control mode
|
||||
routes it to Torso::SetAnalogElevationAxis; keys R/F + pad LeftStickY in the default map;
|
||||
verified to the authentic VerticalLimitTop clamp, 20° on the Blackhawk; aims the GUNS — reads
|
||||
on the HUD elevation tape, the eyepoint stays level)**. Emissions mirror the RIO conventions above exactly; the four fire
|
||||
on the HUD elevation tape, the eyepoint stays level)**.
|
||||
**AXIS SIGN CONVENTION (2026-07-18, user-verified) [T1]:** the sim uses MATH convention —
|
||||
positive turnDemand / twist / free-aim slew is **CCW (LEFT)**. On the pod the RIO Ranger owned
|
||||
the hardware sign; the desktop key bridge negates ONCE per channel (`key_turn = -gBTDrive.turn`;
|
||||
`stickPosition.x = -gBTTwistAxis`; the SetFreeAimSlew call-sites pass the bridge value un-negated)
|
||||
so input-right = turn/twist RIGHT (manual p8: "pulling your joystick to the right torso twists
|
||||
your 'Mech to the right"). Forced/BT_GOTO harness demands are already sim-frame and stay
|
||||
un-negated. Lesson: large-rotation screenshot comparisons are AMBIGUOUS — trust tracked
|
||||
landmarks, numeric yaw telemetry with an established convention, or the user's live observation.
|
||||
Emissions mirror the RIO conventions above exactly; the four fire
|
||||
buttons (0x40/45/46/47) publish as levels to the bring-up fire channels instead of buttonGroup
|
||||
(avoids double-fire once the streamed ChooseButton mappings are exercised). XInput loads
|
||||
dynamically (xinput1_4 → 9_1_0; disconnected-pad probing rate-limited to 1 Hz). **Keys claimed by
|
||||
|
||||
Reference in New Issue
Block a user