This version (2021/11/08 23:20) is a draft.
Approvals: 0/1
The Previously approved version (2020/05/19 12:37) is available.Diff

Scripting in TR2/TR3 for PC/PSX

Overview

The internal gameflow, which levels come in what order, what item(s) Lara has at the beginning of each level, the filenames of the level and cut-scene files, all the visible text (e.g. “Save Game,” “Rusty Key,” etc.), and various other options are controlled by a script file called TOMBPC.DAT/TOMBPSX.DAT. The scripts were compiled using a utility known as GAMEFLOW.EXE which was distributed by Eidos in the German release of Tomb Raider II Gold. Both TR2 and TR3 use these script files. From both games the format remained unchanged. TR1’s gameflow is hardcoded thus there is no external file controlling this resulting in loss of flexibility.

uint32_t Version;             // The Script Version (Always 3 for TR2/3)
uint8_t Description[256];     // Null-terminated string describing the script copyright info etc. Not encrypted.
uint16_t GameflowSize;        // Size in bytes of the game flow data, always 128 bytes
int32_t FirstOption;          // What to do when the game starts
int32_t TitleReplace;         // What to do when ExitToTitle is requested and "TitleDisabled" flag is set
int32_t OnDeathDemoMode;      // What to do when Lara dies during the demo mode
int32_t OnDeathInGame;        // What to do when Lara dies during the game
uint32_t DemoTime;            // Time in game ticks (1/30th of a second) to wait before starting a demo
int32_t OnDemoInterrupt;      // What to do when the demo mode is interrupted
int32_t OnDemoEnd;            // What to do when the demo mode ends
uint8_t Unknown1[36];         // Filler
uint16_t NumLevels;           // Number of levels in the game, including the training level, not including the title level.
uint16_t NumChapterScreens;   // Chapter screens (Present in TR2, first used in TR3)
uint16_t NumTitles;           // Number of title elements (TITLE.TR2 level + the legal/title pictures in *.PCX format)
uint16_t NumFMVs;             // Number of FMV cutscenes PC - (*.RPL), PSX - (*.STR)
uint16_t NumCutscenes;        // Number of in-game (engine-rendered) cutscenes (CUT*.TR2)
uint16_t NumDemoLevels;       // Number of demo levels
uint16_t TitleSoundID;        // ID of title soundtrack (see below)
uint16_t SingleLevel;         // If doing only a single level, the level ID (starting at 1). -1 means disabled.
uint8_t Unknown2[32];         // Filler
uint16_t Flags;               // Various flags, see below
uint8_t Unknown3[6];          // Filler
uint8_t XORKey;               // Key used to encrypt/decrypt strings
uint8_t LanguageID;           // Script Language ID, see below
uint16_t SecretSoundID;       // ID of soundtrack to play when a secret is found (see below)
uint8_t Unknown4[4];          // Filler
 
// If Flags & UseXor true each character (except null-terminator) must be ^ XORKey to decrypt the string.
 
TPCStringArray[NumLevels] LevelStrings;                  // level name strings
TPCStringArray[NumChapterScreens] ChapterScreenStrings;  // chapter screen strings
TPCStringArray[NumTitles] TitleStrings;                  // title strings
TPCStringArray[NumFMVs] FMVStrings;                      // FMV path strings
TPCStringArray[NumLevels] LevelPathStrings;              // level path strings
TPCStringArray[NumCutscenes] CutscenePathStrings;        // cutscene path strings
 
uint16_t SequenceOffsets[NumLevels + 1];                 // Relative offset to sequence info (the +1 is because the first one is the FrontEnd sequence, for when the game starts)
uint16_t SequenceNumBytes;                               // Size of SequenceOffsets in bytes
uint16_t[] Sequences[NumLevels + 1];                     // Sequence info see explanation below (SIZE is dependant on first opcode)
 
uint16_t DemoLevelIDs[NumDemoLevels];
 
#if PSX
    PSXFMVInfo[NumFMVs];
#endif
 
uint16_t NumGameStrings;
TPCStringArray[NumGameStrings] GameStrings;
 
#if PSX
    TPCStringArray[size] PSXStrings; // size is 79 for the TR2 beta, 80 for all other versions
#else
    TPCStringArray[41] PCStrings;
#endif
 
TPCStringArray[NumLevels] PuzzleStrings[4];
#if PSX && TR2_BETA
    TPCStringArray[NumLevels] SecretsStrings[4];
    TPCStringArray[NumLevels] SpecialStrings[2];
