Commit Graph
4 Commits
Author SHA1 Message Date
CydandClaude Fable 5 c66cb00a7e Network races: the local console marshals remote pods over the wire
The lobby-owner-as-console architecture, in-engine. RPL4CONSOLE gains
RPL4LocalConsole_InstallNetworkRace: the owner pod switches to network
mode and meshes like any pod (egg fed locally via FeedLocalEgg, which
now opens the ConsoleOnly state gate), while the console tick also
marshals REMOTE pods over NetTransport speaking the exact arcade
protocol - egg chunks with 5s-retry-until-ACK, 1Hz state polling,
RunMission once every pod stages at WaitingForLaunch, StopMission at
expiry (remotes first, local pod holds until their EndMission scores
land), score intake labeled with [pilots]-order names on the results
screen.

The front end builds the multi-pilot egg: RP412HOSTPODS lists member
console channels (lobby stand-in; the Steam lobby feeds the same
path), RP412HOSTPORT/RP412HOSTADDR set the owner side.

Winsock Connect now redials with a fresh socket per attempt (a refused
TCP socket is dead; the old loop reused it) bounded at 120s - needed
whenever a peer boots after the caller, which is the normal Steam
lobby launch order.

Verified on loopback: member pod in -net, owner hosting from its menu;
mesh completed both sides, 30s race, remote score collected over the
wire (host 3), local stop after the drain, results screen shows both
pilots by name in one process that returns to the menu.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 21:08:18 -05:00
CydandClaude Fable 5 8d7373974f Results screen between race and menu
After a console-marshaled race ends, the race loop now shows a RACE
RESULTS screen (place / pilot / final score, sorted descending, with a
CONTINUE button) before returning to the setup menu. Scores come from
the local console's intake; single-player rows carry the pilot's own
name, additional pods show their host number until the Steam roster
maps IDs to personas.

The setup menu also keeps the player's selections and pilot name across
races now instead of resetting to defaults each cycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 19:05:55 -05:00
CydandClaude Fable 5 9f79508257 LocalConsole: the in-process marshal that ends missions
Domain correction from playtest: hand-fed eggs are a developer shortcut
- a mission only ends on a console command, so the clock hits 00:00 and
counts up forever. Even single-player games need a console marshal.

RPL4CONSOLE is that console. Like the real one it lives on its own
thread: it owns the mission clock and raises the stop request at the
selected length; the app-manager per-frame hook (new gPerFrameHook seam
in APPMGR, called while the application global is live - the loop
condition NULLs it on exit, which ate the first attempt) executes the
engine-safe part, dispatching the same StopMissionMessage TeslaConsole
sent. Final scores flow in through a new RP-layer sink
(gConsoleScoreSink in RPCNSL): RPPlayer feeds it the same score it
sends a real console at mission end.

It also inherits the launcher role: the application tears down after a
stop (arcade pods were relaunched per mission by TeslaLauncher), so
WinMain respawns the process when the console ended the mission,
landing back on the race-setup screen. L4NetworkManager grows
FeedLocalEgg (the single-user egg-inject path, callable mid-session)
for the future in-process loop.

Verified end to end: menu -> 3:00 race -> stop dispatched exactly on
time -> final score collected (host 1 = 4113) -> process respawned with
the front end up. -egg runs stay unmarshaled (the dev shortcut).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 18:10:02 -05:00
CydandClaude Fable 5 58eb25a792 In-game front end: race setup menu builds the mission egg locally
Starting without -egg, -net, or -mr now boots a race-setup screen
(RP_L4/RPL4FE.cpp) instead of aborting: track / vehicle / color / badge
/ time-of-day / weather / race length plus pilot name, populated from
TeslaConsole''s RPConfig.xml catalog (Death Race scenario). LAUNCH
builds the egg exactly as the console did - the RPMission.ToEggString
port, including the pilot name pre-rendered to 1bpp plasma bitmaps
(128x32 + 64x16) via GDI with the console''s auto-shrink font logic and
the verbatim ordinal graphics - writes frontend.egg, and injects it
into the standard egg-load path (new L4Application::
SetEggNotationFileName).

The menu is a GDI child of the main window (pod green-on-black, double
buffered, mouse driven, EDIT control for the name) running a modal loop
before engine init; closing the window exits cleanly. Found and fixed
along the way: the empty egg CString holds a NULL representation
(operator! is the safe emptiness test), and the modal loop needed a
queue nudge for launch clicks delivered via SendMessage.

Verified end to end: boot -> menu -> LAUNCH -> generated egg (7.5KB) ->
racing in the 1080p cockpit with score and mission clock running.
start-windowed.bat now boots into the front end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 16:20:05 -05:00