Skip to content

Latest commit

 

History

History
166 lines (132 loc) · 8.36 KB

File metadata and controls

166 lines (132 loc) · 8.36 KB

iecli

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.

Status

The Rust rewrite is in progress. The current workspace already supports:

  • game root validation via chitin.key
  • Enhanced Edition lang/<locale>/dialog.tlk discovery
  • dialog.tlk string lookup with out-of-range handling
  • dialog.tlk string append for release-candidate local testing
  • typed chitin.key parsing
  • 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:
    • BIFF
    • BIF
    • BIFC
  • dump-raw export for located resources
  • source-selectable lookup for locate, dump, and dump-raw via --source
  • resource enumeration with list
  • typed JSON export for:
    • ITM
    • SPL
    • CRE
    • STO
    • DLG
    • BCS
    • ARE
    • CHR (a wrapper around a complete embedded CRE)
  • 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 by locate as game_variant
  • save inspection via save-list and save-info (GAM v2.0/2.1/2.2 and the SAV archive)
  • scoped PSTEE save mutation via save-add-item (one item into a party member's embedded CRE)
  • Tier 1 CRE/CHR scalar 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 dump smoke coverage for ITM and SPL
  • early manual Near Infinity comparison for selected BG2EE SPL resources
  • env-gated real-install regression tests for validated SPL resources
  • 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, and CRE decoding at scale (see guides)

See Parser coverage for a per-format matrix of what is decoded, deferred, or preserved raw.

Workspace

The Rust workspace is organized into:

  • crates/ie-core
  • crates/ie-io
  • crates/ie-formats
  • crates/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.

Acknowledgements

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 iecli deliberately 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.

Build

cargo build

Run tests:

cargo test

Show CLI help:

cargo run -p iecli -- --help

Current Commands

iecli 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-save

Use --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.

Documentation

Notes

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.

Disclosure

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.