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)

A .ifo file is a module’s own metadata: where the player enters, what the clock reads there, which areas belong to it, and which scripts fire on module-wide events. Inside a save it carries a second layer, the runtime snapshot of the session.

This page documents IFO’s field defaults, the save-game-only blocks gated behind Mod_IsSaveGame, and the confirmed-dead NWN-era residue the toolset still writes. Evidence is drawn from Ghidra decompilation of swkotor.exe (K1 GOG build), cross-checked against a full K1 install’s vanilla .ifo corpus and real save files. The tables below are lookup surfaces, meant to be searched rather than read start to end.

At a Glance

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

Field Schema

The format’s field families, as an orientation before the full list.

CategoryCoversRepresentative fields
Module IdentityThe module’s tag, localized name, and descriptionMod_Tag, Mod_Name, Mod_Description
Entry PointThe spawn area, position, and facing used on module entryMod_Entry_Area, Mod_Entry_X, Mod_Entry_Dir_X
Time & CalendarDay/night pacing and the module’s starting clockMod_MinPerHour, Mod_DawnHour, Mod_StartYear
Global Event ScriptsThe module-wide event hooksMod_OnModLoad, Mod_OnClientEntr, Mod_OnHeartbeat
Area & Cutscene RostersThe areas belonging to the module, plus cutscene and expansion metadataMod_Area_list, Mod_CutSceneList
Save-Only StateThe runtime snapshot a save adds: party roster, tokens, id allocators, and the live clockMod_PlayerList, Mod_Tokens, Mod_NextObjId0

Engine Audits & Decompilation

(Documented from Ghidra decompilation of swkotor.exe. Load path: CSWSModule::LoadModuleStart (0x004c9050). Save-side writers referenced below: SaveModuleFinish (0x004ca680), which calls SaveModuleIFOStart (0x004c7050), the function that actually writes Mod_ID/Mod_Creator_ID/Mod_Version, plus SavePlayers (0x004c7870) and SaveLimboCreatures (0x004c5bb0). Provenance: derived, not attested, so these rows sit on the reverse-engineering queue.)

Module Identity & Structural Rosters

These fields are written on every module save regardless of save-vs-fresh state. They aren’t part of the save-only state covered further down.

FieldTypeEngine Evaluation
Mod_IDVOID (variable length)Opaque, write-only round-trip data; see Mod_ID is inert, and the length split is incidental below. Written unconditionally on every save, whether resuming or freshly starting a module.
Mod_Creator_IDINTWritten unconditionally alongside Mod_ID.
Mod_VersionDWORDWritten unconditionally alongside Mod_Creator_ID.
Mod_IsSaveGameBYTEDefaults to false when absent, carried over from the object’s own constructed value (which the constructor itself sets to 0 immediately before the read runs) rather than a separately-chosen literal.
Mod_IsNWMFileBYTESame carry-over mechanism as Mod_IsSaveGame: constructor sets false first, absence leaves it there.
Mod_NWMResNameCExoStringOnly read at all if the resolved Mod_IsNWMFile (from the read above, present or defaulted) is true. If false, this field is never touched regardless of what the file contains. When the gate is open and the field itself is absent, it carries over the object’s constructed empty string, the same nested pattern as Mod_IsNWMFile gating Mod_NWMResName’s read.
Mod_TagCExoStringDefaults to a literal empty string if missing, not carried over: the read’s own default is a fresh empty string, independent of whatever the constructor set. The result always passes through SetTag, which lowercases it, so tags land lowercase whether read from the file or defaulted.
Mod_NameLocalizedStringDefaults to an empty localized string if missing, unconditional.
Mod_DescriptionLocalizedStringSame as Mod_Name: empty localized string if missing, unconditional.
Mod_Expan_ListList of StructExpansion pack metadata (Expansion_Name, Expansion_ID per entry). Always written, though the list may legitimately be empty. Each entry is freshly allocated and both fields are unconditional literal stamps if absent: Expansion_Name to an empty localized string, Expansion_ID to 0.
Mod_CutSceneListList of StructCutscene name/id pairs (CutScene_Name, CutScene_ID per entry). Always written, though the list may legitimately be empty. Same shape as Mod_Expan_List: CutScene_Name defaults to an empty resref, CutScene_ID to 0, both unconditional.

Mod_ID is inert, and the length split is incidental

