Releases: Frostn1/frostmod
Release list
v0.12.1-beta.1 — isolate the GP Bikes reload crash
Diagnostic build. Not for general use. This is a pre-release, so frostmod.exe --update and the MXB App will both ignore it — everyone stays on v0.12.0 unless they download this by hand.
What it's for
The v0.12.0 logs pinned GP Bikes' reload crash to step 1 — tracks — three times out of three, with no step 2 ever reached. That tells us which loader dies, but not why. Two explanations are still standing:
- That one loader is unsafe to re-run.
- Replaying any loader from where we replay it is unsafe.
This build separates them with one flag.
How to run it
frostmod.exe --game gpb --unsafe-reload-from=2
That skips the tracks step and starts at step 2. Then reload mods in game, as before.
- If it completes — you'll see
[reload] done - steps 2..13 completed— the tracks loader alone is the problem, and the fix is targeted. - If it dies at step 2 the same way, the problem is where we replay from, not what we replay.
Either result is decisive. Send frostmod.log from next to frostmod.exe.
--unsafe-reload-from implies --unsafe-reload, so you don't need both. Plain --unsafe-reload still runs the whole table exactly as it did.
Also in this build
The reload's thread-id line no longer presents the two thread ids as an open question. Your logs answered it: the boot scan and the reload run on the same thread in every session, so the race we suspected isn't happening. That theory is retired, and the notes now record what replaced it.
Nothing else changed. MX Bikes is untouched.
v0.12.0 — Proximity voice, and GP Bikes' reload stands down
MX Bikes: proximity voice, and the radar finally points where riders actually are.
GP Bikes: mod reload is switched off — it was crashing your game.
GP Bikes: reload is off, deliberately
v0.11.0 gave GP Bikes its own reload offsets instead of MX Bikes'. Those crash the game too — just less often. A reporter's log shows the reload starting and the process simply gone: one session died on its first reload, another on its fourth after three that completed cleanly in about two seconds each.
Those offsets were derived by reading the game binary and have never been confirmed against a running game. So GP Bikes now refuses the reload and says so honestly, rather than gambling your session on it. Nothing else on GP Bikes changes.
MX Bikes is untouched. Its reload table is confirmed and works exactly as before.
Want it fixed? This is how
If you're willing to lose one GP Bikes session to pin this down:
frostmod.exe --game gpb --unsafe-reload
That arms the reload anyway. Every step is now written to frostmod.log before it runs, so when the game goes down, the last [reload] step … line names the exact loader that did it — turning 13 suspects into one. The log also records which thread the game loads content on versus which one we replay from; if those differ, that alone explains why some reloads survive and some don't.
Send that log in and GP Bikes gets its reload back properly.
Don't run it otherwise — it is expected to crash.
Proximity voice, via Mumble
Riders on the same server now hear each other from where they actually are on the track. FrostMod publishes your position through Mumble's Link interface; Mumble does the voice, we only say where you are.
On by default, toggled with 6 in the F8 menu, and remembered in frostmod_radar.cfg. Setup is in docs/MUMBLE.md.
The direction you're facing comes from the radar rather than a guess, and the two are checked against each other every 30° of heading — if the radar points at someone, Mumble hears them in the same direction by construction. You're grouped only with riders on your own server and track, identified by your install's GUID, and the grouping clears the moment you leave a session.
Fixed
- The radar pointed riders in arbitrary directions. Yaw is measured in degrees and was being fed straight to functions expecting radians, multiplying every heading by 57.3. A rider held dead ahead of you would swing from +86° to −139° over four degrees of real steering, so blips spun as you rode. This has been wrong since the radar shipped in v0.9.7 — it is right now, and the conventions are confirmed against PiBoSo's own SDK header.
- A short element stride no longer reads off the end of the rider arrays. Where the game reported a smaller element size than we expected, each rider's data was partly read out of the next one, and the last read past the end of the array entirely.
Under the hood
Every reload step is logged before it runs on both titles, not just GP Bikes — each step is crash-guarded, so an ordinary fault is swallowed and the reload completes, and what actually kills a process leaves nothing behind. The log is now the only witness, so it writes through per line.
A title's reload table also carries whether it has ever been confirmed on that title. A table that compiles and has never run is the dangerous case, not the safe one — it looks like a working feature until it isn't. Both GP Bikes crashes shipped exactly that way.
MXB App users: the app updates you to this automatically.
v0.11.0 — GP Bikes reload actually reloads GP Bikes
If you use FrostMod with GP Bikes, update. v0.10.0 could crash the game the first time you reloaded mods.
The fix
v0.10.0 attached to gpbikes.exe correctly — and then reloaded using MX Bikes' internals. Those addresses mean something entirely different inside GP Bikes, so the reload called arbitrary code and overwrote arbitrary memory, and the game went down moments later with nothing useful in the log.
GP Bikes now has its own reload offsets, covering tracks, tyres, rider, bikes, paints, helmets, riders, animations, stands and dashes. Drop a .pkz in and press R — as it was always meant to work.
MX Bikes is unchanged. Its offsets are byte-for-byte what they were; there is a test that fails if they ever drift.
Also fixed
- FrostMod reads the mods folder of the game it's attached to. The default was MX Bikes' folder no matter which game you pointed it at, so on GP Bikes the track manager, the inactive-tracks store and the model swap all worked against the wrong folders.
frostmod.exenow prints which title it's driving, so a mismatch is obvious. - Diagnostics that only make sense on MX Bikes stay off elsewhere. The
registryResetcapture was installing a hook at an MX Bikes address inside GP Bikes;--bikecapand--dump-serverlistwere reading MX Bikes' memory there.
Under the hood
The reload step table now lives per title and is reached through whichever game FrostMod is attached to, so one title can no longer run another's. A title with no offsets derived refuses the reload and says so, instead of trying it with someone else's addresses — which is what turned a missing port into a crash.
Known
GP Bikes' reload offsets were derived by static analysis of the game binary and confirmed against a crash report, but GP Bikes support is still young. If a reload misbehaves there, send frostmod.log (it sits next to frostmod.exe) — it records exactly which offsets resolved.
MXB App users: the app requires this version before it will run FrostMod on GP Bikes, and will update you automatically.
v0.10.0 — GP Bikes attach + reload
FrostMod now attaches to GP Bikes as well as MX Bikes, and live-reloads its mods.
GP Bikes
Run frostmod.exe --game gpb (or --process gpbikes.exe). Drop a .pkz into
Documents\PiBoSo\GP Bikes\mods\tracks, press R in the console, and it shows up in-game
without restarting — the same as MX Bikes has always worked.
Injected into the game, the DLL works out which title it is inside from the host process, so
there is nothing to configure.
Under the hood
The two constants live reload needs were recovered from an unpacked gpbikes.exe: the boot
content-load routine (0xfb650) and the VFS directory walker (0x18f150). MX Bikes'
values are unchanged.
GP's scanner prologue turned out to be byte-for-byte identical to MX Bikes' — same 0x7f8
frame — so the signature-with-delta fallback that keeps FrostMod working across a game update
covers either title unchanged.
Changed
- Features whose offsets are MX-Bikes-only now stay off on other titles instead of firing
at addresses that mean nothing there. The server-browser filter is the one that matters: its
hook writes a jump at an address that is unrelated code on GP Bikes. The log says why. --updaterefuses to run while either game is open, not just MX Bikes — the DLL is locked
by whichever one loaded it.
Still MX Bikes only
Server-browser filter, master protocol, and direct connect. GP Bikes also has its own master
server and default port, so MX's don't carry over.
Known limits
The GP Bikes offsets were derived by static analysis and confirmed by two independent methods,
but have not been verified under a debugger. If reload misbehaves on GP Bikes, the console log
names the RVA it resolved — that's the thing to report. See tasks/gp-bikes-port.md.
v0.10.0-rc1 — GP Bikes attach + reload (test)
FrostMod now attaches to GP Bikes and reloads its mods, alongside MX Bikes.
Run frostmod.exe --game gpb (or --process gpbikes.exe). Drop a .pkz into
Documents\PiBoSo\GP Bikes\mods\tracks, press R, and it should appear in-game without a
restart — the same as MX Bikes.
Why this is a pre-release
The GP Bikes offsets were recovered by static analysis of an unpacked gpbikes.exe and
have not been confirmed under a debugger, and MX Bikes has not been regression-tested
against the refactor. The Windows build passes CI, so it compiles and links — but nothing
here has been run.
frostmod.exe's update check reads releases/latest, which excludes pre-releases, so
nobody on v0.9.11 is offered this. Download it deliberately, or don't.
Two things to check before this is promoted to a full release:
- Confirm
RVA_CONTENT_INIT(0xfb650) andRVA_SCAN_FOLDER(0x18f150) under x64dbg. - Regression-test MX Bikes — the refactor touched its path too. GP Bikes gaining a
broken feature is an inconvenience; MX Bikes losing a working one is not.
What's in it
- Per-title offsets table; MX Bikes' values are unchanged.
- GP's scanner prologue is byte-for-byte identical to MX's, so the signature-with-delta
fallback that survives a game update works for either title unchanged. - Features whose offsets are MX-Bikes-only now stay off on other titles instead of
firing at addresses that mean nothing there. The server-browser filter is the one that
matters — its hook writes a jump at an address that is unrelated code on GP Bikes. --updaterefuses to run while either game is open, not just MX Bikes.
Full derivation and what remains: tasks/gp-bikes-port.md. Server-browser filter, master
protocol and direct connect are still MX Bikes only.
v0.9.11 — the model-swap crash is gone
Update to this build if you use MXB App's model swaps. v0.9.9 could crash MX Bikes to desktop, and the crash landed later than the thing that caused it.
Fixed
The game no longer crashes to desktop after a model swap. v0.9.9's instant model refresh replayed the game's bike-apply call using the arguments of an earlier call, so a swapped model would appear without the class-switch away-and-back. It crashed the game — but not at the swap. The crash landed on the next bike you selected by hand, which is why it read as "picking a bike crashes MX Bikes" rather than as anything to do with swapping a model.
The replay is removed. It couldn't be made safe by checking harder:
- The descriptor is a caller temporary FrostMod doesn't own. The liveness test — is the captured bike name still in its bytes — passes for a stack frame that has returned but not yet been overwritten, which is exactly the case it existed to catch.
- The object the call writes its result into was never checked at all.
- The content reload rebuilds the very arrays the loader indexes, so after a swap the capture describes a world that no longer exists — and the replay waited for that reload to finish, then went ahead regardless.
- The exception guard around the call made it worse: a fault inside a half-finished machine swap was swallowed and the game carried on with the wreckage, turning an immediate crash into a delayed one.
Both swap paths — the F8 model swap and MXB App's command channel — now say "model swapped — re-select the bike to see it" and leave the running game alone. Re-selecting the bike in the garage loads the new model.
Changed
The bike-apply hook is opt-in again (frostmod_bikecap.flag), as it was before v0.9.9. Shipping it to everyone put a detour — and its speculative scan of the descriptor — in the path of every bike selection in every player's game, purely to feed a refresh that no longer exists.
Why the version skips 0.9.10
A v0.9.10-rc1 pre-release was published from a different branch that still contains the replay, and its version file also reads 0.9.10. MXB App decides whether it's safe to ask for a live model refresh by comparing the recorded version numerically, so a 0.9.10 floor would have read that pre-release as new enough and asked it for the very thing that crashes it. Taking the next number excludes it cleanly. If you are on v0.9.10-rc1, update — it still has the crash.
Pairing with MXB App
MXB App v0.7.1 and up withhold the live-refresh request from any FrostMod below v0.9.11, so the app protects its own swaps even before you update. This release is what also covers FrostMod's own F8 swap, which the app can't reach.
Still open
Making a swapped model appear without the re-select needs the descriptor's layout pinned down first, so the apply can be driven from one FrostMod builds rather than one it borrowed. Until then, the re-select is the step.
v0.9.10-rc1 — UI-free build (test)
Test build of the UI-free FrostMod. Pre-release, so frostmod.exe --update will not pick it up — existing installs are unaffected.
Download Release.zip, unzip, run frostmod.exe.
What changed
FrostMod now draws exactly one thing in game: a small pill in the top-left corner reading FrostMod v0.9.10 - attached. That is the whole in-game UI.
Gone: the F8 menu and every panel it opened (track manager, track switcher, bike model swap, direct connect, server maps), the radar disc and rider outlines, the reload progress bar and the status line.
FrostMod no longer reads the keyboard at all while the game runs — no F8, digits, arrows, Enter/Esc or PageUp/PageDown — so it cannot shadow a game binding or collide with another HUD plugin.
Reload still works. Press R in the frostmod.exe console, or signal Local\FrostModReload (the MXB App does this after it installs something). Progress goes to frostmod.log instead of an on-screen bar.
Nothing was deleted: every feature behind those panels is still compiled in, gated on one switch (FROSTMOD_UI at the top of src/frostmod.cpp). Set it to 1 and rebuild to get the old UI back verbatim.
Worth checking
- Badge shows in menus (GL render path).
- Badge shows on track (the sanctioned plugin
Draw()path — different renderer, so it is the one that could land wrong). Rin the console still reloads, with progress in the log.- F8 does nothing.
Built green on Windows CI; not yet run in the game.
v0.9.9 — swap a bike's model and see it instantly
Swap a model, see it straight away
Until now, changing a bike's model left the garage showing the old bike. The reload rebuilt FrostMod's content lists but not the preview you were looking at, so the only way to actually see your new model was to switch bike class away and back — an unmarked step nobody would guess.
That's fixed. Swap a model — from the F8 menu or from MXB App — and if it's the bike you currently have selected, it changes right there.
It only ever touches the bike you have selected. Swapping a model on some other bike won't disturb what's on screen.
Also new: MXB App can talk to FrostMod properly
MXB App has been able to ask FrostMod to do things for a while, but the message channel only existed on the app's side — FrostMod was never listening, so those requests went nowhere. It listens now. That's what lets a model swap in MXB App refresh your garage without you touching the game.
Groundwork for the in-garage bike switcher (swap your whole bike mid-session, offline) also landed here, though the switcher itself isn't wired up yet.
Worth knowing
To refresh your bike, FrostMod watches how the game loads bikes and replays that same load. That watch used to be an opt-in diagnostic; it's now on for everyone, because it's what the refresh is built from. It only reads — nothing is replayed unless you swap a model, and then only for your selected bike.
If a refresh can't be done safely, FrostMod leaves the game alone and tells you to re-select the bike — you'll never be left with a broken-looking garage. Details land in frostmod.log as [bikefresh] lines if something looks off.
This is the first build with the refresh in it and it hasn't been through a wide test yet. If a model swap doesn't show up, re-selecting the bike in the garage still works exactly as before. Reports welcome.
Install
Download Release.zip below, unzip, run frostmod.exe. Already running FrostMod? frostmod.exe --update pulls this build.
The .dll / .dlo / .exe files are also attached individually — the updater fetches those by name, so you don't need to grab them yourself.
Full changelog: https://github.com/Frostn1/frostmod/blob/main/CHANGELOG.md
v0.9.8 — plugin Draw() dispatch watch (diagnostic)
Diagnostic build to investigate a report that a co-existing HUD plugin (MXBMRP3) stops rendering after an in-game F8 → 1 Reload mods, while FrostMod's own HUD stays up.
What it does (log-only, no behaviour change): on each F8 reload, FrostMod logs for 20s — once a second — the presented frames/s vs the number of times the game called the plugin Draw() callback ([drawdiag] lines in frostmod.log).
How to read it: if after the reload frames/s stays high but Draw()/s drops to 0 (plugin Draw dispatch DEAD), the game stopped dispatching Draw() to plugins — which is why MXBMRP3 goes dark while FrostMod survives via its GL fallback. That confirms the cause so the real fix can be built.
Self-silencing, touches no game state; will be removed once the underlying reload fix lands.
v0.9.6 — .edf model-open capture (diagnostic)
Patch release. Ships an opt-in, read-only diagnostic to reverse-engineer the garage bike-preview reload path (so a model swap can auto-refresh the preview instead of needing a manual bike-class switch away-and-back).
No behaviour change for normal users — the capture is off unless you arm it.
Arming the capture (testers)
- Drop an empty file
frostmod_edfcap.flagnext tofrostmod.log(the DLL folder), before launching. - In the garage: (A) swap a bike's model, then re-select the same bike with no class change; (B) switch bike class away then back.
- Send back
frostmod.log— the[edf]lines log every model.edfthe game opens with its call stack.
See CHANGELOG.md for details.