Per-Game Caps
The core’s mechanisms (registry walking, vtable interposition, stub
emission) are game-generic. Its numbers are not: singleton RVAs, hook
slots, registry heads differ per title — and per build. usems-cap is the
single table where those facts live.
The record
Section titled “The record”GameCap { game: Game, // Portal1 | Portal2 | HalfLife2 | HalfLife2Episodes game_folders: &["portal"], // -game values that identify the title engine_size: 7180288, // engine.dll image size — build fingerprint reg_heads: &[ // s_rgInterfaces head globals (regwalk) RegHeadSpec { module: "vstdlib.dll", rva: 0x8fbcc }, RegHeadSpec { module: "engine.dll", rva: 0x687e94 }, RegHeadSpec { module: "client.dll", rva: 0x555f40 }, RegHeadSpec { module: "server.dll", rva: 0x775e18 }, ], client: Some(ClientVtableSpec { version: "VClient017", // interface string to resolve singleton_rva: 0x4ab534, // where CreateFn's object lives gp_globals_rva: 0x4ab294, // CGlobalVarsBase* global frame_slot: 11, // HudUpdate vtable slot }), server: Some(ServerVtableSpec { version: "ServerGameDLL009", singleton_rva: 0x676e68, // CreateFn: mov eax, 0x10676e68; ret tick_slot: 5, // GameFrame (66/s cadence verified live) }),}Detection — refuse, don’t guess
Section titled “Detection — refuse, don’t guess”GameCap::detect(command_line, engine_size):
- Parse
-game <folder>from the process command line. - Match against
game_folders. No match →None(unknown title). - Fingerprint check:
engine_sizemust equal the caps’ recorded value. Mismatch →None, even though the folder matched — a patched or updated binary invalidates every RVA at once, so all game-specific features turn off rather than crash.
let cap = GameCap::detect(r#""...\hl2.exe" -game portal -steam"#, 7180288);assert_eq!(cap.unwrap().game, Game::Portal1);
GameCap::detect("-game portal", 12345) // wrong build → NoneGameCap::detect("-game garrysmod", ...) // unknown → NoneAt boot the core logs the verdict:
[USEMS] game detected: Portal1 (caps verified)-- or --[USEMS] game NOT recognized (or binary fingerprint mismatch); game-specific features disabledGraceful degradation
Section titled “Graceful degradation”Unsupported or unrecognized builds still get: interface probing by name, the mod loader, Luau sandboxing, commands and cvars. They lose: regwalk dumps, the frame hook, everything that needs an offset. The degradation is logged, never silent, never fatal.
Current cap status
Section titled “Current cap status”| Game | reg_heads |
client |
server |
Notes |
|---|---|---|---|---|
| Portal 1 | 4 heads, verified live | verified (slot 11) | verified (slot 5) | every value from shipped binaries |
| Half-Life 2 | empty | None |
None |
awaits RE pass |
| HL2 Episodes | empty | None |
None |
awaits RE pass |
| Portal 2 | empty | None |
None |
different branch (VClient018-era); full RE pass required |
Producing new caps
Section titled “Producing new caps”Every fact in a cap came from a tool in tools/, and every new game gets
the same treatment (see RE Toolkit):
1. tools/find_reghead2.py <dll>... → registry head RVAs2. walk the registry (regwalk) → interface names + CreateFn RVAs3. resolve the interface, disassemble CreateFn → singleton RVA4. usems_hook_profile client|server → candidate slots5. disassemble candidates → confirm GameFrame/HudUpdate6. write the GameCap entry + engine_size fingerprint7. inject, verify live, commit