A vanilla module’s own .ifo (as shipped inside a .mod archive) carries a 16-byte Mod_ID. Every save-game’s bundled module.ifo carries 32 bytes. This isn’t two encodings of one concept, nor a save-only extension of the field with meaningful extra data. It is an artifact of how the engine reads and re-writes an opaque blob it never interprets.

The read is capped at 32 bytes and does not zero-pad

LoadModuleStart reads Mod_ID into a fixed 32-byte destination, with the read capped at 32 bytes whatever the field’s real length. A vanilla module’s 16 bytes therefore overwrite only the first half, and nothing zero-pads the rest. The buffer is allocated without zero-initialization, so the upper 16 bytes keep whatever the heap left there.

Mod_Creator_ID and Mod_Version sit beside Mod_ID in that same allocation. They are distinct GFF fields, adjacent as a memory-layout convenience rather than as part of Mod_ID.

The writer always emits 32 bytes back

It takes them from that same in-memory buffer, unconditionally, regardless of how many of those bytes came from the original file versus leftover heap contents. That is the entire explanation for the observed split: a vanilla .ifo’s 16-byte Mod_ID, once loaded and saved even once, becomes a 32-byte field whose upper half is incidental garbage, not a second logical sub-field with any meaning.

Nothing reads it back

Nothing reads Mod_ID back out. No comparison against the target module’s own file, no hash check, no “does this save belong to this module” validation, confirmed by an exhaustive check of every reference to the field and to the buffer it lands in. It is write-only round-trip data.

So a tool rewriting module info need not preserve its bytes for correctness. It should still read the field at whatever length it finds and not synthesize a 32-byte one on write, because the engine’s own 32 bytes are a side effect of that uninitialized buffer rather than a requirement of the format.

Global State Configurations

FieldTypeEngine Evaluation
Mod_Entry_AreaResRefThe primary spawning area ResRef.
Mod_Entry_X / Mod_Entry_Y / Mod_Entry_ZFLOATExact spawning XYZ coordinates. All three default to a literal 0.0 if missing, unconditional, independent of Mod_IsSaveGame.
Mod_Entry_Dir_X / Mod_Entry_Dir_YFLOATEntry Direction Fallback: If Mod_Entry_Dir_Y is absent from the GFF, the engine forces a fallback facing of (X=1.0, Y=0.0).
Mod_XPScaleBYTEModule XP scale, default 10. The K1 engine reads this field and writes it back on save, but never consumes it: nothing in the XP award path multiplies by it. It is inert in swkotor.exe.
Mod_StartMovieResRefRead on module load with a constant empty-ResRef default. A binary-wide search turns up exactly one reference to the Mod_StartMovie label in the whole engine, the read inside LoadModuleStart itself; no write exists anywhere in swkotor.exe. This field is load-only, full stop.

Time & Cycle Management

FieldTypeDescription
Mod_DawnHourBYTEDawn hour integer marker. Defaults to 0 if missing: a plain literal, not the object’s constructed value, since the constructor doesn’t initialize this field to a meaningful hour before the read runs.
Mod_DuskHourBYTEDusk hour integer marker. Defaults to 0 if missing, same as Mod_DawnHour.
Mod_MinPerHourBYTEHow many minutes of gameplay make one module hour. Defaults to 0 if missing.

Note

Day/Night Cycle Computations The engine derives the day/night phase from Mod_DawnHour, Mod_DuskHour and the current hour, keeping the result in an internal flag: 1 Day, 2 Night, 3 Dawn, 4 Dusk.

Note

Mod_MinPerHour, Mod_DawnHour, and Mod_DuskHour each default to a literal 0 when absent, confirmed directly against the read call for all three. Not 2, 6, and 18, values that would look plausible as a real-world minute count and typical dawn/dusk hours but aren’t what the engine actually falls back to.

Global Event Scripts

Each event is a single ResRef field naming a compiled script (.ncs) the engine fires when that event occurs. K1 defines these module events:

