Warcraft eXtension Layer
Mod the 3.3.5a
client, cleanly.
Loads into the running World of Warcraft client and gives mods a typed way to talk to the engine - the same idea as SKSE or RED4ext.
Free, and always will be. Open source under GPLv3.
class MyModule final : public wxl::events::EventScript {
public:
MyModule() {
on<&MyModule::OnEndScene>(wxl::events::Event::OnEndScene);
}
void OnEndScene(const wxl::events::EndSceneArgs& a) {
// draw, read the world, edit it...
}
};
// file-scope instance self-registers at load
MyModule g_myModule;
A small core,
plus your modules
WarcraftXL.dll boots inside the client, brings up the hook engine, and raises events.
A module subscribes to those events and uses the core's typed bindings to read and drive the game.
Needed everywhere and always the same? It belongs in the core. A feature - a decision, an effect, an editor - is a module. Small reusable core, free modules.
Four pillars
So a module never touches a raw address itself.
Offsets
Curated client addresses and struct layouts. Internal - modules never touch these directly.
Bindings
Typed, zero-overhead calls into engine functions, with an enumerable catalog of signatures.
Events
A lightweight event bus. Subclass EventScript and bind methods to engine events.
Assets
In-memory contracts for the client's file formats - structured data, not byte soup.
Bind, then react
Subscribe to engine events in the constructor, react in the handlers. A file-scope instance self-registers when the DLL loads.
Drop it in, rebuild, and it is live - no separate injector, no patched data files.
class MyModule final : public wxl::events::EventScript {
public:
MyModule() {
on<&MyModule::OnEndScene>(wxl::events::Event::OnEndScene);
}
void OnEndScene(const wxl::events::EndSceneArgs& a) {
// draw, read the world, edit it...
}
};
// file-scope instance self-registers at load
MyModule g_myModule;
Example modules
Proof and starting points both. If an in-client map editor is the "hello world", imagine the rest.