A desktop GUI for browsing, editing, and creating Conquest of Elysium 5 mods —
so you can build a mod without hand-writing .c5m command files.
Python + PySide6 (Qt6). Windows-first, but the code is plain Python.
CoE5 mods are plain-text .c5m files: a flat list of commands like
newmonster "Goblin Chief", hp 12, addunitrec 3 40 "Goblin". The format is
unforgiving — one typo, one stray space in a name, one unit referenced before
it's defined, and the engine silently ignores your block instead of erroring.
This tool gives you a form for each entity, writes the commands for you, and warns about the traps that fail silently.
You can edit:
| Category | What you get |
|---|---|
| Factions (classes) | Starting units/commander, recruitment lists, resources, class properties |
| Units (monsters) | Stats, weapons, sprites, special abilities |
| Weapons | Damage, attack type, effects |
| Rituals | Costs, school + level, effects |
| Items | Stats and effects |
| Terrain | Resource production, spawns |
| Schools | Mod-declared magic schools (newritpow), with scaffolding for mastery / level-up / promotion ritual chains |
| Resources | Reference view of the engine's 18 hardcoded resource types — which terrain produces each, which rituals consume it |
Anything the tool has no form for yet, you can still edit as raw commands (⟨/⟩ Raw button) — nothing is locked away.
Requirements: Python 3.11 or later, with "Add Python to PATH" checked during the Python installer.
Download/clone the repo, then double-click install.bat. It:
- Checks Python is on
PATH pip install --user -e .(no admin rights needed)- Creates a CoE5 Modder desktop shortcut
Manual alternative:
python -m pip install --user -e .
python -m coe5_modderRunning: use the desktop shortcut, or Run CoE5 Modder.bat in the repo
folder (Run CoE5 Modder.vbs launches with no console window at all).
Steam and CoE5 are detected automatically — whatever drive they're on. The chain is:
- The Windows registry (
HKCU\Software\Valve\Steam→SteamPath). This is authoritative and drive-agnostic, so it works for aC:install, aD:install, or anywhere else. libraryfolders.vdf, which enumerates every Steam library — Steam supports libraries spread across multiple drives, and all of them get checked.- For each library,
appmanifest_1606340.acfgives the real install folder name; the result is only accepted ifCoE5.exeis actually in it. - Only if all of the above fail: a short list of common default locations.
The resolved paths are cached in %APPDATA%\coe5\coe5_modder\settings.json.
If detection fails anyway, set them by hand in File → Settings.
The tool needs vanilla stats (units, classes, rituals, terrain, weapons, items) to show you what you're modifying. None of it ships with this repo — it's copyrighted game content.
Instead, on first launch it downloads the extracted vanilla .c5m data from the
public briggscalum/CoE_EA_Mod
mirror into data/cache/vanilla/, then reuses that cache offline forever after.
So the first launch needs an internet connection. After that, none.
Unit sprites are a separate matter: those are read from the .trs files in
your own local CoE5 install, and never leave your machine.
If vanilla is unavailable (offline first run, GitHub rate-limited), the tool still starts and mod-only editing works — you just lose the vanilla reference layer.
Startup is never fatal in general: a missing game install, no internet, or a
single unparseable Workshop mod gets logged and skipped while everything else
loads. The status bar reports what came up, e.g.
Ready: vanilla, 2 user mods, 14 Workshop mods.
Nothing is bundled. Every mod you see is discovered on your machine at startup, each launch, by scanning two folders:
| Source | Path |
|---|---|
| Your own mods | %APPDATA%\coe5\mods\ |
| Steam Workshop subscriptions | <Steam>\steamapps\workshop\content\1606340\ |
So mods you've subscribed to on the Workshop, and mods you've made yourself, show up automatically — no import step, no configuration. Subscribe to something new, restart the tool, and it's in the sidebar under Workshop Mods.
Scanning is read-only: other people's mods are shown as reference and are never written to. Your edits only ever go into your own active mod folder.
A mod that fails to parse is logged and skipped rather than taking the app down with it, so one broken Workshop mod can't stop you working.
Every entity has up to three layers, and the sidebar keeps them visibly separate:
- Vanilla — the base game's definition. Read-only reference.
- Workshop Mods — what other installed mods change, grouped per mod.
- My Edits — what your active mod changes. Your working set, expanded by default.
An entity you've overridden shows in both Vanilla and My Edits (tagged
(override)) — same underlying entry, so either row opens the same page.
Your edits always go into one active mod, shown as the Save target pill on
every editor page. You never modify vanilla files; the tool writes a select…
override block or a new… definition into your own mod folder under
%APPDATA%\coe5\mods\<your mod>\.
The engine numbers mod-defined classes across enabled mods only, so the tool
reads your coe5config to keep its class ids matching what the game will
actually assign. Disabling a mod in-game shifts those numbers — this keeps them
in sync.
You are not limited to overriding vanilla. Anything another installed mod
defines — a Workshop unit, a Workshop class — can be overridden the same way.
Open it from the Workshop Mods group, change a field, and a select… block
targeting it is written into your active mod.
Overrides resolve by name/id, exactly like the engine resolves them, so the tool doesn't care whether the thing you're changing came from the base game or from somebody else's mod.
Other people's mod files are never written to. Every edit lands in your own
mod folder. That includes deletion: on an entity another mod defined, Delete
removes the block from your mod, leaving theirs untouched.
The engine applies mods in modprio order and the last one wins, so an override
only takes effect if your mod loads after the mod it targets. A
selectclass aimed at another mod's class also needs that class to already
exist by the time yours is read.
New mods are created with modprio 9 — the top of the documented 1–9 range —
precisely so they load last and your overrides win by default.
Two limitations worth knowing:
modpriois not editable or even visible in the UI. It's parsed and used for ordering internally, but if you need to change it you have to edit the header line in the.c5mby hand.- If another mod also sits at
modprio 9, which of you wins is not something the tool can currently show or resolve.
Top bar: active mod indicator · ⌂ Project (what does my mod change?) · + Faction / Unit / Weapon / Ritual / Item / Terrain / School · 💾 Save · ▶ Launch CoE5 (offers to save first).
On any entity page:
- Duplicate… — clone under a new name via the engine's
copystats/copyspr, then change only what differs - Rename… — rename in place; sprite and stats untouched
- Set sprite… — copies your
.tga/.pnginto the mod'ssprites/folder. Pickingname1.tgaautomatically bringsname2.tgaalong so the unit animates - Recruit everywhere… — makes a unit recruitable by every class (the
SupportUnits pattern: one recruit line per
selectclass 1–30, written for you) - Move to new mod… — relocate the entity into a different mod folder
- ⟨/⟩ Raw — edit the entity's block as raw mod commands
- Delete (mod-defined) / Restore Default (removes your override; vanilla stays intact)
Project page lists every block your mod carries with an Edit/New badge, a
summary of the commands in it, and a one-click revert.
The .c5m format has failure modes that produce no error message at all. The
tool flags them as warnings (never blocking):
- Leading/trailing spaces in names —
"Goblin "is a legitimate trick to fork a unit without colliding with vanilla"Goblin", but one dropped space in a later reference silently breaks the link. Flagged so it's a choice, not an accident. - Definition-before-use — the engine parses top to bottom. A
setmaincom/addstartunits/copystatsnaming a unit defined later in the same file resolves to nothing. - Unclosed quotes — tolerated by the engine, brittle everywhere else.
- Non-ASCII characters — saves are ASCII; anything else is silently replaced.
python -m pip install --user -e ".[dev]"
python -m pytest -qCOE5_MODDING_FRAMEWORK points at a separate local checkout carrying an
archive of public Workshop mods, a command-usage corpus, and some standalone
CLI tools (validate / resize-sprite / make-transparent / new-mod).
You do not need it. It is not published, the app never requires it, and every consumer checks for existence and silently degrades. Leaving it unset is the normal, supported configuration — the only visible effect is that a handful of sample-mod tests skip.
If you do have such a checkout:
# Windows (PowerShell)
$env:COE5_MODDING_FRAMEWORK = "D:\path\to\coe5_modding"
# Linux / macOS
export COE5_MODDING_FRAMEWORK=/path/to/coe5_moddingUnset, it defaults to ~/.coe5_modding, which normally doesn't exist.
510 tests. How many actually run depends on what's available locally:
| Environment | Result |
|---|---|
| Fresh clone, no game, no cache (this is what CI runs) | 417 pass, 93 skip |
| Vanilla cached, i.e. after one normal launch | 503 pass, 7 skip |
Plus COE5_MODDING_FRAMEWORK set |
510 pass |
Nothing fails in any of these configurations — unavailable data causes a skip, never an error. CI runs the leanest of the three on Windows against Python 3.11, 3.12 and 3.13.
Layout:
src/coe5_modder/
parser/ lexer → AST → serializer for the .c5m format
model/ typed entities (monster, weapon, ritual, item, terrain, faction)
data/ vanilla + mod loading, registry, active-mod writes, lint
sprites/ sprite extraction and transparency handling
ui/ main window, sidebar, per-entity pages, dialogs
tests/ pytest suite
scripts/ extract_vanilla_sprites.py
Serialization is round-trip preserving: an unmodified document rewrites byte-for-byte identical to what was read, and when you do change something only the lines you touched are regenerated — surrounding formatting and comments are emitted verbatim. Editing a mod the tool only partly understands won't mangle the parts it doesn't.
MIT.
Conquest of Elysium 5 is a trademark of Illwinter Game Design. This is an unofficial, fan-made tool, not affiliated with or endorsed by Illwinter.
No game data or assets ship with this repository. Vanilla stat data is fetched at runtime from the public briggscalum/CoE_EA_Mod mirror; sprites are read from your own installation.