FieldFires when
Mod_OnModLoadthe module is loaded
Mod_OnModStartthe module starts (first client entry)
Mod_OnClientEntra player enters the module
Mod_OnClientLeava player leaves the module
Mod_OnHeartbeatthe module heartbeat ticks
Mod_OnUsrDefineda user-defined event is signalled
Mod_OnAcquirIteman item is acquired
Mod_OnUnAqreIteman item is unacquired (dropped or removed)
Mod_OnActvtIteman item is activated
Mod_OnEquipIteman item is equipped
Mod_OnPlrDeatha player dies
Mod_OnPlrDyinga player drops to dying
Mod_OnPlrLvlUpa player levels up
Mod_OnPlrResta player rests
Mod_OnSpawnBtnDna respawn is requested (a multiplayer-era Aurora event)
  • Asymmetric I/O (equipping). Mod_OnEquipItem is read during module startup (LoadModuleStart), but SaveModuleIFOStart never writes it back out, so a save-game round-trip silently drops it. In the binary its label sits apart from the rest, which are stored contiguously, matching the one-off handling.
  • Absent-field default, every hook. Every script hook, Mod_OnEquipItem included, follows one uniform pattern: read with a locally-constructed empty resref as the default and unconditionally stamped into the module’s script table, no presence check consulted afterward. Mod_OnEquipItem’s asymmetry above is entirely a write-side omission. On the read side it is handled identically to its siblings.

Note

NWM = NeverWinter Module. Mod_IsNWMFile marks a module as a .nwm-type module, a format the Odyssey engine inherited from BioWare’s Aurora engine (the one behind Neverwinter Nights). When the flag is set, the engine pairs it with Mod_NWMResName and skips re-saving the area ARE static into the module’s save ERF. The skip is narrow: SaveModuleFinish gates the ARE static write behind is_nwm_file == 0, while the GIT is written unconditionally in SaveModuleInProgress. So an NWM save still gets its dynamic GIT, just not a re-copied static ARE .

Save-only state

Mod_PlayerList, Mod_Tokens, VarTable, the EventQueue and the id counters sit inside the loader’s is_save_game block, so they are read only when the engine mounts a module out of a loaded .sav. In a static module they are skipped entirely.

Two rules cover the whole block.

No list drops a partially-specified entry. Across Mod_Area_list, Mod_Expan_List, Mod_CutSceneList, Mod_PlayerList and Mod_Tokens, an entry missing fields is still appended, with each missing field independently defaulted to a literal. Only a heap-allocation failure aborts a list, and that terminates the whole LoadModuleStart call.

An absent list container is a skip, not a clear. Mod_PlayerList, Mod_Tokens, VarTable and SWVarTable all resolve an empty count when the field is missing and never enter their read loop, leaving whatever the object already held. None of the four clears its in-memory list first, so omitting a container does not erase state.

VarTable

Read by CSWSScriptVarTable::LoadVarTable. Each entry is Name (CExoString, empty if absent), Type (DWORD, 0 if absent), and Value, whose read type comes from a switch on the resolved Type:

TypeValue read asAbsent default
1INT0
2FLOAT0.0
3CExoStringempty
4DWORD0
5nested location structits own sub-field defaults

Type’s own absent default is 0, which matches no case, and the switch has no default arm. An entry whose Type is missing is silently a no-op.

Warning

CSWVarTable::LoadVarTable is a different function reading a different label It reads a nested struct labelled SWVarTable holding two capped lists, BitArray at three entries and ByteArray at eight, each entry a single Variable field defaulting to 0. This is legacy bit/byte-var infrastructure, unrelated to the VarTable above despite the near-identical function name.

EventQueue

Read by CServerAIMaster::LoadEventQueue, each element handed to CServerAIEventNode::LoadNode, which reads five DWORD scalars: Day, Time, ObjectId, CallerId, EventId. All default to a literal 0.

ObjectId defaulting to 0 here is the one exception to the object-reference sentinel used everywhere else, and the cause is allocation rather than intent. CServerAIEventNode has no constructor and is allocated with a bare unzeroed operator new immediately before LoadNode runs, so there is no constructor step to set 0x7F000000 and the read’s own literal is the only initialization the field gets. Every other object-reference field traces back to a real constructor (see UTC’s LoadCreature divergence).

Once EventId resolves, a switch dispatches to type-specific EventData loaders for effects, combat data and script situations. Those nested defaults are not traced.

Mod_PlayerList

One struct per party member, written by SavePlayers: Mod_CommntyName, Mod_IsPrimaryPlr (BYTE), Mod_FirstName and Mod_LastName (localized), ObjectId, plus the member’s full creature serialization.

