A modding framework for Eets (the Klei puzzle game).
Mods are native plugins (.dll on Windows, .so on Linux), injected by a small
loader, packaged as one self-contained .eetsmod file, and managed from inside the
game.
A mod is one .eetsmod file with everything inside (code, assets, config, etc).
Turning on mod support takes three steps. The first two differ by platform; the third is the same everywhere.
- Open the game folder. In Steam, right click Eets > Manage > Browse local
files, then drop the loader (from a release) into it:
- Windows:
version.dll(a proxy the game loads on startup) - Linux:
libeetsmod.so
- Windows:
- Set the launch option (Steam > right click Eets > Properties > General >
Launch Options), pasted exactly:
- Windows: none needed; Windows loads
version.dllfrom the game folder automatically. - Linux:
LD_PRELOAD=./libeetsmod.so %command%
- Windows: none needed; Windows loads
- Add mods. Put
.eetsmodfiles in themodsfolder. Press Play.
In-game: on the main menu, click the MODS button (bottom left) to enable/disable mods, change their settings, or open the mods folder.
Heads up: Mods are native code that runs as part of the game (no sandbox). Only install mods from people you trust.
The eetsmod CLI used below lives in this repo at bin/eetsmod. Clone the repo and
put it on your PATH:
git clone https://github.com/johnqherman/eets-mod-framework
export PATH="$PWD/eets-mod-framework/bin:$PATH"You also need a C++ compiler (g++). To build the Windows .dll as well, install
MinGW (i686-w64-mingw32-g++); without it pack still works but the bundle is
Linux-only.
eetsmod new mymodThis writes three files:
mymod.cpp: your code, pre-filled with empty event hooks.mymod.cfg: the manifest (version, author, dependencies; all optional).compile_flags.txt: include path so clangd/your editor resolves the API.
Implement the engine callbacks you care about; leave the rest out. The main ones:
| Hook | Fires |
|---|---|
EetsMod_Init() |
once at load |
EetsMod_Update() |
every frame |
EetsMod_OnKey(key, mods, down) |
key press/release |
EetsMod_OnEvent(name, a, b) |
game events: object_spawn, object_killed, level_load, level_reset, level_complete |
The full engine API is in API.md and the include/ headers.
Custom images, sounds, and anims live in a sibling mymod.assets/ folder whose
layout mirrors the game's Data/ tree (e.g. mymod.assets/Sound/Music/song.ogg).
Drop files there and the next step bundles them automatically.
Sounds are the one exception: the engine needs its own patch format, not a raw audio
file. Supply an .ogg and convert it first:
eetsmod add-sound mymod song.ogg # writes the engine-format files into mymod.assets/Then play it by name from code: PlaySound("song").
eetsmod pack mymod.cpp -o mymod.eetsmodpack does everything in one shot: compiles the .dll (Windows) and .so (Linux),
then bundles them with the source, the manifest, and mymod.assets/ into a single
mymod.eetsmod file.
Drop mymod.eetsmod in <game>/mods, then launch
and toggle it from the in-game MODS button. On launch the loader unpacks the bundle
and overlays its assets onto the game's Data/ before the engine reads them, so
custom assets load as if they shipped with the game. Build logs land in
<game>/Log/native_mods.log.
Tip: while developing you can skip packing: drop
mymod.cppstraight intomods/and the loader compiles it on launch.
Learn by example in examples/: gravity, custom images/sounds/anims, the UI
toolkit, object extensions, collisions.
bin/eetsmod build/pack/manage CLI
loader/ the injected loader (hooks, crash isolation, .eetsmod staging)
include/ mod headers: engine API, addresses, UI toolkit
examples/ example mods (source + <name>.assets/)
tools/ check-mod, add-sound, gen-api-ref, new-mod
API.md generated engine-API reference
Makefile build / check / bundles / apidoc / release
MIT.
Not affiliated with or endorsed by Klei Entertainment; Eets and its assets belong to their owners. This framework ships no game code, only original tooling and addresses derived from our own copy of the game. Use at your own risk.
