This is a racing simulator HUD plugin for Piboso racing games (MX Bikes, GP Bikes, WRS, KRP). It’s a DLL plugin written in C++ using each game’s proprietary API, with a shared core that works across all supported games.
For deep technical details: See ARCHITECTURE.md (comprehensive documentation with mermaid diagrams, component descriptions, dependency graphs, multi-game architecture). This file is a quick-start guide.
Game Engine (MX Bikes / GP Bikes / WRS / KRP)
↓ (callbacks via plugin API)
mxb_api.cpp / gpb_api.cpp (per-game DLL exports)
↓ (converts to unified types via adapters)
PluginManager (receives unified types only)
↓
PluginData (singleton - caches all game state)
↓ (notifies on data changes)
HudManager (singleton - owns all HUD instances)
↓
Individual HUDs (IdealLap, Standings, Map, etc.)
↓ (build render primitives)
Game Engine (renders quads/strings)
Key Singletons:
PluginData - Central game state cache, change detectionHudManager - HUD lifecycle, owns all HUD instancesSettingsManager - Save/load HUD configurationsInputManager - Mouse and keyboard inputXInputReader - Controller state and rumble effectsRumbleProfileManager - Per-bike rumble profiles stored in JSONOdometerManager - Per-bike odometer/trip meter data stored in JSONFmxManager - FMX trick detection state machine, scoring, chain systemAssetManager - Dynamic discovery of fonts, textures, icons from subdirectoriesFontConfig - User-configurable font categories (Title, Normal, Strong, Marker, Small)ColorConfig - User-configurable color paletteThe plugin supports multiple Piboso games from a single codebase:
| Game | Config | Output | Status |
|---|---|---|---|
| MX Bikes | MXB-Release |
mxbmrp3.dlo |
✅ Full support |
| GP Bikes | GPB-Release |
mxbmrp3_gpb.dlo |
✅ Core features |
| WRS | - | wrsmrp3.dlo |
⏳ Stubbed |
| KRP | - | krpmrp3.dlo |
⏳ Stubbed |
Translation Layer:
game/unified_types.h - Game-agnostic data structures (Unified:: namespace)game/game_config.h - Compile-time game selection, feature macrosgame/adapters/*_adapter.h - Convert game structs → unified typesvendor/piboso/*_api.cpp - Per-game DLL exports⚠️ IMPORTANT - Build Environment:
⚠️ IMPORTANT - Shell Commands:
& instead of && for chaining commands (or provide separate commands)\ for paths, or forward slashes / (git accepts both)git fetch origin & git reset --hard origin/branch-nameBuild Instructions (Windows only):
mxbmrp3.sln in Visual Studio 2022 (C++17, v143 toolset)MXB-Debug / MXB-Release → build/MXB-Release/mxbmrp3.dloGPB-Debug / GPB-Release → build/GPB-Release/mxbmrp3_gpb.dlo.dlo to game’s plugins/ folderThe plugin must run efficiently at 240fps (4.17ms frame budget). Many competitive players use high refresh rate monitors. Avoid per-frame allocations, unnecessary string operations, and complex calculations in hot paths like Draw() and RunTelemetry().
new/delete)strncpy_s, snprintf)DEBUG_INFO_F() for logging (not printf)Singletons Everywhere Required by plugin API - we get one global entry point, everything branches from there.
Lambdas in settings_hud.cpp rebuildRenderData() Intentional - they capture local layout state. Alternatives were worse (passing 8+ parameters).
Public member variables on HUDs (e.g., m_enabledRows)
These are configuration data, not encapsulated state. SettingsHud needs direct access.
HUDs don’t cache raw game data
HUDs pull fresh from PluginData on rebuild - they only cache formatted render data (m_displayEntries, m_quads, m_strings).
This enforces PluginData as single source of truth and prevents synchronization issues.
Widget vs HUD Distinction Widgets (TimeWidget, PositionWidget, LapWidget, SpeedWidget, SpeedoWidget, TachoWidget, BarsWidget, LeanWidget, NoticesWidget, VersionWidget, SettingsButtonWidget) are simplified HUD components with:
Full HUDs (StandingsHud, LapLogHud, PitboardHud, TimingHud, etc.) have:
Handler-to-API Event Mapping Each handler corresponds to game API callback(s), but receives unified types:
No unit tests Requires game engine to run. Manual testing in-game is current workflow.
BaseHud (.h and .cpp files in mxbmrp3/hud/)mxbmrp3/mxbmrp3.vcxproj - Add <ClInclude> for .h and <ClCompile> for .cppmxbmrp3/mxbmrp3.vcxproj.filters - Add filter entries to place files in Header Files\hud and Source Files\hudrebuildRenderData() - builds vectors of quads/stringsHudManager constructor (add pointer, getter, initialize in initialize(), null in clear())SettingsHud for configurationSettingsManagerhud->isVisible()hud->isDataDirty() triggers rebuildrebuildRenderData()When implementing event handlers or debugging timing/lap data:
mxbmrp3/vendor/piboso/mxb_api.h, gpb_api.h, etc.Unified::* types, not raw game structsm_iLapNum=0 for first lap) but UI typically shows 1-based (display as “L1”)Unified:: struct in game/unified_types.hgame/adapters/*_adapter.h)game/game_config.h if game-specificCore:
mxbmrp3/core/plugin_manager.cpp - Plugin coordinator (receives unified types)mxbmrp3/core/plugin_data.h/.cpp - Game state cachemxbmrp3/core/hud_manager.h/.cpp - HUD ownershipmxbmrp3/core/asset_manager.h/.cpp - Dynamic asset discovery (with user override support)mxbmrp3/core/font_config.h/.cpp - Font category configurationmxbmrp3/core/color_config.h/.cpp - Color palette configurationmxbmrp3/core/update_checker.h/.cpp - GitHub update checkermxbmrp3/core/update_downloader.h/.cpp - Update download and installationmxbmrp3/core/tooltip_manager.h - UI tooltip management (header-only)mxbmrp3/core/xinput_reader.h/.cpp - Controller input and rumble effectsmxbmrp3/core/rumble_profile_manager.h/.cpp - Per-bike rumble profilesmxbmrp3/core/odometer_manager.h/.cpp - Per-bike odometer and trip meter trackingmxbmrp3/core/fmx_manager.h/.cpp - FMX trick detection and scoringmxbmrp3/core/fmx_types.h - FMX data structures (TrickType, TrickInstance, RotationTracker, etc.)Multi-Game Layer:
mxbmrp3/game/unified_types.h - Game-agnostic data structuresmxbmrp3/game/game_config.h - Compile-time game selectionmxbmrp3/game/adapters/mxbikes_adapter.h - MX Bikes type conversionmxbmrp3/game/adapters/gpbikes_adapter.h - GP Bikes type conversionmxbmrp3/vendor/piboso/mxb_api.cpp - MX Bikes DLL exportsmxbmrp3/vendor/piboso/gpb_api.cpp - GP Bikes DLL exportsHUD Base:
mxbmrp3/hud/base_hud.h/.cpp - Base class for all HUDsExample HUDs:
mxbmrp3/hud/ideal_lap_hud.cpp - Simple HUD (good starting point)mxbmrp3/hud/standings_hud.cpp - Complex HUD (dynamic table)mxbmrp3/hud/map_hud.cpp - Advanced (2D rendering, rotation)Settings:
mxbmrp3/hud/settings_hud.cpp - Main settings UI classmxbmrp3/hud/settings/settings_tab_*.cpp - Individual tab implementationsmxbmrp3/hud/settings/settings_layout.cpp - Layout helper contextmxbmrp3/core/settings_manager.cpp - Persistence layerAdd podium colors for P1/P2/P3 in standingsFix position cache not being marked dirty when standings updateRefactor SettingsHud click handlers to reduce complexityclaude/descriptive-name-sessionIDclaude/analyze-comments-correctness-01EqgeCF2tcaLHWDT9xpeK1Wclaude/ and end with matching session ID, otherwise push will fail with 403mxbmrp3/core/plugin_constants.hPLUGIN_VERSION constant when releasing