#endif
TPCStringArray[NumLevels] PickupStrings[2];
TPCStringArray[NumLevels] KeyStrings[4];

String arrays

struct TPCStringArray // (variable length)
{
    uint16_t Offsets[Count]; // List containing for each string an offset in the Data block (Count * 2 bytes)
    uint16_t TotalSize; // Total size, in bytes (2 bytes)
    uint8_t Data[TotalSize]; // Strings block, usually encrypted (XOR-ed with XORKey, see above)
}

In non-English versions of TR2-3, accented characters are written using “escape” characters so that everything can be written in standard ASCII, here are the 4 escape characters:
Accent Code becomes
Acute )e é
Circumflex (e ê
Grave $e è
Diaeresis ~e ë

The following non-ASCII characters are also replaced:

Character becomes
Eszett (German) ß =

There are also some exceptions (strings that were badly encoded by Core):

String becomes
Red)marrer un niveau
(“e” missing after parenthesis, )e implied)
Redémarrer un niveau

PSX FMV Info

struct PSXFMVInfo // 8 bytes
{
    uint32_t Start;     // Start frame
    uint32_t End;       // End frame
};

This specific info is exclusive to TOMBPSX.DAT.

Script Flags

Bit Hex Name Description
0 0x01 DemoVersion Indicates that the game is a demo distribution.
1 0x02 TitleDisabled Indicates that the game has no Title Screen.
2 0x04 CheatModeCheckDisabled Indicates that the game does not look for the cheat sequence keystrokes and events.
3 0x08 NoInputTimeout Indicates that the game waits forever if there is no input (won’t enter demo mode).
4 0x10 LoadSaveDisabled Indicates that the game does not allow save games.
5 0x20 ScreenSizingDisabled Indicates that the game does not allow screen resizing (with the function keys).
6 0x40 LockoutOptionRing Indicates that the user has no access to the Option Ring while playing the game.
7 0x80 DozyCheatEnabled Indicates that the game has the DOZY cheat enabled (flag only set in the final build of TR2 on PSX, but has no effect in-game).
8 0x100 UseXor Indicates that a cypher byte was used to encrypt the strings in the script file, and is stored in the XorKey field.
9 0x200 GymEnabled Is Gym available on title screen.
10 0x400 SelectAnyLevel Enables level select when New Game is selected.
11 0x800 EnableCheatCode It apparently has no effect on the PC game.

Script Language

  • 0 — English
  • 1 — French
  • 2 — German
  • 3 — American
  • 4 — Japanese

TR3 only:

  • 5 — Italian
  • 6 — Spanish

Script Sequencing & Opcodes/Operands

Each script has “sequence information”, Opcodes and Operands are all stored as uint16_t. Sequences contain a set of commands to execute where an additional value (operand) is usually passed as a parameter to the function the command needs to call.

If a level is a demo level, its level ID will be 1024 higher than a normal level ID.

Script Opcodes

ID Name Description Operand
0 Picture Unused. On PC, crashes if used and file missing. Otherwise, no action. Crashes under TR3 (PC). Picture ID
1 ListStart Define the start and the end of a list of commands which will be cut short if the user presses a key/button.
2 ListEnd
3 FMV Display Full Motion Video. FMV ID
4 Level Start a playable level. Level ID
5 Cine Display cut scene sequence. Cutscene ID
6 Complete Display level-completion statistics panel.
7 Demo Display demo sequence. Demo level ID
8 JumpToSequence Jump to another sequence. Sequence ID
9 End Close script sequence.
10 Track Play Soundtrack (it precedes opcodes of associated levels). Track ID
11 Sunset Gradually dim all lights in rooms with LightMode set to sunset (3). Used in Bartoli's Hideout.
12 LoadPic TR2 onlyTR3 onlyShow chapter screen on TR2 (PSX only ) and TR3. On TR2 PC, it's hardcoded to do nothing. Picture ID
13 DeadlyWater Not used anywhere in the game code. Used in Temple of Xian. Maybe not-implemented ancestor of TR3 Death_by_Drowning ?
14 RemoveWeapons Lara starts the level with no weapons.
15 GameComplete End of game, show the final statistics and start the credits sequence.
16 CutAngle Match the North-South orientation of the Room Editor and the North-South orientation of the 3D animated characters from a CAD application. Horizontal rotation ($\text{angle in degrees} \cdot 65536 / 360$)
17 NoFloor Lara dies when her feet reach the given depth. If falling, 4 to 5 extra blocks are added to Depth. Depth ($\text{blocks} \times 1024$), relative to where Lara starts the level
18 StartInv / Bonus Give item to lara at level-start (StartInv ) or at all-secrets-found (Bonus). Item ID
19 StartAnim Lara starts the level with the given animation. Animation ID
20 Secrets If zero, the level does not account for secrets. Non-zero value means the level must be accounted for secrets.
21 KillToComplete Kill all enemies to finish the level.
22 RemoveAmmo Lara starts the level without ammunition or medi packs.

