iecli is a CLI-first, Rust-based Infinity Engine inspection tool.
The project is aimed at trustworthy extraction rather than GUI editing. The goal is to read installed game resources, resolve them through the same archive and override rules the games use, and export stable machine-readable output that is useful for:
- inspection
- scripting
- diffing
- AI-assisted analysis
- future patch-generation workflows
The motivation is to have a tool that AI agents can use natively to explore/fix/modify Infinity Engine games.
The Rust rewrite is in progress. The current workspace already supports:
- game root validation via
chitin.key - Enhanced Edition
lang/<locale>/dialog.tlkdiscovery dialog.tlkstring lookup with out-of-range handlingdialog.tlkstring append for release-candidate local testing- typed
chitin.keyparsing - resource lookup from:
override- KEY-backed BIFF mappings
- read-only Enhanced Edition DLC archives (
dlc/*.zip), including the KEY a DLC carries of its own
- byte extraction from:
BIFFBIFBIFC
dump-rawexport for located resources- source-selectable lookup for
locate,dump, anddump-rawvia--source - resource enumeration with
list - typed JSON export for:
ITMSPLCRESTODLGBCSARECHR(a wrapper around a complete embeddedCRE)
- DLG graph export via
dump --format dot|mermaid, with optional extern following - override shadow/reference comparison via
override-diff - install-wide ARE cross-resource verification via
verify(dead Travel links, phantom entrances, missing scripts/actors/items) - game-variant detection (
standard/iwd/pst) with PST-specific effect-opcode decoding, reported bylocateasgame_variant - save inspection via
save-listandsave-info(GAMv2.0/2.1/2.2 and theSAVarchive) - scoped PSTEE save mutation via
save-add-item(one item into a party member's embedded CRE) - Tier 1
CRE/CHRscalar patching with byte-exact copy behavior outside requested fixed-offset fields - Tier 1 ARE Travel-region patching (
destination_area,destination_entrance) - agent skills for Claude Code and Codex that turn the JSON into narrative answers about a real install
Not implemented yet:
- structured write support for variable-length resource sections
Current validation for decoded formats already includes:
- real-install
dumpsmoke coverage forITMandSPL - early manual Near Infinity comparison for selected BG2EE
SPLresources - env-gated real-install regression tests for validated
SPLresources - output goldens in two tiers: exact-value goldens over synthetic fixtures and a synthetic install, covering every decoded format plus graph, save-listing, TLK, and human-text output modes and running in CI; and normalized JSON shape goldens checked against four real installs
- whole-install PSTEE sweeps across every dialogue in the game (859 DLGs), plus resource enumeration and diffing over a 2,313-resource PST mod, exercising
DLG,ITM,SPL, andCREdecoding at scale (see guides)
See Parser coverage for a per-format matrix of what is decoded, deferred, or preserved raw.
The Rust workspace is organized into:
crates/ie-corecrates/ie-iocrates/ie-formatscrates/ie-cli
IESDP is the layout reference for format work — offsets, field widths, and enum meanings. Expected values come from real game resources, since a specification cannot say what a given file contains. See Format References for the workflow.
Two projects shaped this one:
- IESDP for Infinity Engine file-format specifications, offsets, and field descriptions. It is the specification source the parsers are written against.
- Near Infinity for the inspiration behind this project, and for behavioral comparison during early parser validation. It remains the mature GUI tool
ieclideliberately does not try to replace.
iecli is a separate Rust implementation with a CLI-first product direction, not a Near Infinity
fork. Formats are decoded from IESDP and pinned against real game resources.
cargo buildRun tests:
cargo testShow CLI help:
cargo run -p iecli -- --helpiecli locate --game /path/to/game --resource ACIDBL.ITM
iecli locate --game /path/to/game --resource KIRINH.CRE --source bif
iecli dump-raw --game /path/to/game --resource ACIDBL.ITM --output ./ACIDBL.ITM
iecli dump-raw --game /path/to/game --resource KIRINH.CRE --source bif --output ./KIRINH-stock.CRE
iecli dump --game /path/to/game --resource ACIDBL.ITM --format json
iecli dump --game /path/to/game --resource SPWI112.SPL --format json
iecli dump --game /path/to/game --resource BALDUR.BCS --format json
iecli dump --game /path/to/game --resource AR0202.ARE --format json
iecli dump --game /path/to/game --resource FINMEL01.DLG --format dot --strings both
iecli dump --game /path/to/game --resource FINMEL01.DLG --format mermaid --follow-extern=2
iecli verify --game /path/to/game --source override --format json
iecli patch --game /path/to/game --resource KIRINH.CRE --set morale=9 --set morale_break=3 --output ./KIRINH.CRE
iecli patch --game /path/to/game --resource ARR019.ARE --set "regions.Door1900.destination_entrance=Exit1903" --output ./ARR019.ARE
iecli list --game /path/to/game --type CRE --name "kirin*"
iecli list --game /path/to/game --type ITM --source override --format json
iecli override-diff --game /path/to/game --type DLG --format json
iecli override-diff --game /path/to/game --against ./reference-override
iecli override-diff --game /path/to/game --resource KIRINH.CRE --against ./KIRINH-stock.CRE --format json
iecli tlk --game /path/to/game --strref 1
iecli tlk-append --game /path/to/game --text "New line" --tlk-out ./dialog-patched.tlk --output-strref-to ./new-strref.txt
iecli save-list --game /path/to/game --format json
iecli save-info --game /path/to/game --save "000000001-Quick-Save" --part gam
# save-add-item is PSTEE-only today; BG/IWD layouts are hard-refused until validated
iecli save-add-item --game /path/to/pstee --save "000000001-Quick-Save" --item <ITM-RESREF> --member 0 --output ./patched-saveUse --format json when something other than a human reads the output. Resrefs are not guaranteed to
be whitespace-free — stock BGEE ships MONKTU 8.DLG — so list --format text quotes any resref that
is not plain graphic ASCII, and splitting the unquoted text output on whitespace is not safe.
- Roadmap — current status, next milestones, write-support tiers
- Architecture
- Todo priorities
- Parser coverage — what each decoder exposes, defers, or leaves raw
- Regression plan
- JSON goldens — why real installs can pin shape but not values, and how to regenerate both tiers
- Testing notes — env-gated real-install test setup
- Format references — IESDP-first workflow
- DLG graph export + override diff
- Save support status and the write gate in SPEC_SAVE_ITEM_WRITE_COMPLETE
- DLC mounting spec — how Enhanced Edition
dlc/*.zipoverlays resolve, why a DLC's own KEY has to be merged, and how precedence is decided - Project skills — six game-exploration workflows (
diagnose-dialog,explore-dungeon,map-stat-gates,plan-stat-build,mod-diff,trace-quest-timer), packaged for both Claude Code and Codex - Guides — analysis written by those skills against real installs
This is a new tool with its own architecture and scope. Its parsers are developed against public format references and validated against real game resources.
This project is agent-coded. The concept, product direction, architecture, validation priorities, and final review are human-directed, but the Rust implementation was written by AI coding agents, primarily Codex from OpenAI, with review and debugging assistance from Claude by Anthropic.