Game updates¶
CAPIE works with the code of one exact game build. A Paradox patch can move or change that code, so CAPIE treats every unknown build as unsafe until a release says otherwise.
What happens after a patch today Works today¶
The pinned hoi4.exe hash no longer matches, CAPIE does not start, and the game runs without it.
Every patch does this, even one that changes nothing CAPIE uses. The planned launcher also
checks the hash first and starts the game without CAPIE, with a message that says why.
For players with a mod built on CAPIE, nothing breaks: states, cities and characters still rename through scripts, a custom country name shows as the original, and indicators say "CAPIE missing". The names come back when a CAPIE release supports the new build.
Opt-in verification on unknown builds Planned¶
Players asked for every feature to keep working after a patch that does not touch CAPIE's code, without waiting for a release. The decided answer is an option, off by default:
- With the option on and an unknown
hoi4.exehash, CAPIE scans the running game for every entry of its signature table: function patterns and the structure offsets it reads from code. - It switches on only if every pattern matches exactly once and every byte it would hook is identical to the tested build.
- If even one check fails, nothing is hooked. All features or none, never a subset.
- On an unverified build a small, discreet mark stays visible in the game.
The goal is still a release for every build, so that most players never need the option.
Signature table Planned¶
Today the addresses and patterns CAPIE checks are constants spread over several source files. The plan replaces them with one table per supported game build, generated offline, reviewed, signed with the release, and compiled into the DLL (so the launcher's hash of the DLL also covers the table). CAPIE never downloads it and never reads it from disk.
Proposed, subject to change
{
"schema": 1,
"game": { "sha256": "7DC947BE…A031D5", "version": "1.19.3.0", "steam_buildid": 25205862 },
"entries": [
{
"id": "loc.lookup_n",
"kind": "hook",
"module": "names",
"required": true,
"rva": "0x239EE20",
"pattern": "48 8B 05 ?? ?? ?? ?? 49 B8 25 23 22 84 E4 9C F2 CB",
"expect": "unique-in-text-at-rva"
},
{
"id": "view.dirty_offset",
"kind": "offset",
"derive": { "from": "view.mark_dirty", "instruction": "mov byte ptr [reg+disp8], 1", "operand": "disp" },
"value": "0x44"
}
]
}
Patterns cover whole instructions and mask only bytes that move when code is relinked. Every offset records how it was derived from an instruction, so it is re-derived for each new build, never copied from the previous one.
A new release for a new build Planned¶
- Notice the patch: a new Steam build id or a new
hoi4.exehash. -
Run the offline scanner on the new executable. It sorts each table entry into one of six classes:
Class Meaning Action EXACT Same bytes, same address Accept RELOCATED Same function body, new address, all anchors agree Accept after review DRIFTED Right function, but its body or a derived offset changed Human review, targeted reverse engineering, new tests AMBIGUOUS More than one candidate Short, targeted reverse engineering MISSING No candidate Reverse engineering; the module may ship disabled CONTRADICTED Anchors point at different functions Treated as missing; never pick one -
Build every binary and run the offline tests.
- Run a smoke test in the game of about 30 minutes: start with CAPIE, rename a country, leader and party, check Enter and the 32-character limit, save, load, restart, and start once without CAPIE.
- Update the main-menu snippet if Paradox changed the vanilla menu file.
- Scan locally with Windows Defender.
- Upload the final release files to VirusTotal, with the maintainer's consent each time, and link the results in the release notes.
- Sign the release manifest (file hashes and supported game hashes) with the offline key.
- Publish
versions.json, signed with the same key.
A module whose entries are not all resolved ships disabled in that release (for example: names on, caption refresh off), and the release notes say so.
versions.json Planned¶
The release manifest describes one release. versions.json answers a different question: which
CAPIE release do I need for my hoi4.exe? It lives in the repository, signed, and is attached to
each release.
Proposed, subject to change
{
"schema": 1,
"games": {
"7DC947BE…A031D5": { "version": "1.19.3.0", "min_capie": "1.0.0", "status": "supported" },
"<new sha>": { "version": "1.19.4.0", "min_capie": "1.0.1", "status": "supported" },
"<other sha>": { "version": "1.20.0.0", "status": "pending" }
},
"api_level": { "1.0.0": 1, "1.0.1": 1 }
}
install.ps1 -CheckUpdate would read it, compare it with your local hoi4.exe hash and the
installed version, and suggest -Update or report "pending". It stays on demand: no background
checks and no telemetry. Today -CheckUpdate reads only the latest GitHub release; reading
versions.json is a planned change.
What a patch costs¶
These are estimates, not measurements.
| Scenario | Effort |
|---|---|
| The patch does not touch hooked code, only addresses move | 2 to 4 hours, plus about 30 minutes for VirusTotal and signing |
| Some entries drifted (a structure field moved, a function was edited) | 1 to 3 days, mostly targeted reverse engineering and new tests |
| Paradox reworked the politics view, edit box or command system | 1 to 3 weeks; affected modules may ship disabled first |
| Only the main-menu snippet changed | 30 to 60 minutes |
Old game builds¶
To compare builds, the maintainer keeps a private copy of each new hoi4.exe from now on. Game
files are never redistributed: they stay out of every repository, CI artifact and release.
Tools that need Steam credentials are run only by the maintainer, by hand.