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

GVT Format (Global Variable Table)

Description: The globalvars (GLOBALVARS.res) file is the campaign’s plot state (type GVT ): the flags and counters scripts read and set across the whole playthrough. It sits loose in the save folder, written at save time.

At a Glance

PropertyValue
FilenameGLOBALVARS.res
Magic SignatureGVT / V3.2
TypeGlobal Variable Table
Rust ReferenceHandled by rakata-save (mid-refactor).

Data Model Structure

Globals come in four types, one for each kind of variable a script can stash between sessions. Each type has its own get/set accessor (the engine’s GetValueBoolean / SetValueBoolean, and the Number, Location, and String variants), so what a type is for is what shapes how it is stored and how many of it the engine keeps room for:

TypeHoldsCapWhat scripts use it for
Booleana single bit900Plot switches and one-shot guards: has this happened? The most common kind of global.
Numbera single unsigned byte (0-255)500Small counters and quest-stage enumerations. It is a byte, not a 32-bit integer, so it cannot hold an arbitrary count.
Locationa position and orientation100A remembered spot to send, spawn, or move an object to later.
Stringa short text value5A handful of named text tokens; scripts rarely need one.

The caps are hard limits: any identifier past a type’s cap is dropped on load with a “won’t fit” log.

Each type pairs a catalogue list of names with a positional value block: the name of global i is Cat<Type> element i, and its value is position i of the matching Val<Type> block. The catalogue maps each value slot back to its name.

Catalogue (names)Value blockEncoding
CatBooleanValBooleanVOID, bit-packed. Boolean i is bit 7 - (i & 7) of byte i >> 3 (most-significant bit first). Block length is (count >> 3) + 1 bytes.
CatNumberValNumberVOID, one unsigned byte per number. Number i is byte i; values are 0-255.
CatLocationValLocationVOID, a fixed 2400-byte array of 100 slots of 24 bytes each. Location i is slot i; unused slots are zero, and the block is written whole.
CatStringValStringLIST, one struct per string carrying a String (CExoString).

Each Cat* element is a struct with a Name (CExoString). Because the Val* blocks are positional, dropping or reordering a catalogue entry silently reassigns every later value.

Warning

There are four global types, not two. A model that handles only CatNumber / CatBoolean silently drops every Location and String global. They are simple to miss, but they are real campaign state that has to round-trip.

Each 24-byte location slot is a CScriptLocation: a position Vector followed by an orientation Vector, with no area reference in K1.

FieldTypeMeaning
PositionVector (three float32, LE)The stored point (X, Y, Z), bytes 0x00-0x0b.
OrientationVector (three float32, LE)The stored facing (X, Y, Z), bytes 0x0c-0x17.

Engine Audits & Decompilation

Documented from Ghidra decompilation of swkotor.exe (K1 GOG build); see the Provenance Policy. The encoding, the per-type accessors, and the location layout are read from:

FunctionAddressCovers
CSWGlobalVariableTable::WriteTable0x005299b0Value-block encoding on write
CSWGlobalVariableTable::ReadTableWithCatalogue0x0052a280Encoding and per-type caps on read
CSWGlobalVariableTable::GetValueBoolean0x00529110Boolean value read (the script get)
CSWGlobalVariableTable::GetValueNumber0x00529240Number value read
CSWGlobalVariableTable::GetValueLocation0x00529350Location value read (slot copy)
CSWGlobalVariableTable::GetValueString0x00529460String value read
CSWSObject::GetScriptLocation0x004cb7b0Location field order (position then orientation)

Note

The script layer is not documented yet. These are the engine’s internal per-type accessors. The NCS/NSS-facing script functions (GetGlobalBoolean / SetGlobalBoolean and the Number / Location / String pairs) that call them are still to be mapped and documented.

Implemented Linter Rules (Rakata-Lint)

None yet. Documented here ahead of any dedicated rakata-lint rules.