Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

PropertyValue
Extension(s).ifo
Magic SignatureIFO / V3.2
TypeModule Blueprint
Rust ReferenceView rakata_generics::Ifo in Rustdocs

Data Model Structure

Rakata parses the raw GFF structure into the rakata_generics::Ifo struct.

  • (Note: rakata-lint does not currently implement behavioral validation for .ifo formats.)

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

FieldTypeEngine Evaluation
Mod_Entry_AreaResRefThe primary spawning area ResRef.
Mod_Entry_X / Mod_Entry_Y / Mod_Entry_ZFLOATExact spawning XYZ coordinates.
Mod_Entry_Dir_X / Mod_Entry_Dir_YFLOATEntry 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_XPScaleBYTEGlobals XP multiplier scale. Defaults natively to 10.

Time & Cycle Management

FieldTypeDescription
Mod_DawnHourBYTEDawn hour integer marker.
Mod_DuskHourBYTEDusk hour integer marker.
Mod_MinPerHourBYTEConfiguration 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 the current_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_OnEquipItem array 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 TargetDescription
Player / Mod VariablesStructures like Mod_PlayerList, Mod_Tokens, VarTable, and the EventQueue are strictly bypassed unless natively evaluated under is_save_game conditions.
Area OverridesThe 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.

Proposed Linter Rules (Rakata-Lint)

While rakata-lint does not currently implement .ifo validation, the exact engine behaviors discovered during decompilation dictate these static constraints:

  1. Direction Fallback: If Mod_Entry_Dir_X and Mod_Entry_Dir_Y both evaluate unconditionally to 0.0, the engine forces an unrecorded fallback direction locking the player spawn sequence toward (1.0, 0.0).
  2. XP Dead-Scaling: Since the Mod_XPScale default value evaluates to 10, any unexpected baseline of 0 aggressively halts all localized XP acquisition flows.
  3. Eternal Day/Night Bounds: If Mod_DawnHour strictly equals Mod_DuskHour, the module becomes hopelessly locked into perpetual daylight configurations.
  4. Void Area Initialization: An empty Mod_Area_list array directly faults the load cycle, as the module has no physical payload layout to inject the player into.
  5. Dangling NWM Structure: Setting Mod_IsNWMFile to 1 without deploying the conditionally mandatory Mod_NWMResName evaluates to an unstable execution state.