Lore
CBZ Client Mod — Technical
CBZ's technical implementation — winmm.dll proxy, build toolchain, Zeal char-select backdrop port plan, and the MinGW-w64 cross-compile path.
This page is the technical companion to CBZ — The Last Camp Zeal. The user-facing overview (what CBZ does, what it doesn't, status) lives there. Here we cover the internals: the winmm.dll proxy mechanism, the build toolchain decision, the planned Zeal char-select backdrop port, and the engineering shape of future phases.
At a glance
| Field | Value |
|---|---|
| Mechanism | DLL hijack via winmm.dll proxy in the eqgame.exe folder |
| Language | C / C++ (Windows DLL) |
| Source upstream | solar984/eqclientmod-rof2 (Unlicense) |
| Build toolchain (current leaning) | MinGW-w64 cross-compile from macOS |
| Struct library | macroquest/eqlib (GPL-2.0, vendored) |
| Phase 0 build | Functional parity with SOLAR_ROF2_20250829 |
The winmm.dll proxy mechanism
CBZ ships as winmm.dll placed alongside eqgame.exe. Windows (and Wine) resolve DLL imports by checking the executable's directory before walking the system path. By dropping a custom winmm.dll next to eqgame.exe, CBZ gets loaded into the EverQuest process at startup — before any game code runs.
The proxy itself forwards all real winmm calls to the system DLL, so the game's actual multimedia API calls (timers, sounds, etc.) work normally. CBZ's hook code runs in addition — patching specific game functions, reading game state through eqlib's struct offsets, and exposing the /cbz chat command.
This is the same mechanism Zeal uses on TAKP. CBZ inherits the framework wholesale from solar984's RoF2 fork.
Wine DLL override gotcha
Wine ignores local DLL drops by default — even when the file is right next to eqgame.exe. The fix is WINEDLLOVERRIDES with winmm=n,b to load CBZ's shim:
WINEDLLOVERRIDES="winmm=n,b" wine eqgame.exe patchme
This is baked into The Last Camp Launcher's bottle config so Mac players don't have to think about it. For raw Wine setups, this env var is required.
Build toolchain — MinGW-w64 leaning
CBZ is a Windows DLL. The build toolchain question is how to produce a Windows DLL from a Mac development environment without spinning up a Windows VM. Options on the table:
| Toolchain | Pros | Cons |
|---|---|---|
| MinGW-w64 (cross-compile) | Native macOS build, no VM, well-tested for Windows DLLs | Requires careful CMake / Makefile setup |
| Visual Studio in Parallels | Most "official" toolchain | Requires Windows VM, slow iteration cycle |
| MSVC via CMake + Wine | In-place toolchain | Brittle, awkward debug story |
| Existing Phase 0 inherited build | Already works | Tied to upstream solar984 build env |
The current lean is MinGW-w64. It produces clean Windows DLLs from a macOS dev box, integrates with VS Code or any local editor, and avoids the Parallels tax. The decision is parked until CBZ work resumes from its Phase 0 banked state.
Vendored struct library — eqlib
macroquest/eqlib (GPL-2.0) is vendored as a Git submodule. It provides RoF2 struct offsets — the memory layouts of EQ's internal data structures (player, target, group, etc.) — that CBZ needs to read game state without reverse-engineering each offset by hand.
The license matters: GPL-2.0 vendored as a submodule keeps eqlib's terms intact while letting CBZ use it. CBZ itself is MIT licensed, with the upstream license preserved on any file inherited or derived from a different-licensed upstream.
Planned: Zeal char-select backdrop port
The dormant explore mode in RoF2's char-select screen was confirmed working (2026-05-09 research). The integration plan:
- Single hook on
StartWorldDisplay— flips the renderer into the dormant explore-mode path. - Backdrop-only, no interactive camera (Phase 1) — just the cinematic background a player sees while picking a character.
- Zeal Titanium reference — Zeal already does this on Titanium. RoF2 has the same dormant code path with different addresses; the port is a known-shape job.
This becomes a CBZ "polish" phase once the build toolchain is settled and a Phase 1 module set is live. It is one of the most visually noticeable QoL adds — char-select goes from a static image to a slowly-panning vista.
Future module plan
Each future module is a separate, toggleable cbz.ini entry. The shape of the work:
- Integrated map — read player position from the character struct, overlay on the existing map UI. Requires eqlib offsets for player-position; well-known shape.
- Nameplate enhancements — hook the nameplate render path, swap colors based on class field. Requires class-id offset, name color register.
- Raidbars — read group/raid roster, hook a UI render pass. Heavier work — touches multiple game subsystems.
- Autofire / lootall — chat command bindings that emit existing game events. The simplest of the future modules.
All planned modules stay within the QoL guard rails enumerated on CBZ — The Last Camp Zeal. Nothing that automates play.
Phase 0 build inheritance
Phase 0 is a near-direct fork of solar984/eqclientmod-rof2 build SOLAR_ROF2_20250829. The behavior is identical to that build — same modules, same config, same winmm.dll shape — rebranded as CBZ for clear attribution and to give The Last Camp a maintained downstream when solar984's upstream eventually goes quiet (or goes a direction CBZ doesn't want to follow).
Resume status
CBZ is banked. Phase 0 shipped 2026-04-22 and the next work cycle was paused pending the toolchain pick (above). Resume is gated on either:
- A clean MinGW-w64 setup with a working CMake build that produces a
winmm.dllbyte-equivalent to the Phase 0 inherited build, or - A decision to keep using the upstream-inherited build env for a while longer and start Phase 1 modules on top of it.
When CBZ work resumes, the first deliverable is likely the integrated map module — the most-asked-for QoL feature for any RoF2 client.
Related
- CBZ — The Last Camp Zeal — player-facing overview
- Getting Started — Install the Client
- Server History
- Cogsworth — sibling Discord project