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>
WinMain now wraps the engine block in a loop: when a front-end-launched
mission ends under the local console, the setup screen comes back in the
same process instead of exiting (the arcade relaunch-per-mission model).
Replaces the CreateProcess self-respawn - required for Steam, where the
lobby and sockets must survive across races.
Second-cycle re-init crash fixed: d3d_OBJECT kept a static texture cache
keyed by filename, so race 2 got IDirect3DTexture9 pointers created on
race 1 destroyed device and died at first draw (DrawMesh AV). The cache
is now flushed in ~DPLRenderer before the device is released, and
ParticleEngine::Initialize drops particles left over from the previous
mission. Verified: three consecutive 30s races in one PID, each stopped
on time by the console with final scores collected.
Also: L4CONSOLELEN env override for test-length races, and the console
exposes MissionCompleted() for the loop.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>