The correct way to parse a sequence is to first read a uint16_t opcode specifying what this command within the sequence does. In reference to the list above, certain commands MUST have an additional uint16_t read from the sequence data directly after the opcode that’s the pairing operand to this opcode. Not all opcodes have an operand so this must be done correctly. The original games execute each sequence command 1 by 1 until it reaches End (9), where it then runs the next sequence.

Opcode-18 StartInv and Bonus

(repeat means give another)

By default, the item is given at level start (StartInv). Adding 1000 to the item ID means it will be given when all secrets are found (Bonus).

ID Tomb Raider 2 Tomb Raider 3
0 Pistols
1 Shotgun
2 Automatic pistols Desert Eagle
3 Uzis
4 Harpoon gun
5 M-16 MP5
6 Grenade launcher Rocket launcher
7 Pistol clip (no effect, infinite by default) Grenade launcher
8 Shotgun-shell box (adds 2 shells) Pistol clip (no effect, infinite by default)
9 Automatic-pistol clip (adds 2 shells) Shotgun-shell box (adds 2 shells)
10 Uzi clip (adds 2 shells) Desert eagle clip (adds 5 shells)
11 Harpoon bundle (adds 2 harpoons) Uzi clip (adds 2 shells)
12 M-16 clip (add 2 shells) Harpoon bundle (adds 2 harpoons)
13 Grenade pack (adds 1 grenade) MP5 clip (add 2 shells)
14 Flare box (adds 1 flare) Rocket pack (adds 1 rocket)
15 Small medipack (adds 1 pack) Grenade pack (adds 1 grenade)
16 Big medipack (adds 1 pack) Flare box (adds 1 flare)
17 Pickup 1 Small medipack (adds 1 pack)
18 Pickup 2 Big medipack (adds 1 pack)
19 Puzzle 1 Pickup 1
20 Puzzle 2 Pickup 2
21 Puzzle 3 Puzzle 1
22 Puzzle 4 Puzzle 2
23 Key 1 Puzzle 3
24 Key 2 Puzzle 4
25 Key 3 Key 1
26 Key 4 Key 2
27 / Key 3
28 / Key 4
29 / Save crystal

Tomb Raider 2 Identifications

TR2 only information here. These lists are virtually colored blue.

FMV IDs

  • 0 — LOGO (everybody’s corporate logos)
  • 1 — ANCIENT (monks vs. dragon)
  • 2 — MODERN (Lara drops in from helicopter)
  • 3 — LANDING (Seaplane lands at rig)
  • 4 — MS (Lara hitchhikes on a minisub)
  • 5 — CRASH (Lara goes to Tibet and has a rough landing there)
  • 6 — JEEP (Lara steals it and outruns Bartoli’s goons)
  • 7 — END (Lara escaping the collapsing lair)

Cutscene IDs

  • 0 — CUT1 (At the end of the Great Wall)
  • 1 — CUT2 (Lara the stowaway)
  • 2 — CUT3 (Bartoli vs. goon)
  • 3 — CUT4 (Bartoli stabs himself)

Soundtrack IDs

  • 002 – Cutscene Gates
  • 003 – Cutscene Gates
  • 004 – Cutscene Plane
  • 005 – Cutscene Monk
  • 006 – Home block begin
  • 007
  • 008
  • 009
  • 010
  • 011
  • 012
  • 013
  • 014
  • 015
  • 016
  • 017
  • 018
  • 019
  • 020
  • 021
  • 022
  • 023
  • 024
  • 025
  • 026 – Lara shower (Endgame)
  • 027 – Lara shower (Endgame)
  • 028 – Dragon death
  • 029 – Home - addon
  • 030 – Cutscene Bartoli stab
  • 031 – Caves ambience
  • 032 – Water ambience
  • 033 – Wind ambience
  • 034 – Pulse ambience
  • 035 – Danger 1
  • 036 – Danger 2
  • 037 – Danger 3
  • 038 – Sacred
  • 039 – Awe
  • 040 – Venice Violins
  • 041 – End level
  • 042 – Mystical
  • 043 – Revelation
  • 044 – Careful
  • 045 – Guitar TR
  • 046 – Drama
  • 047 – Secret theme
  • 048 – It's coming!
  • 049 – It's coming 2!
  • 050 – Warning!
  • 051 – Warning 2!
  • 052 – Techno TR
  • 053 – Percussion
  • 054 – Pads
  • 055 – Super-revelation
  • 056 – Hmm…
  • 057 – Long way up
  • 058 – Industrial ambience
  • 059 – Spooky ambience
  • 060 – Barkhang theme
  • 061 – Super-revelation short
  • 062 – Monk beaten
  • 063 – Home sweet home
  • 064 – Main theme
  • 065 – Dummy track

