Four new optimizations, four measurement tools that were reporting wrong numbers, and six modules that had never done anything.
Thanks to @txtsd for four long sessions on request, including the first one anyone has ever sent in with the frame rate uncapped. Every number here comes from those logs.
New — all off by default, all in the Experimental tab
Enable All skips them. Tick them yourself if you want to test them.
Reuse Compiled Scripts · UI_Lua/LuaProtoCache
Interface scripts written inside XML templates are recompiled every time a frame is built from that template. Measured: 68% of every chunk the client compiled in a session was source it had already compiled. This keeps the compiled form and hands it back, so the parse does not run. The client still builds the function object, its environment and its addon ownership.
Field: 806 and 704 reuses across two sessions, each compared against a fresh compile, none differing.
UI Method Object Lookup · UI_Lua/LuaThisFast
Every call an addon makes into a frame — SetText, GetWidth, and 672 others — starts by fetching the frame object through four script-engine calls. This reads it directly. The addon-ownership propagation those calls perform is reproduced, not skipped: it decides what may touch protected actions.
Field: 86.6M, 63.4M and 31.4M lookups across three sessions. None handed back, none disagreeing.
Spread Model Animation · Graphics_Sound/AnimLod
Posing model skeletons is the largest single block of frame time: 3.68 ms of a 24.5 ms frame in a VoA raid, 114 models averaging 31 bones. Below 96 models on screen nothing changes. Above that each model's pose refreshes every 2nd–4th frame, never slower than a quarter of your frame rate. It cannot make animations run slow — the client derives animation time from a clock, not by counting frames. In a packed city you may notice steppier movement on some characters.
Collision Box Test (SSE2) · Graphics_Sound/CollisionOutcode
Line-of-sight checks, world clicks and projectile paths sort a collision model's corners against a box — six comparisons per corner on the x87 stack, 3.8% of main-thread time. This does four corners per instruction. Unlike the other maths replacements here it is exact, not approximate: the bounds are plain floats with no arithmetic applied. Before taking over it predicts what the game is about to produce and compares — 3000 matches required.
The measurement tools were wrong
The profiler divided by the wrong number. Sample counts came from the last million ring entries; the divisor was the whole session — 5.6× too small on a three-hour run. The top fifty entries summed to 12% of a profile, which no program can do. It produced a profile with no hot spot in it, and that reading was steering the work.
Corrected: AwesomeWotlkLib.dll 9.7%, model animation 7.0%, d3d9.dll 6.3%, this DLL's own modules ~6%, particle vertex fill 2.5%, UI batch draw 2.3%.
The animation counter claimed 72 ms of animation inside a 53 ms frame. It closed its frame on the hooked Sleep tick, which a CPU-bound client stops running.
The vsync detector called an uncapped session capped and told a tester to redo it.
Removed and cheapened
Six things that were never running: two event-name caches that logged themselves at startup and were never read, a CDataStore batch whose Install was called from nowhere, a frame-script throttle whose entry point nothing called, a sound guard that re-registered another module's hook, and a combat-text batch flushed every frame whose producer index nothing incremented. About 550 lines.
Nine counters on hot paths were atomic — six on the skip branch of the D3D9 state cache, the fast path the feature exists to reach. All plain now.
The DBC row cache moved 1360 bytes per hit to deliver 680, about 6.7 GB of spare memcpy in one session.
The quality governor could change settings the client only applies later, which queues a change the player never asked for and leaves the governor unable to measure what it did. It now reads each setting's flags and refuses those.
Install
Unzip all files together and run wow_optimize_launcher.exe. See the README for the proxy-load and standalone-loader options.
Do not use this on Warmane. Their anti-cheat flags performance injectors regardless of intent, and the result is a permanent ban.