Each MFDSplitView window now carries its display's physical button bank, placed as in the pod (addresses per vRIO CockpitLayout): a 4x2 red cluster around each MFD glass (anchors 0x2F/0x27/0x37 upper, 0x0F/0x07 lower, addresses descending row-major) and 6 amber buttons down each side of the map - Secondary 0x10-0x15 left, Screen 0x18-0x1D right; the remaining column addresses are Tesla relays, per the pod wiring, so they get no buttons. Buttons light from the lamp state the game commands: PadRIO grows a static active-instance hook (SetScreenButton/GetLampState); mouse press/release feeds PadRIO's desired-state sampling alongside pad and keyboard, and paint decodes the lamp byte (state1/state2 brightness, solid/slow/med/fast flash animated by tick). With real serial hardware (no PadRIO) the buttons draw dark and inert. Verified: map flank buttons light per the game's preset lamps, aligned with the labels the glass draws at its edges; MFD clusters render 4+4. Roadmap: queued the vRIO Dynamic Lighting RGB-keyboard lamp mirror as a polish-pass item. dist repacked. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
143 lines
8.1 KiB
Markdown
143 lines
8.1 KiB
Markdown
# RP 4.12 Roadmap — Steam + Internet Multiplayer
|
||
|
||
Working plan for turning the 4.11 arcade/cockpit build into a consumer Steam
|
||
title. Status: initial assessment (2026-07-12). Items marked **[investigate]**
|
||
need code archaeology before they become concrete tasks.
|
||
|
||
## Where 4.11 stands
|
||
|
||
- **Game**: `rpl4opt.exe`, 32-bit Win32, DirectX 9, VS2005/2008-era `.vcproj`
|
||
projects ([BUILD.md](../BUILD.md)). Builds clean on VC++ 2008 Express.
|
||
- **Networking**: the engine has a real multiplayer layer —
|
||
[MUNGA/NETWORK.cpp](../MUNGA/NETWORK.cpp), [MUNGA/SOCKET.cpp](../MUNGA/SOCKET.cpp),
|
||
[MUNGA/HOSTMGR.cpp](../MUNGA/HOSTMGR.cpp), interest management
|
||
([MUNGA/INTEREST.cpp](../MUNGA/INTEREST.cpp)), bound to WinSock2 in
|
||
[MUNGA_L4/L4NET.CPP](../MUNGA_L4/L4NET.CPP) (TCP; the 2007 WinSock port of the
|
||
1995 code). It was built for pods on a dedicated LAN.
|
||
- **Input/output**: the pod's controls are a **RIO** serial board (buttons,
|
||
five analog axes, lamps) and a **plasma display** (128×32 dot-matrix on COM2,
|
||
driven by `MUNGA_L4/L4PLASMA.CPP`). No cockpit, no controls.
|
||
- **Session control**: races are configured and launched from the outside by
|
||
**TeslaConsole** over the Munga control protocol (TCP 1501, via `Munga Net.dll`),
|
||
with TeslaLauncher (TCP 53290) handling app lifecycle on each pod.
|
||
|
||
## Workstream A — Play without the cockpit (from vRIO)
|
||
|
||
vRIO already solved the "no hardware" problem once, from the outside: it speaks
|
||
the RIO serial protocol as the device, with a complete **keyboard + XInput
|
||
bindings model** (deflect/rate/deadzone/invert per axis, bindings file), and
|
||
vPLASMA renders the display's recovered command grammar
|
||
(`VPlasma.Core/Protocol/PlasmaProtocol.cs`, grammar recovered from
|
||
`L4PLASMA.CPP` itself). For 4.12 that logic moves *inside* the game:
|
||
|
||
**Design principle — recreate the cockpit's feel on screen.** The 4.12 screen
|
||
layout places the RIO panel controls *around* the displays in the same
|
||
physical arrangement as the pod: MFD button clusters framing the screens,
|
||
board columns and keypads where they sit in the cockpit, the plasma glass in
|
||
its place above. vRIO's panel layout data (`VRio.Core`, the five MFD
|
||
clusters / four board columns / two keypads / encoder-gauge strip) is the
|
||
geometry reference — it is already the faithful software copy of the physical
|
||
panel. On-screen buttons light with the same lamp states the game commands,
|
||
so press-feedback works like the real button field.
|
||
|
||
- ✅ **Prototype landed (2026-07-12).** The seam existed: the controls manager
|
||
consumes a small RIO surface (8 methods + 5 analog scalars), now split out
|
||
as `RIOBase`. **PadRIO** (`L4CONTROLS=PAD`) implements it from XInput + the
|
||
PC keyboard with vRIO's default profile — the stock `VTVRIOMapper`, lamps,
|
||
and button field run unchanged, no serial, hot-plug supported. Verified:
|
||
boots and plays with vRIO off and no COM ports.
|
||
- ✅ Plasma display: **PlasmaScreen** (`L4PLASMA=SCREEN`) renders the same
|
||
`Video8BitBuffered` surface into a desktop "Plasma Display" window in
|
||
plasma orange — verified drawing live game content (score readout).
|
||
See BUILD.md §4 for bindings and the desktop `environ.ini`.
|
||
- ✅ **7-display cockpit in-engine** (`L4MFDSPLIT=1`): the five MFDs the pod
|
||
packed into the color channels of two video outputs, plus the
|
||
portrait-mounted map, now open as their own windows (green-screen MFDs,
|
||
90°-rotated map), rendered CPU-side from the shared gauge canvas — the
|
||
external BitBlt-mirror wrapper is obsolete. Verified visually (MFD score
|
||
readout, full tactical map).
|
||
- ✅ **Cockpit buttons on the displays** (2026-07-12): each split window
|
||
carries its physical button bank — 4+4 red buttons per MFD, 6 amber per
|
||
map side (Secondary/Screen columns; addresses per vRIO `CockpitLayout`,
|
||
placement per the pod). Mouse presses inject into `PadRIO`; the game's
|
||
lamp commands light them (verified: PRESET lamps lit on the map flank,
|
||
aligned with the glass's own edge labels).
|
||
- Next in A: port the full vRIO bindings-file model (deflect/rate/deadzone
|
||
per axis, rebinding); pilot keypad (numpad / on-screen 4×4 → KeyEvent);
|
||
Steam Input once C starts.
|
||
- Polish pass (queued): **vRIO's Dynamic Lighting RGB-keyboard mirror** —
|
||
lamp states glow on the physical keyboard's keys (per-key or zone-lit),
|
||
blinking with the flash modes. Needs package identity for background
|
||
light control (vRIO's `pkg\Register-vRIO.ps1` pattern; see the vRIO
|
||
README for the Settings → Dynamic Lighting steps).
|
||
- vRIO itself stays useful as a dev harness against unmodified builds.
|
||
|
||
## Workstream B — In-game sessions (from TeslaConsole)
|
||
|
||
Consumer players get no operator. The create/configure/launch flow that
|
||
TeslaConsole drives over TCP 1501 becomes in-game UI:
|
||
|
||
- Front-end menus: pilot setup, race/mission select, create/join session.
|
||
**[investigate]** how much of the mission-launch handshake lives in the game
|
||
(`MUNGA` mission/host code) vs. in the console — TeslaSuite's `Contract/` and
|
||
the console's Munga-protocol client are the reference implementation.
|
||
- **vPOD** (TeslaSuite) impersonates both the game client and launcher — a
|
||
ready-made test double while the launch flow is being internalized.
|
||
- TeslaLauncher's responsibilities (install, watchdog, auto-login) disappear —
|
||
Steam owns install/update/launch.
|
||
|
||
## Workstream C — Steam + internet multiplayer logistics
|
||
|
||
### Networking
|
||
|
||
- The engine's LAN TCP assumptions need auditing before anything else:
|
||
**[investigate]** what `HOSTMGR`/`NETWORK` actually synchronize (state
|
||
replication vs. lockstep), tick/latency assumptions, and who is authoritative.
|
||
A LAN design that tolerates ~1 ms RTT may need prediction/interpolation work
|
||
for 50–100 ms internet RTTs; the existing interest manager is a good sign.
|
||
- Transport: **Steam Networking Sockets** (`ISteamNetworkingSockets`) is the
|
||
target — it gives NAT traversal + Steam Datagram Relay for free, hides IPs,
|
||
and offers reliable + unreliable channels. Plan: introduce a transport
|
||
abstraction under `L4NET` so raw-socket LAN play (dev) and Steam sockets
|
||
(retail) coexist.
|
||
- Topology: player-hosted (listen server / P2P over SDR) is the low-cost
|
||
default for a pod-count-sized race; dedicated servers are a later option.
|
||
- Matchmaking: Steam **lobbies** (`ISteamMatchmaking`) for create/join/invite;
|
||
friends-list invites come nearly free once lobbies work.
|
||
|
||
### Steamworks integration
|
||
|
||
- Steamworks partner account + app credit (Steam Direct, $100/app), appid,
|
||
depot layout via SteamPipe. The old `Setup1/` installer project retires —
|
||
Steam delivers files; OpenAL / libsndfile runtime DLLs ship in the depot.
|
||
- `steam_api.dll` supports 32-bit Win32, so Steam does not *force* a 64-bit
|
||
port. It does require init/callback pumping in the main loop and the
|
||
overlay hooking D3D9 (works, but test early — old-engine present() paths
|
||
sometimes fight the overlay).
|
||
- Steam client requires Windows 10+ now, which **frees 4.12 from the XP-era
|
||
constraints** that shaped the 4.11/TeslaSuite line.
|
||
|
||
### Toolchain
|
||
|
||
- ✅ **Done (2026-07-12)** — the solution builds on **VS2022 (v143)** with the
|
||
Windows 11 SDK; see [BUILD.md](../BUILD.md) §3 for what changed and why.
|
||
Runtime-verified equivalent to the VC9 baseline (including RIO init against
|
||
vRIO). Remaining cleanups called out there: un-`/Zp1` the Windows-header
|
||
boundary, port `stdext::hash_map` → `std::unordered_map`, single-TU the
|
||
duplicated globals so `/FORCE:MULTIPLE` can go away.
|
||
- ✅ The pre-existing mission-load crash (NULL-texture `AddRef` in
|
||
`d3d_OBJECT::LoadTexture`) is fixed — missing textures render untextured and
|
||
log. The game boots standalone to a running window (BUILD.md §4). Note for
|
||
Workstream B: pod skins (`player1–8`) come from the presets /
|
||
replacement-material path the console used to drive; the in-game session UI
|
||
must own that.
|
||
|
||
## Suggested order
|
||
|
||
1. Toolchain upgrade to VS2022 (unblocks everything, no design risk).
|
||
2. Workstream A input layer (makes the game *playable* on a desktop — also the
|
||
fastest path to a demoable build).
|
||
3. Networking audit (**C**), then transport abstraction + Steam sockets.
|
||
4. Workstream B session UI, using vPOD as the test double.
|
||
5. Steamworks bring-up (appid, overlay, lobbies), SteamPipe packaging.
|