IFO Format (Module Info Blueprint)
Description: The Module Info (.ifo) is the absolute root metadata file for any environment. It dictates global module behavior, handling everything from the starting spawn location, to the local calendar and time-of-day progression, to script execution for global module events.
At a Glance
| Property | Value |
|---|---|
| Extension(s) | .ifo |
| Magic Signature | IFO / V3.2 |
| Type | Module Blueprint |
| Rust Reference | View rakata_generics::Ifo in Rustdocs |
Data Model Structure
Rakata parses the raw GFF structure into the rakata_generics::Ifo struct.
- Typestate Extraction: By extracting the loosely-typed GFF binary into a strict Rust struct, Rakata natively implements robust parsing for all module-level configuration.
Engine Audits & Decompilation
The following documents the engine’s exact load sequence and field requirements for .ifo files mapped from swkotor.exe.
(Decompilation logic for this section was entirely audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from CSWSModule::LoadModuleStart at 0x004c9050.)
Global State Configurations
| Field | Type | Engine Evaluation |
|---|---|---|
Mod_Entry_Area | ResRef | The primary spawning area ResRef. |
Mod_Entry_X / Mod_Entry_Y / Mod_Entry_Z | FLOAT | Exact spawning XYZ coordinates. |
Mod_Entry_Dir_X / Mod_Entry_Dir_Y | FLOAT | Entry Direction Fallback: If the engine cannot evaluate Mod_Entry_Dir_Y, it forces a hard graphical fallback rendering the entity facing east (X=1.0, Y=0.0). |
Mod_XPScale | BYTE | Globals XP multiplier scale. Defaults natively to 10. |
Time & Cycle Management
| Field | Type | Description |
|---|---|---|
Mod_DawnHour | BYTE | Dawn hour integer marker. |
Mod_DuskHour | BYTE | Dusk hour integer marker. |
Mod_MinPerHour | BYTE | Configuration for exactly how many real-time active gameplay minutes constitute a module hour limit. |
Note
Day/Night Cycle Computations The engine continuously computes localized day/night phases explicitly against
Mod_DawnHour,Mod_DuskHour, and thecurrent_hour. This dynamically updates an internal state flag denoting:1=Day,2=Night,3=Dawn,4=Dusk.
Global Event Scripts
Event scripts are universally evaluated as string ResRef pointers executing compiled NSS logic. The engine evaluates 15 separate global events (like Mod_OnHeartbeat, Mod_OnModLoad, Mod_OnClientEntr, Mod_OnPlrDeath, etc).
- Asymmetric I/O (Equipping): The
Mod_OnEquipItemarray natively loads during absolute module startup bounds (LoadModuleStart), however, it is entirely omitted and ignored during the save-game serialization cycle (SaveModuleIFOStart).
Safe-State Injection (Save Games Only)
Certain blocks of data inside the .ifo are deliberately evaluated only when the engine is mounting a module directly from a loaded .sav archive block.
| Engine Target | Description |
|---|---|
| Player / Mod Variables | Structures like Mod_PlayerList, Mod_Tokens, VarTable, and the EventQueue are strictly bypassed unless natively evaluated under is_save_game conditions. |
| Area Overrides | The Mod_Area_list technically supports arrays (for NWN legacy), but KOTOR strictly enforces a single active area boundary. The secondary ObjectId within this specific array is only ever read natively inside a save state flow. |
| Legacy Hak De-sync | “Hak Packs” are custom override archives natively used in Neverwinter Nights (the engine’s predecessor). While KOTOR’s save routine (SaveModuleIFOStart) blindly writes a Mod_Hak string into save-games as leftover legacy behavior, the actual load cycle (LoadModuleStart) completely ignores it. Modders cannot use this field to hook custom archives. |
Implemented Linter Rules (Rakata-Lint)
Phase 1 (intra-resource, no context)
Implemented under rakata_lint::rules::ifo.
- IFO-001 (Direction Fallback): Warns when
Mod_Entry_Dir_XandMod_Entry_Dir_Yboth evaluate to0.0; the engine forces an unrecorded fallback direction locking spawn toward(1.0, 0.0). - IFO-002 (XP Dead-Scaling): Warns when
Mod_XPScale == 0; aggressively halts all localized XP acquisition. - IFO-003 (Eternal Day/Night Bounds): Warns when
Mod_DawnHour == Mod_DuskHour; locks the module into perpetual daylight (engine forces transition indices to 3 or 4). - IFO-004 (Void Area Initialization): Errors when
Mod_Area_listis empty; directly faults the load cycle. - IFO-005 (Dangling NWM Structure): Warns when
Mod_IsNWMFile=truewithoutMod_NWMResName; evaluates to an unstable execution state.
Phase 2 (resource existence, requires LintContext)
Implemented under rakata_lint::rules::ifo_range.
- IFO-006 (Resref Existence): Warns when
Mod_Entry_Area(.are), anyMod_Area_list[i].Area_Name(.are), or any of the 15Mod_On*script hooks (.ncs) does not resolve in the configured resource sources.
Pending
- Mod_StartMovie (.bik): No
ResourceTypeCodevariant for the Bink movie format yet. - Mod_CutSceneList[i].CutScene_Name: Engine resolution is .dlg or .bik depending on context (audit deferred).