PT Format (Party Table)
Description: The partytable (PARTYTABLE.res) file is a live snapshot of the adventuring group plus a grab-bag of session state (type PT , two trailing spaces). It sits loose in the save folder, written at save time.
At a Glance
| Property | Value |
|---|---|
| Filename | PARTYTABLE.res |
| Magic Signature | PT / V3.2 (two trailing spaces in the tag) |
| Type | Party Table |
| Rust Reference | Handled by rakata-save (mid-refactor). |
Data Model Structure
The top-level struct groups party state into scalar flags plus several lists: the roster, available companions, the pazaak decks, the feedback and dialog logs, and the journal. Each group is a field table below.
Engine Audits & Decompilation
(Documented from Ghidra decompilation of swkotor.exe (K1 GOG build). Writer: CSWPartyTable::SaveTableInfo at 0x005648c0. The journal is written by CSWPartyTable::SaveJournal at 0x00563d90, which SaveTableInfo invokes.)
Resources and flags
| Field | Type | Meaning |
|---|---|---|
PT_GOLD | DWORD | Party gold. The authoritative value on load: party members’ own Gold fields are deliberately skipped in favour of this one (see Gold and the party pool). |
PT_XP_POOL | INT | Shared experience pool; benched companions are topped up toward their npc.2da PercentXP share of it when they rejoin. |
PT_PLAYEDSECONDS | DWORD | Running play time, in seconds. |
PT_CHEAT_USED | BYTE | Cheat flag; savenfo’s CHEATUSED carries the same value. |
PT_SOLOMODE | BYTE | Solo-mode flag. |
PT_CONTROLLED_NPC | INT | Currently controlled party member. |
Roster
PT_NUM_MEMBERS (BYTE) plus PT_MEMBERS, a list with one struct per active member:
| Field | Type | Meaning |
|---|---|---|
PT_MEMBER_ID | INT | Companion id (npc.2da row) of the member. |
PT_IS_LEADER | BYTE | Whether this member is the party leader. |
Available companions
PT_AVAIL_NPCS, a list with one struct per recruitable companion, indexed by npc.2da row (nine slots in K1):
| Field | Type | Meaning |
|---|---|---|
PT_NPC_AVAIL | BYTE | Whether the companion has been unlocked. |
PT_NPC_SELECT | BYTE | Whether the companion is selectable for the active party. |
These flags are only the index. The actual creature snapshot for each recruited companion is a standalone AVAILNPCn UTC bundled inside SAVEGAME.sav, written at recruit time and refreshed at save time; PT_NPC_AVAIL gates whether the engine will instantiate it at all. See the companion pool in the deep dive.
Party AI
| Field | Type | Meaning |
|---|---|---|
PT_AISTATE | INT | Party combat-AI state. |
PT_FOLLOWSTATE | INT | Party follow/formation state. |
Galaxy map
| Field | Type | Meaning |
|---|---|---|
GlxyMapNumPnts | DWORD | Number of known map points. |
GlxyMapPlntMsk | DWORD | Planet unlock bitmask. |
GlxyMapSelPnt | INT | Currently selected map point. |
Pazaak
| Field | Type | Meaning |
|---|---|---|
PT_PAZAAKCARDS | list | Owned-card counts: a fixed 18 elements, each { PT_PAZAAKCOUNT: INT } (one per card). |
PT_PAZSIDELIST | list | Chosen side deck: a fixed 10 elements, each { PT_PAZSIDECARD: INT }. |
Feedback and dialog logs
| Field | Type | Meaning |
|---|---|---|
PT_FB_MSG_LIST | list | On-screen feedback messages, each { PT_FB_MSG_MSG: CExoString, PT_FB_MSG_TYPE: DWORD, PT_FB_MSG_COLOR: BYTE }. |
PT_DLG_MSG_LIST | list | Dialog message log, each { PT_DLG_MSG_SPKR: CExoString, PT_DLG_MSG_MSG: CExoString }. |
PT_COST_MULT_LIST | list | Store cost multipliers, each { PT_COST_MULT_VALUE: FLOAT }. |
UI state
| Field | Type | Meaning |
|---|---|---|
PT_TUT_WND_SHOWN | VOID | Tutorial-window-shown flags (opaque byte blob). |
PT_LAST_GUI_PNL | INT | Last GUI panel the player had open. |
Journal
The journal is folded into the same file: JNL_SortOrder (INT) plus JNL_Entries, a list with one struct per active quest:
| Field | Type | Meaning |
|---|---|---|
JNL_PlotID | CExoString | Quest/plot identifier. |
JNL_State | INT | Current quest state. |
JNL_Date | DWORD | In-game date stamp. |
JNL_Time | DWORD | In-game time stamp. |
Note
partytable quirks.
- The journal block is omitted entirely when the party journal is empty. A reader must treat a missing
JNL_Entriesas “no active quests”, not as malformed data.PT_TUT_WND_SHOWNis a GFFVOIDfield (an opaque byte blob), not an integer.PT_PAZAAKCARDShas a stowaway element: after the 18 INT card-count entries, the writer appends a 19th entry whosePT_PAZAAKCOUNTis a BYTE carrying the cheat-used flag, not a card count. The loader reads back only the first 18 (as INT) and ignores the rest, so that trailing byte never round-trips. Read 18 elements; ignore any trailing one. This is not a hidden store: the cheat flag’s real home is the top-levelPT_CHEAT_USEDfield, which does round-trip. The trailing byte is a dead write (aBYTEamong 18INTs, sourced from the cheat-flag field), most likely leftover code.
Implemented Linter Rules (Rakata-Lint)
None yet. Documented here ahead of any dedicated rakata-lint rules.