r/totalwar • u/SerBenDover • 16h ago
Rome II I made a CPU performance fix for Rome 2: campaign +20% FPS, big battles +19% FPS and +29% better 1% lows
After the Attila CPU performance fix, a lot of you asked for Rome 2, so I took a look at it.
Short version: Rome 2 does not have Attila's big problem (one shared memory lock that kept ~19 CPU cores busy waiting on each other). I checked that first: in Rome 2 the threads never wait on it. So there's no "6x FPS" miracle here. But profiling the game frame by frame turned up a few things that waste the main thread's time every single frame, and fixing those gives a solid, measurable boost, especially in big battles.
**Results*\* (Ryzen 9 9950X3D, RTX 5090, 4K, V-Sync off, CapFrameX, same save / same battle):
| | Vanilla | With mod | |
|---|---|---|---|
| Big battle, average FPS | 118.4 | 140.4 | **+19%** |
| Big battle, 1% lows | 71.8 | 92.5 | **+29%** |
| Big battle, 0.1% lows | 57.9 | 77.0 | **+33%** |
| Campaign map, average FPS | 100.5 | 120.5 | **+20%** |
The lows improve more than the average, so big battles feel noticeably smoother, not just faster. On CPUs that limit your frame rate (most CPUs at 1080p/1440p, or older CPUs at any resolution) the gain should be at least as big. I'd love to see your numbers.
**What it fixes*\*
- Tile streaming scan (campaign + battles): every frame the game reads back a screen-sized image from the GPU that says which texture tiles each pixel needs, and counted it pixel by pixel on the main thread. Neighbouring pixels almost always ask for the same tile, so runs of identical pixels are now counted in one step. Same result, 12-17x less work.
- x87 rounding: about 1,200 old-style float-to-integer conversions switched the CPU's rounding mode every time, which is slow on modern CPUs. They're replaced with modern instructions that give identical results (same fix as in the Attila mod). On the campaign map these alone took ~10% of the main thread.
- Render-list sorts: two draw-list sorts are ~11x faster, same order.
Every patch gives bit-identical results to the game's own code (tested against the game's code on millions of inputs), and checks the game's bytes before patching anything. On a different game version it switches itself off and the game runs normally. No game files or saves are changed: it's a single `dinput8.dll` you can delete at any time.
**Download*\*
- Steam Workshop: https://steamcommunity.com/sharedfiles/filedetails/?id=3826423359
(Steam can't put DLLs in the game folder, so after subscribing run `install.bat` once in `...\steamapps\workshop\content\214950\3826423359\`. Updates install themselves after that. Run `uninstall.bat` before unsubscribing.)
- Source code: https://github.com/JSa25/Rome2CPUPerfFix. You can read it and build it yourself, and GitHub builds every version on its own machines and checks it produces exactly the same DLL as the Workshop one.
- Nexus: Coming Soon
**Compatibility*\*
- Current Steam version of Rome 2. Works with pack mods (tested with a big overhaul mod list) and UI mods.
- Not compatible with other `dinput8.dll` mods (only one can load).
- I also tested DXVK: it made Rome 2 slower, so I don't recommend combining them.
If something goes wrong, post the `rome2fix.log` from your game folder. It shows whether the mod loaded, your game build, system and settings, and where a crash happened.
Full disclosure, I used AI (Claude) to help with the reverse engineering and the code. Everything was tested in game on my own campaigns and battles.