Each rebuilt node is placement-constructed empty first, so every field is an unconditional literal stamp: empty string, empty localized strings, and 0 for Mod_IsPrimaryPlr.

ObjectId is not read in that rebuild loop at all. It is read in SavePlayers’ carry-forward pass, which reopens the previous module’s Mod_PlayerList to pull limbo members forward. There an absent ObjectId defaults to 0x7F000000, and that default is load-bearing: the carry-forward code compares against that exact sentinel and drops the entry. An absent ObjectId on a carried-forward member means the member does not survive the module transition.

Mod_Area_list

The list supports arrays for NWN compatibility, but KOTOR takes element 0 and nothing else, reading Area_Name directly with an empty-ResRef default rather than looping.

The ObjectId inside this list is read only under the save-game gate, defaulting when absent to 0x7F000000, the engine-wide default for the label.

Runtime id counters

Mod_NextCharId0, Mod_NextCharId1, Mod_NextObjId0, Mod_NextObjId1 and Mod_Effect_NxtId persist the engine’s id allocators so a resumed session keeps handing out fresh ids. All five read with a literal 0 default and are written only by SaveModuleIFOStart.

None of them writes onto the module object. The four id fields write into fixed offsets on the engine’s shared global object-id allocator, reached through CServerExoApp::GetObjectArray, and Mod_Effect_NxtId writes a global symbol.

That makes an absent counter worse than an ordinary default gap: it zeroes the live shared allocator mid-load, affecting the whole session rather than one module.

The live clock

Beyond the authored Mod_StartYear/Month/Day/Hour, a save records the live time of day (Mod_StartMinute, Mod_StartSecond, Mod_StartMiliSec), the paused world clock (Mod_PauseDay, Mod_PauseTime) and Mod_Transition.

This block’s gate is not Mod_IsSaveGame. LoadModuleStart takes a separate parameter the client sets for “the player picked Load Game”. The two agree in practice and are structurally different conditions.

With that parameter set, all ten fields read with literal defaults: Mod_StartYear 1340, Mod_StartMonth 6, Mod_StartDay 1, Mod_StartHour 23, and 0 for the remaining six.

With it clear, on an ordinary module-to-module transition, none of the ten is read from the GFF and no default applies. The engine carries the live clock forward from the previous module through CServerExoApp::GetMoveToWorldTime and its paused-time counterparts. So these fields have a default only on a genuine save load; otherwise their values are session-carried.

Mod_StartMonth, Mod_StartDay and Mod_StartHour are also named asymmetrically: the writer sources them from where gameplay time currently stands, and the loader treats them as start values.

Mod_Tokens

Runtime overrides for custom TLK string tokens. Each entry carries Mod_TokensNumber (the index, default 0) and Mod_TokensValue (the replacement, default empty), both unconditional stamps.

Only entries with an index above 9 are written back out, since 0-9 are reserved.

Warning

The reserved range is protected on write and not on read SetCustomToken does a plain indexed insert with no range check. An entry whose Mod_TokensNumber is absent defaults to index 0 and is installed there, overwriting a slot the writer itself treats as reserved. A hand-authored or corrupted entry lands on a reserved index without complaint.

Limbo creatures

Party members not in the active area are serialized into the module IFO by SaveLimboCreatures, each an ObjectId plus a full creature blob. The list reuses the label Creature List, which the GIT also uses for area creatures, so the same name appears in two containers. Note it takes that name bare, with no Mod_ prefix, unlike every other list the IFO owns.

Each element’s struct id must be 4 or the engine skips it, the same constant and the same silent skip GIT’s own Creature List uses. A wrong id costs a party member out of a save with nothing recording that anyone went missing, so a tool writing limbo creatures carries the same obligation as one writing area creatures.

The read itself is not save-gated. It sits outside the is_save_game block that guards Mod_PlayerList and its neighbours, and runs on every module load. An ordinary module carries no such list so nothing happens, but that is a fact about what vanilla writes rather than a gate in the loader: a static module that did carry one would have it read.

Mod_Hak

Hak packs are Neverwinter Nights override archives. SaveModuleIFOStart writes a Mod_Hak string into save games and LoadModuleStart never reads it, so the field cannot hook custom archives.

More Confirmed-Dead NWN Residue: Mod_VO_ID, Expansion_Pack, Mod_GVar_List