Tomb Raider 3 Identifications

Level IDs

  • 0 – Lara's House (house.TR2)
  • 1 — Jungle (jungle.TR2)
  • 2 — Temple Ruins (temple.TR2)
  • 3 — The River Ganges (quadchas.TR2)
  • 4 — Caves Of Kaliya (tonyboss.TR2)
  • 5 — Coastal Village (shore.TR2)
  • 6 — Crash Site (crash.TR2)
  • 7 — Madubu Gorge (rapids.TR2)
  • 8 — Temple Of Puna (triboss.TR2)
  • 9 — Thames Wharf (roofs.TR2)
  • 10 — Aldwych (sewer.TR2)
  • 11 — Lud's Gate (tower.TR2)
  • 12 — City (office.TR2)
  • 13 — Nevada Desert (nevada.TR2)
  • 14 — High Security Compound (compound.TR2)
  • 15 — Area 51 (area51.TR2)
  • 16 — Antarctica (antarc.TR2)
  • 17 — RX-Tech Mines (mines.TR2)
  • 18 — Lost City Of Tinnos (city.TR2)
  • 19 — Meteorite Cavern (chamber.TR2)
  • 20 — All Hallows (stpaul.TR2)

FMV IDs

  • 0 — LOGO (everybody’s corporate logos)
  • 1 — INTR (“The Meteorite”)
  • 2 — SAIL (Lara meets Willard, after the India levels)
  • 3 — CRSH (Plane crash, before the Antartica levels)
  • 4 — ENDGAME

Cutscene IDs

  • 0 — CUT6 (Lara at Tony's camp)
  • 1 — CUT9 (Lara meets Tony again)
  • 2 — CUT1 (Lara Meets Amputated Mercenary)
  • 3 — CUT4 (Lara confronts tribesman about artifact)
  • 4 — CUT2 (Saved by the Bell)
  • 5 — CUT5 (Lara meets the leader of the Damned)
  • 6 — CUT11 (Lara meets Sophia Leigh)
  • 7 — CUT7 (Lara Drives Over Fence)
  • 8 — CUT8 (Lara the stowaway in a delivery truck)
  • 9 — CUT3 (Lara gets the artifacts to Willard)
  • 10 — CUT12 (Lara watches Willard transform)

Other Script Commands

FirstOption, TitleReplace, OnDeathDemoMode, OnDeathInGame, OnDemoInterrupt and OnDemoEnd can also be setup to perform specific actions. For example, OnDeathInGame will be set to “0x500” which loads the title screen when Lara dies in-game.

NameCodeOperandDescription
Level 0x00000000 LevelLoad specified level (0 means Lara's Home (or do nothing, if in a demo), 1 means first level (Great Wall or Jungle), 2 means second level)
SavedGame0x00000100 Number between in [0, 15]Load specified savegame file (load file savegame.N where N is the operand)
Cutscene0x00000200 Cutscene IDPlay specified cutscene
FMV0x00000300 FMV IDPlay specified FMV
Demo 0x00000400 NoneLoad a random demo level
ExitToTitle 0x00000500 Exit to Title Screen (or do action specified in TitleReplace if TitleDisabled flag is set)
ExitGame 0x00000700 Exit the game
(anything else) Exit the game

Commands with operand are used like this: if you want to load the 2nd level, then you are going to do 0x000 (Level) + 2 which gives 0x003.

In the original TOMBPC.DAT/TOMBPSX.DAT files, the value 0xFFFFFFFF is often used by Core in fields to denotate that it should not happen. For example, in the standard (not demo) games' scripts, the TitleReplace field contains the value 0xFFFFFFFF (which, as mentioned before, will crash-exit the game quietly) because this field should never be used, as the TitleDisabled flag should never be set in standard games.
trs/scripting_tr2_tr3.txt · Last modified: 2021/11/08 23:20 by zdimension
Back to top
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0