option(BT412 ... ON) gates the steamification layer for the merge-back into BT411, so the unified repo serves both fronts: - Default (BT412=ON): pod/dev game + PadRIO / plasma / front end / lobby -- all runtime-gated, so a -egg/-net launch still behaves as 4.11. - Pod-minimal (-DBT412=OFF, build-pod/): compiles OUT L4PADRIO, L4PADBINDINGS, L4KEYLIGHT, L4PLASMASCREEN, L4STEAMTRANSPORT, btl4fe, btl4console, btl4lobby. Seam sites carry #ifdef BT412: L4CTRL.cpp PAD token (log + ignore), L4GREND.cpp L4PLASMA=SCREEN (log + ignore), L4VB16.cpp (inert PadRIO stub -- call sites identical in both flavors), btl4main.cpp (front-end/marshal/lobby blocks out; zero-arg launch = 4.11 behavior). - The NetTransport seam ALWAYS compiles -- it is the wire for both flavors (WinsockNetTransport, verified byte-identical to the pre-seam arcade path). - BT412_STEAM now requires BT412 (configure-time FATAL_ERROR; negative-tested). Verified: OFF -- clean v143 link, solo DEV.EGG mission runs (31 subsystems tick, gait, targeting). ON -- zero-arg launch engages the front-end menu. STEAM -- links clean, ships steam_api.dll. Also: README/context docs for the flavors + the merge-back; corrected the stale Phase 3b DEFERRED note (the single-window cockpit landed 07-16) and the README's leftover 0xBD3 valve-gate claim (it is a damage/explosion hub). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
293 lines
21 KiB
Markdown
293 lines
21 KiB
Markdown
---
|
||
id: steamification
|
||
title: "BT412 Steamification — status, seams, and merge notes"
|
||
status: living
|
||
source_sections: "docs/BT412-ROADMAP.md; RP412 repo (C:\\vwe\\RP412) git history + docs"
|
||
related_topics: [pod-hardware, multiplayer, gauges-hud, build-and-run, wintesla-port]
|
||
key_terms: [egg, RIO, console]
|
||
open_questions:
|
||
- "BT cockpit button-bank geometry source (no vRIO CockpitLayout exists for BT): l4gauge.cfg / pod photos / Nick"
|
||
- "Does BT's rebuilt L4D3D still have RP's NULL-texture AddRef crash pattern?"
|
||
- "Does L4CONTROLS=PAD set primaryControlType=PrimaryRIO so MechRIOMapper engages unchanged?"
|
||
---
|
||
# BT412 Steamification — status, seams, and merge notes
|
||
|
||
BT412 = BT411 made distributable on Steam and playable over the internet with no pod
|
||
hardware, following the recipe RP412 proved end-to-end (RP411 → RP412). The full plan
|
||
and phase order: `docs/BT412-ROADMAP.md`. RP412 (`C:\vwe\RP412`) is the reference
|
||
implementation — its git history from commit `467934c` onward is the steamification,
|
||
grouped roughly: toolchain → PadRIO input → MFD-split cockpit → front end/LocalConsole
|
||
→ NetTransport/Steam sockets → lobby → bindings/KeyLight → packaging.
|
||
|
||
**Repo rule [T0]:** each checkout talks ONLY to its own gitea remote — `C:\VWE\BT412`
|
||
`origin` = `VWE/BT412.git`, `C:\VWE\BT411` `origin` = `VWE/BT411.git`. Cross-repo sync
|
||
is **local-path only** (`git fetch C:/VWE/BT412 master` from BT411 and vice versa) —
|
||
never a cross remote. Forked at BT411 `4e72f0c` (2026-07-14); **merged back 2026-07-17**
|
||
(see the merge-back section below) — BT411 is now the unified repo carrying both lines
|
||
behind the `BT412` compile gate.
|
||
|
||
## Merge-back into BT411 + the `BT412` compile gate (2026-07-17)
|
||
|
||
The whole steamification line was merged **back into BT411** so one repo serves both
|
||
fronts (pod work + internet MP). Mechanics [T2]:
|
||
- BT411's head was exactly `abed41e` — the catch-up point BT412 had already merged —
|
||
so the merge was a clean **fast-forward** of BT411 onto BT412's line via a
|
||
local-path fetch (no gitea remote touched from either side). BT411's dirty
|
||
`run/run.cmd` bench edit (pod `-net 1501` restart loop) was stashed and restored.
|
||
- **Compile gate:** CMake `option(BT412 ... ON)` + compile definition `BT412` on all
|
||
three targets. Gated OUT under `-DBT412=OFF` (the pod-minimal flavor, `build-pod/`):
|
||
`L4PADRIO`, `L4PADBINDINGS`, `L4KEYLIGHT`, `L4PLASMASCREEN`, `L4STEAMTRANSPORT`,
|
||
`btl4fe`, `btl4console`, `btl4lobby`, plus `#ifdef BT412` seams in `L4CTRL.cpp`
|
||
(PAD token), `L4GREND.cpp` (`L4PLASMA=SCREEN`), `L4VB16.cpp` (inert `PadRIO` stub),
|
||
`btl4main.cpp` (front-end/marshal/lobby blocks; zero-arg = 4.11 behavior). The
|
||
**NetTransport seam always compiles** (the wire for both flavors). `BT412_STEAM`
|
||
requires `BT412` (configure-time `FATAL_ERROR`, negative-tested). All three flavors
|
||
verified: OFF solo mission un-regressed (31 subsystems, gait, targeting); ON zero-arg
|
||
front end engages; STEAM links + ships `steam_api.dll`. Details:
|
||
[[build-and-run]] §Build flavors.
|
||
- `handoff/padrio/` (the interim BT411 transfer copy, commit `2e475f4`) was retired —
|
||
superseded by the merge itself (the real modules now live in BT411; a drifting
|
||
duplicate in the same tree would be a hazard).
|
||
|
||
## BT411 catch-up merge (2026-07-14)
|
||
|
||
Merged BT411's post-fork line (`4e72f0c..abed41e`, 91 commits) into BT412 via a
|
||
**local-path** merge — brought the whole **audio-fidelity system** (engine `AUD*` +
|
||
`L4AUD*` + `audiopresets.cpp` + ~600 content `.wav`s, `docs/AUDIO_FIDELITY.md`),
|
||
missiles/rear-fire/HUD/gyro/gait tasks (#66–68), `FOGDAY.EGG`, and refreshed context
|
||
docs. Only **5 files** overlapped the steamification; resolutions:
|
||
- `.gitignore`, `CMakeLists.txt`, `mech4.cpp` — trivial / auto-merged (the
|
||
`deviceOwnsInput` gating survived).
|
||
- `L4NET.CPP` — took BT411's task-#50 fix (don't close the game listener on console
|
||
loss) over the seam's adaptation of the old buggy close; the point-to-point send
|
||
stays on `NetTransport_Get()->Connect()`.
|
||
- `L4NETTRANSPORT.cpp` — folded BT411's **TCP_NODELAY** latency fix into
|
||
`WinsockNetTransport::Connect` (the seam already had BT411's retry-while-refused +
|
||
non-blocking). Accept-side game-socket NODELAY stayed at the L4NET call site.
|
||
- `mechmppr.cpp` — combined the `device_owns_input` gating with BT411's task-#68
|
||
look-behind ('V' rear-view), gating the `lookBehind` write too (a live RIO device
|
||
feeds it through its mapped button).
|
||
Verified after merge: clean build; solo front-end mode; loopback MP through the seam
|
||
(mesh completes, both tick, replication, no NODELAY warnings). [T2]
|
||
|
||
## Status ledger
|
||
|
||
- **Phase 0 bootstrap — DONE 2026-07-14.** Tree copied (working tree + full history,
|
||
`build/` excluded), origin re-pointed, fast-forwarded to `4e72f0c`, dev-state
|
||
`run/run.cmd` working-tree edit discarded (committed version is the documented solo
|
||
launcher), identity pass (README/CLAUDE.md/CMake `project(bt412)`), this topic +
|
||
roadmap authored.
|
||
- **Phase 1 (VS2022 v143) — DONE 2026-07-14.** Generator moved to
|
||
`Visual Studio 17 2022` (v143, Win32). One real change was forced: the v143 linker
|
||
fails the image on unresolved externals even under `/FORCE`, so the dead
|
||
offline-tool ladders in `game/reconstructed/mech3.cpp` are neutralized behind
|
||
`BT412_OFFLINE_TOOLS` (default off) and the exe now links `/FORCE:MULTIPLE`
|
||
(UNRESOLVED retired — real unresolved symbols are hard errors now). None of RP412's
|
||
other v143 source fixes (TIME.h, NETWORK.h, L4DINPUT, CAMMGR) were needed — BT's
|
||
tree was already v142-clean. Verified: clean build; solo DEV.EGG runs (gait/target/
|
||
31-subsystem ticks); two-instance loopback MP via btconsole.py — mesh forms
|
||
(console + 1502↔1602 game ports, "All connections completed!"), mission runs both
|
||
sides, each world ticks its master + the remote replicant. [T2]
|
||
- **Phase 2 (PadRIO input layer) — DONE 2026-07-14.** Ported from RP412:
|
||
`L4RIO.h` (RIOBase split; serial RIO re-parented), `L4CTRL.h` (`rioPointer` is
|
||
`RIOBase*`), `L4CTRL.cpp` PAD-token hook (→ `primaryControlType=PrimaryRIO`, so the
|
||
stock `MechRIOMapper` engages — confirmed), new `L4PADRIO.*` / `L4PADBINDINGS.*` /
|
||
`L4KEYLIGHT.*` (gates renamed `BT412KEYLIGHT`; KeyLight TU builds `/std:c++17
|
||
/permissive-` per-file). Default `bindings.txt` = the shared Tesla board layout
|
||
(numpad flight, letter rows = MFD banks, F-keys = Secondary columns, joystick head
|
||
0x40-0x47 on Space/arrows/pad). `content/bindings.txt` is gitignored (written on
|
||
first PAD run).
|
||
**BT-side changes PadRIO forced:** (1) both keyboard input bridges (mech4.cpp write
|
||
of mapper attrs; mechmppr.cpp `BT_KEY_BRIDGE`) now stand down when a RIO device
|
||
exists (`bridge_controls->rioPointer != 0`) — they clobbered the engine push every
|
||
frame; M mode-cycle / X recenter conveniences stay live. (2) **the mapper attribute
|
||
chain was off by one** — see [[reconstruction-gotchas]] §11 (short-parent-chain
|
||
positional trap): the `.CTL` stick mapping wrote `throttlePosition`. Fixed with a
|
||
pad slot + binary-locked enum. This was a latent REAL-POD bug (Phase 8 would have
|
||
hit it).
|
||
Verified live: `L4CONTROLS=PAD` → throttle lever ramps (rate axis, sticky), stick
|
||
deflects (turnDemand=1 + the authentic speed-vs-turn clamp: 61.5→22.0 u/s while
|
||
turning), mech drives across the map, XInput pad detected + 3 s re-probe, bindings
|
||
parse (59 key buttons/8 axes/12 pad buttons/5 pad axes). Keyboard fallback
|
||
regression-verified headless (`BT_FORCE_THROTTLE=1` walks). New diagnostics:
|
||
`BT_CTRLMAP_LOG=1` (streamed-mapping dump), `BT_STICK_LOG=1` (RIO stick push trace).
|
||
- **Phase 3a (PlasmaScreen, `L4PLASMA=SCREEN`) — DONE 2026-07-14.** `L4PLASMASCREEN.*`
|
||
copied verbatim; `L4GREND.cpp` selector diff applied (BT's only divergence there is a
|
||
comment at line 440 — no collision). Renders BT's 128×32 plasma into a desktop window.
|
||
Verified: a window titled "Plasma Display" opens and the game ticks normally beside it
|
||
(`L4GAUGE=640x480x16 L4PLASMA=SCREEN`). Note: the `L4GAUGE` gauge path binds a listen
|
||
socket at startup → a first-run Windows Firewall prompt (expected; unrelated to plasma).
|
||
- **Phase 3b (single-window MFD-split cockpit, `L4MFDSPLIT=1`) — DONE 2026-07-16**
|
||
(initially deferred 2026-07-14; the blockers fell). Landed across commits `0c964c0` →
|
||
`59c454b` + `2b238a8`: the 1920×1080 single-window cockpit arrangement (RP412 layout)
|
||
via the `L4VB16.cpp` hand-merge, on-screen clickable lamp-lit RIO button banks framing
|
||
the MFDs (4-above/4-below strips — BT-derived placement, not vRIO geometry, which has
|
||
no BT data), green MFD phosphor tint, button-lamp bitfield decode (subdued idle
|
||
baseline), `L4CONTROLS=PAD` as the cockpit default (before the DEV keyboard default),
|
||
the gauge NULL-source guard extended to the split path, and the backtick (`) toggle
|
||
for the secondary displays. Mouse presses inject into PadRIO as screen buttons
|
||
(`BTPadRIOScreenButton`, WndProc → `L4VB16.cpp`). [T2]
|
||
- **Phase 4 (NetTransport seam + Steam transport) — DONE 2026-07-14.** `L4NET.CPP`
|
||
taken from RP412 post-seam (all ~24 Winsock call sites now route through
|
||
`NetTransport_Get()`); BT's 3 `BT_NET_TRACE` blocks re-sited onto their code anchors
|
||
(the drop path, the point-to-point send before `NetTransport_Get()->Send`, the
|
||
pad-buffer receive) — they read message/packet metadata, not sockets, so no
|
||
collision. `L4NETTRANSPORT.*` (seam + `WinsockNetTransport` default) and
|
||
`L4STEAMTRANSPORT.*` (gate renamed `BT412_STEAM`, self-test env `BT412STEAMSELFTEST`)
|
||
copied. `extern/steamworks_sdk_164/` vendored (headers + win32 redistributable_bin).
|
||
One engine global ported from RP412's APPMGR: `gConsoleLossEndsMission` (default
|
||
False = arcade re-listen; the marshaled/lobby path sets it in Phase 5/6).
|
||
CMake: seam always compiled; `option(BT412_STEAM)` (default OFF) gates the transport
|
||
define + `sdk/public` include + `steam_api.lib` + post-build `steam_api.dll` copy.
|
||
`steam_appid.txt` gitignored (Spacewar 480 by hand until a real AppID).
|
||
Verified: (1) default TCP build — loopback MP through the seam is byte-for-byte the
|
||
old behavior (console connects, egg msgID-3 chunks delivered, "All connections
|
||
completed!", both instances tick, `net-tx`/`net-rx` traces fire through
|
||
`NetTransport_Get()`); (2) `BT412_STEAM=ON` config + build (compile-check of the
|
||
Steam transport TU against the vendored SDK; a live Steam session needs the Phase 6
|
||
lobby + 3 machines).
|
||
- **Phase 5 (front end) — DONE 2026-07-16 (5a–5d).** Interactive menu + local egg builder
|
||
+ in-process marshal + results + single-binary loop all landed and boot-verified.
|
||
Landed the local **mission-egg builder** — the core "single-player without the
|
||
operator console" capability:
|
||
- `game/reconstructed/btl4fe.{hpp,cpp}`: catalogs (8 maps, 8 mechs + variants,
|
||
colors), a `BTFeMission` config struct, and `BTFeMission_WriteEgg` that emits the
|
||
exact console egg format (verified against `content/MP.EGG`): `[mission]`,
|
||
`[ordinals]` + the 4 static rank-place plasma bitmaps, `[pilots]`, per-pilot
|
||
loadout sections, `[largebitmap]`/`[smallbitmap]` with **GDI-rendered** 128×32 /
|
||
64×16 pilot-name plasma bitmaps, and the role models.
|
||
- Two engine setters ported from RP412's L4APP.H (`SetEggNotationFileName`,
|
||
`SetNetworkCommonFlatAddress`) so the front end feeds the standard `-egg` path.
|
||
- `game/btl4main.cpp` WinMain: **front-end mode** — no `-egg` and no `-net` builds
|
||
`frontend.egg` locally and points the engine at it (`BTFrontEnd_Run`). `-egg`/`-net`
|
||
runs are untouched.
|
||
Verified: zero-argument launch → `[frontend] built frontend.egg` → mission loads and
|
||
runs (ticks, gait, targeting); the generated egg is structurally identical to MP.EGG
|
||
(32×32/16×16 name bitmaps with real glyph pixels, all sections present).
|
||
**Completed since (2026-07-16):**
|
||
- Interactive on-screen catalog **menu** (green-on-black GDI, `btl4fe.cpp`): map / mech /
|
||
color / time / weather / length groups + pilot-name edit, framed LAUNCH (and, under
|
||
Steam, HOST / JOIN) buttons. Zero-arg launch shows it; a chosen LAUNCH builds the egg.
|
||
- In-process **LocalConsole marshal** (`btl4console.{hpp,cpp}`): NOT a thread — it runs on
|
||
the engine's per-frame hook (`gPerFrameHook`, added to `engine/MUNGA/APPMGR.*`, called on
|
||
the game thread in `RunMissions`), so its `application->Dispatch(StopMissionMessage)` is
|
||
safe. Owns the mission clock and stops it at the chosen `length=`; snapshots
|
||
per-pilot kills/deaths at the stop (`BTResolveRosterPilot`/`BTPilotKills`/`BTPilotDeaths`).
|
||
- **Score intake + results screen**: BT's own kills/deaths model (no `gConsoleScoreSink` —
|
||
that is RP-layer; BT has no working mission-end wire flow, msgID 0x18 stays a stub). A
|
||
GDI "MISSION COMPLETE" scoreboard (`BTFrontEnd_ShowResults`) reads the marshal snapshot
|
||
(`BTLocalConsole_GetResult`/`GetResultName`).
|
||
- **Single-binary loop** = RELAUNCH per mission (`CreateProcessW` after the marshal stop),
|
||
NOT an in-process `for(;;)` — in-process re-init crashes on the stale reconstructed
|
||
`gBT*` globals (cdb-traced to `BTL4VideoRenderer::MakeEntityRenderables` →
|
||
`gBTTerrainEntity`). Verified: 3 distinct PIDs across the menu→mission→results→menu cycle.
|
||
- WinMain launch-mode branch (`BTFrontEnd_LastLaunchMode()`): 0 solo, 1 lobby host, 2
|
||
lobby member (see Phase 6).
|
||
- **Phase 6 (Steam lobby) — CODE LANDED 2026-07-16; live 3-machine test DEFERRED.**
|
||
`game/reconstructed/btl4lobby.{hpp,cpp}` (ported from RP412 `RPL4LOBBY`) builds both gates
|
||
— stubs without `BT412_STEAM`, full `ISteamMatchmaking` room under it (both configs
|
||
link clean). What works: the room screen; member data (`ip`/`cp`/`gp`/`nm`/`vh`/`cl`/`bd` =
|
||
FakeIP + fake console/game ports + persona + mech/color/badge); the nonced `go` launch
|
||
roster → `SteamNetTransport_RegisterPeer` for every peer; `Push`/`PullMissionResults` over
|
||
lobby data (`res` key) rebuilding the shared score sheet via `BTLocalConsole_ClearResults`/
|
||
`InjectResult`. The menu offers HOST/JOIN when `BTLobby_Available()` (Steam transport up,
|
||
installed by WinMain on `BT412STEAM` env). A host launch bakes every member into the egg's
|
||
`[pilots]` (mesh `FakeIP:1502` addresses, round-robin drop zones) via
|
||
`BTFrontEnd_SetHostedPilots`; a member enters as a network pod on `:1501`
|
||
(`SetNetworkCommonFlatAddress` + `gConsoleLossEndsMission=True`).
|
||
**Host→member wire egg-feed marshal — DONE (2026-07-17):**
|
||
`BTLocalConsole_InstallNetworkMission` (btl4console.cpp) makes the owner play the arcade console
|
||
in-process over the NetTransport seam (Winsock TCP or Steam SDR): connect to each member's
|
||
console channel, feed the chunked egg (`NetworkManager::ReceiveEggFileMessage`, \n→NUL wire image
|
||
like `tools/btconsole.py`) retry-until-ACK, poll state (`StateQueryMessage`), and when the whole
|
||
mesh is staged at `WaitingForLaunch` dispatch `RunMission` to all + locally at once; `StopMission`
|
||
at expiry. The owner's own pod is fed via `L4NetworkManager::FeedLocalEgg`. Scores are BT's
|
||
kills/deaths snapshotted from the (meshed) roster at the stop — NO EndMission wire intake (BT's
|
||
mission-end flow is a stub; the mesh already put every pilot in the host's roster).
|
||
- **Engine change (ported from RP412):** `gConsoleMarshalsLaunch` (APPMGR.h/.cpp) + the
|
||
`!gConsoleMarshalsLaunch &&` guard in APP.cpp's WaitingForLaunch self-launch — holds the owner
|
||
(which has no console connection to itself) at WaitingForLaunch so the in-process console
|
||
launches the mesh together instead of the owner self-launching early. Default False = stock
|
||
behavior; solo boot un-regressed.
|
||
- **WinMain host path** honors `BT412HOSTPODS` (+`BT412HOSTPORT`) for the lobby host AND a classic
|
||
LAN host: `SetNetworkCommonFlatAddress` + `InstallNetworkMission(secs, "frontend.egg", pods)`,
|
||
falling back to a solo marshal if no member is reachable.
|
||
- **Verified (loopback):** two `btl4.exe -net` pods fed by `tools/btconsole.py` reach
|
||
"All connections completed!" and run after the engine change — the exact protocol + launch
|
||
handshake the marshal uses. Both gates build+link; the Release dist boots and the Steam
|
||
transport comes up (FakeIP allocated).
|
||
- **Remaining:** the live multi-machine Steam mission (FakeIP mesh + pilot-slot matching across
|
||
machines) — untestable here (needs Steam + ≥2 accounts/machines). Procedure:
|
||
`docs/STEAM-3-MACHINE-TEST.md`. The lobby object does NOT survive the per-mission relaunch
|
||
(single-binary limitation — everyone returns to a fresh menu, not the room).
|
||
- **Phase 7 (packaging) — IN PROGRESS.** `pack-dist.ps1` landed (assembles a runnable
|
||
Steam test dist; wraps the zip in a single `BT412/` folder). KeyLight landed with
|
||
Phase 2 (`L4KEYLIGHT`, gate `BT412KEYLIGHT`). Remaining: release proper (real Steam
|
||
AppID, store assets, depot config) + the Phase 6 live 3-machine test.
|
||
- **Merge-back into BT411 — DONE 2026-07-17** (see the merge-back section above): one
|
||
repo, both lines, behind the `BT412` compile gate.
|
||
|
||
## The seams (what plugs in where) [T0 unless noted]
|
||
|
||
- **Input**: `LBE4ControlsManager` PUSH model; `L4CTRL.cpp` parses `L4CONTROLS` tokens;
|
||
RP412 adds token `PAD` → `new PadRIO()` (a `RIOBase` implementation from
|
||
XInput+keyboard), and the stock RIO mapper runs against it unchanged. BT's mapper
|
||
selection: `btl4app.cpp MakeViewpointEntity` switch on
|
||
`controls->primaryControlType` (+0xc98) → `MechRIOMapper` for PrimaryRIO(4).
|
||
- **Plasma**: BT's plasma is identical hardware to RP's (128×32, `L4PLASMA.h`);
|
||
RP412's `PlasmaScreen` renders the same `Video8BitBuffered` surface into a desktop
|
||
window, selected in `L4GREND.cpp` on `L4PLASMA=SCREEN`.
|
||
- **Displays**: BT pod = main 800×600 3D view + 640×480 radar + five mono MFDs on one
|
||
spanned 1280×480 surface (+ plasma). All cockpit surfaces are bit-plane masks over
|
||
one shared `SVGA16` pixelBuffer (see [[gauges-hud]], [[pod-hardware]]). RP412's
|
||
`MFDSplitView` (`L4MFDVIEW.*` + `L4VB16.cpp` split mode, `L4MFDSPLIT=1`) composes
|
||
child panes on a fixed 1920×1080 canvas; 3D presents into the viewscreen pane via
|
||
`Present(hDestWindowOverride)`.
|
||
- **Networking**: arcade stack unchanged (see [[multiplayer]]); RP412 moved the wire
|
||
behind `NetTransport` (`L4NETTRANSPORT.*`), default `WinsockNetTransport`, Steam
|
||
implementation `L4STEAMTRANSPORT.*` (`ISteamNetworkingSockets`, FakeIP + SDR,
|
||
degrade-to-TCP on any failure). Addresses stay SOCKADDR_IN-shaped so the egg
|
||
`[pilots] ip[:port]` roster works over both wires.
|
||
- **Session**: console protocol (egg msgID 3, 1040-byte chunks + ACK; RunMission
|
||
msgID 5 ×2; console must stay connected) — `tools/btconsole.py` is the working
|
||
feeder and the spec for the in-process LocalConsole marshal (Phase 5).
|
||
|
||
## Known merge risks (from the 3-way BT411 / RP411-baseline / RP412 comparison)
|
||
|
||
**Quantified 2026-07-14 [T1]** — BT-vs-RP411-baseline divergence measured with
|
||
`diff --strip-trailing-cr` (baseline extracted from RP412 history, `git show
|
||
3b8b729:MUNGA_L4/<f>`); RP412-side change sizes from `git diff 3b8b729..HEAD`:
|
||
|
||
| File | BT vs baseline | RP412 change | Treatment |
|
||
|------|----------------|--------------|-----------|
|
||
| `L4RIO.h` | identical | 125 lines (RIOBase split) | RP412 verbatim |
|
||
| `L4RIO.cpp` | identical | 0 | nothing to do |
|
||
| `L4CTRL.h`, `L4NET.H`, `L4PLASMA.*`, `L4KEYBD.h` | identical | small | RP412 verbatim |
|
||
| `L4CTRL.cpp` | 29 diff lines | 17 (PadRIO hook) | apply RP412 diff |
|
||
| `L4GREND.cpp` | 6 diff lines | 15 (PlasmaScreen selector) | apply RP412 diff |
|
||
| `L4VIDEO.cpp` | **2725** diff lines (BT render work) | only 14 | apply RP412 diff — small despite BT divergence |
|
||
| `L4VIDEO.h` | 29 diff lines | 7 | apply RP412 diff |
|
||
| `L4NET.CPP` | 23 diff lines (BT_NET_TRACE ×5) | 345 (seam refactor) | **MEDIUM** — apply seam refactor, re-site traces |
|
||
| `L4VB16.cpp` | **514** diff lines (dev-gauge dock) | 350 (split view) | **HIGH** — true hand-merge |
|
||
| `L4VB16.h` | 14 diff lines | 32 | hand-merge with L4VB16.cpp |
|
||
|
||
- **`L4VB16.cpp` — HIGH.** RP412 rebuilt ~3846–4046 (splitViews/canvas/present); BT
|
||
rebuilt the same window-management region for dev-gauge docking (`BT_DEV_GAUGES`,
|
||
`BT_DEV_GAUGES_WINDOW`, `BT_DEV_GAUGES_DOCK`, `BT_GAUGE_SCALE`, `BT_GAUGE_SEC_ROT`,
|
||
`BT_ALL` — 15 sites). Hand-merge; write the 3-way diff notes HERE before editing.
|
||
- **`L4NET.CPP` — MEDIUM.** RP412 rerouted all ~22–26 Winsock call sites through
|
||
`NetTransport_Get()`; BT's 5 `BT_NET_TRACE` diagnostic blocks sit exactly on those
|
||
send/receive sites and must be re-sited onto the seam calls.
|
||
- **CMake**: engine sources are explicit per-file lines (no globs) — every ported
|
||
`.cpp` needs its own `add_library` line or it silently doesn't compile. New deps:
|
||
`xinput9_1_0.lib` (PadRIO), C++/WinRT (KeyLight, per-file C++17), Steamworks SDK +
|
||
`steam_api.lib` behind `option(BT412_STEAM)`.
|
||
- **No `/Zp1` in BT's build** (RP's engine builds `/Zp1`): RP412's packing-mismatch
|
||
workarounds (`WINDOWS_IGNORE_PACKING_MISMATCH`, KeyLight default-packing carve-out,
|
||
`pack(push,8)` around Steam headers) are no-ops here — keep them for verbatim-ness,
|
||
but eyeball any copied code for /Zp1-layout assumptions.
|
||
|
||
## Key Relationships
|
||
- Uses: [[pod-hardware]] · [[multiplayer]] · [[gauges-hud]] · [[build-and-run]]
|
||
- Feeds: [[open-questions]] (steamification investigate items)
|