A corpus scan across 117 real module.ifo files, vanilla and save-bundled, turned up three more fields beside the documented Mod_Hak/Mod_IsNWMFile residue. None of the three label strings exists anywhere in swkotor.exe. GFF field access is string-literal lookup, so a label the binary never spells out cannot be read by LoadModuleStart or written by SaveModuleIFOStart.

That leaves nothing to document per field: no read call site to trace, and no absent-value default to give, because there is no read.

  • Mod_VO_ID (CExoString) is the most notable of the three: it carries a value in 98 of the 117 files scanned, the highest live-value density of any unmodeled field found in this codebase’s completeness audits, yet the engine never reads it under any code path. It shares the exact fate of .uti’s already-confirmed-dead VO_ID field: both look like an authoring-side voice-over production lookup key, and neither has a runtime consumer in K1. Model it as dead/toolset-only rather than a live field with a meaningful default.
  • Expansion_Pack (WORD) is present in every file and always 0. This is NWN/Aurora expansion-selector residue, consistent with the Mod_IsNWMFile/Mod_Hak precedents on this same format. A real, unrelated Expansion_ID/Expansion_Name pair exists in the binary, used by Mod_Expan_List and already modelled, but Expansion_Pack itself is a different, unread label.
  • Mod_GVar_List (List) is present in every file and always empty. K1’s actual campaign-global mechanism lives exclusively in the save-scoped GLOBALVARS.res (GVT ), a completely separate system with no code path connecting it back to this module-scoped field. Mod_GVar_List is NWN module-format residue that happens to share vocabulary with the real mechanism, nothing more.

Implemented Linter Rules (Rakata-Lint)

Phase 1 (intra-resource, no context)

Implemented under rakata_lint::rules::ifo.

  1. IFO-001 (Direction Fallback): Warns when Mod_Entry_Dir_X and Mod_Entry_Dir_Y are both 0.0. The engine substitutes a hard fallback heading of (1.0, 0.0) only when Mod_Entry_Dir_Y is absent from the GFF; a value that is present but (0.0, 0.0) is left as a degenerate heading with no facing.
  2. IFO-002 (XP Dead-Scaling): Reports at info severity when Mod_XPScale == 0. The engine parses Mod_XPScale and never applies it to awarded XP, so the field is inert and a zero halts nothing. Zero is the trigger because it is the value somebody writes when they are trying to switch XP off, and the point of the diagnostic is to tell them the edit does nothing.
  3. IFO-003 (Eternal Day/Night Bounds): Warns when Mod_DawnHour == Mod_DuskHour. When the two are equal the engine skips the entire dawn/dusk/night computation and locks the phase to 1 (Day), so the module is stuck in perpetual daylight.
  4. IFO-004 (Void Area Initialization): Errors when Mod_Area_list is empty, which fails the module load.
  5. IFO-005 (Dangling NWM Structure): Warns when Mod_IsNWMFile=true without Mod_NWMResName; the gate opens on a name the file never supplies, leaving the module marked NWM with an empty resource name.
  6. IFO-007 (Limbo Creature Struct Id): Errors when an element of the module’s own Creature List does not carry struct id 4. Same constant and same silent skip as GIT’s area creatures, and a mismatch costs a party member out of a save with nothing recording it. Reads the raw GFF, since a struct id does not survive from_gff. Applies to any IFO carrying the list rather than to saves specifically: the read sits outside the save-game gate and runs on every module load.

Phase 2 (resource existence, requires LintContext)

Implemented under rakata_lint::rules::ifo_range.

  1. IFO-006 (Resref Existence): Warns when Mod_Entry_Area (.are), any Mod_Area_list[i].Area_Name (.are), or any Mod_On* script hook (.ncs) does not resolve in the configured resource sources.

Pending

  • Mod_StartMovie (.bik): No ResourceTypeCode variant for the Bink movie format yet.
  • Mod_CutSceneList[i].CutScene_Name: Engine resolution is .dlg or .bik depending on context (audit deferred).

Every label the schema declares

Generated from the schema, so no label can be quietly left out. How to read these tables.

What the engine does with each field

FieldTypeEngineWhen absent
Creature ListListreads itnot one constant; we substitute container

Fields nobody has examined

Whether the engine reads these has not been established, which is not the same as establishing that it does not. Where When absent carries an answer, that half is settled.

