Fixes the synthetic car_select jump for cold sessions, makes the loadout
exit chain safe for real (non-synthetic) events, and adds a native->Kotlin
GameEvents bridge (onMapLoaded/onRaceStarted/onRaceEnded/onUpgradesAccepted/
onCarSelected) so both the UI layer and a future native RatNet client can
learn what the player picked - car id, accepted upgrades, and paint color
(name + RGBA) are all resolved live from the game's own engine state
rather than a static extracted table, so they stay correct for any car
added later. Includes a Jetpack Compose overlay as a worked example of a
UI-side GameEventListener consumer.
Full investigation history, root causes, and the several dead ends ruled
out along the way are documented in PROGRESS.md (cont. 30-63b).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Hooks MapTrack::HandleEvent to fabricate a RaceEvent+CashReward+fake
Actor and insert it via the engine's own AddEvent, making a synthetic
"LAN: <lobby>" card appear on an already-loaded street entirely at
runtime (no game_cache/OBB/native_lib changes). Also hooks the
per-frame MapScreen tick to neutralize a QA-only "Soak Test" feature
whose index-based scan of a parallel, unsynced list was the root
cause of a delayed crash on injected entries.
Verified live on Galaxy A9 (2018): zero crashes across all reachable
pins, and a 10-minute soak test with zero crashes after the Soak Test
fix, confirmed against a genuinely responsive post-test map screen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lets the track-substitution hook be enabled/disabled by flipping one
constexpr bool in main.cpp instead of commenting/uncommenting code, so
before/after comparisons don't need back-and-forth edits.