FieldTypeWhen absent
Mod_IDVOIDNOT EXAMINED; we substitute ````
Mod_Creator_IDINTNOT EXAMINED; we substitute 0
Mod_VersionDWORDNOT EXAMINED; we substitute 0
Mod_NameCExoLocStringNOT EXAMINED; we substitute empty
Mod_DescriptionCExoLocStringNOT EXAMINED; we substitute empty
Mod_TagCExoStringstamps ""
Mod_IsSaveGameBYTEkeeps 0
Mod_IsNWMFileBYTEkeeps 0
Mod_NWMResNameCExoStringkeeps ""
Mod_StartMovieCResRefstamps ""
Mod_Entry_AreaCResRefNOT EXAMINED; we substitute ""
Mod_Entry_XFLOATNOT EXAMINED; we substitute 0.0
Mod_Entry_YFLOATNOT EXAMINED; we substitute 0.0
Mod_Entry_ZFLOATNOT EXAMINED; we substitute 0.0
Mod_Entry_Dir_XFLOATnot one constant; we substitute 0.0
Mod_Entry_Dir_YFLOATnot one constant; we substitute 0.0
Mod_MinPerHourBYTEstamps 0
Mod_DawnHourBYTEstamps 0
Mod_DuskHourBYTEstamps 0
Mod_XPScaleBYTEstamps 10
Mod_StartYearDWORDstamps 1340
Mod_StartMonthBYTEstamps 6
Mod_StartDayBYTEstamps 1
Mod_StartHourBYTEstamps 23
Mod_TransitionDWORDstamps 0
Mod_StartMinuteWORDstamps 0
Mod_StartSecondWORDstamps 0
Mod_StartMiliSecWORDstamps 0
Mod_PauseTimeDWORDstamps 0
Mod_PauseDayDWORDstamps 0
Mod_Effect_NxtIdDWORD64stamps 0
Mod_NextCharId0DWORDstamps 0
Mod_NextCharId1DWORDstamps 0
Mod_NextObjId0DWORDstamps 0
Mod_NextObjId1DWORDstamps 0
Mod_HakCExoStringNOT EXAMINED; we substitute ""
Mod_OnHeartbeatCResRefstamps ""
Mod_OnUsrDefinedCResRefstamps ""
Mod_OnModLoadCResRefstamps ""
Mod_OnModStartCResRefstamps ""
Mod_OnClientEntrCResRefstamps ""
Mod_OnClientLeavCResRefstamps ""
Mod_OnActvtItemCResRefstamps ""
Mod_OnAcquirItemCResRefstamps ""
Mod_OnUnAqreItemCResRefstamps ""
Mod_OnPlrDeathCResRefstamps ""
Mod_OnPlrDyingCResRefstamps ""
Mod_OnSpawnBtnDnCResRefstamps ""
Mod_OnPlrRestCResRefstamps ""
Mod_OnPlrLvlUpCResRefstamps ""
Mod_OnEquipItemCResRefstamps ""
Mod_Expan_ListListNOT EXAMINED; we substitute container
Mod_Expan_List[].Expansion_NameCExoLocStringstamps empty
Mod_Expan_List[].Expansion_IDINTstamps 0
Mod_CutSceneListListthe page does not say; we substitute container
Mod_CutSceneList[].CutScene_NameCResRefstamps ""
Mod_CutSceneList[].CutScene_IDDWORDstamps 0
Mod_Area_listListthe page does not say; we substitute container
Mod_Area_list[].Area_NameCResRefstamps ""
Mod_Area_list[].ObjectIdDWORDstamps 2130706432
Mod_PlayerListListnot one constant; we substitute container
Mod_PlayerList[].Mod_CommntyNameCExoStringstamps ""
Mod_PlayerList[].Mod_FirstNameCExoLocStringstamps empty
Mod_PlayerList[].Mod_LastNameCExoLocStringstamps empty
Mod_PlayerList[].Mod_IsPrimaryPlrBYTEstamps 0
Mod_TokensListnot one constant; we substitute container
Mod_Tokens[].Mod_TokensNumberDWORDstamps 0
Mod_Tokens[].Mod_TokensValueCExoStringstamps ""
SWVarTableStructnot one constant; we substitute container
VarTableListnot one constant; we substitute container