Object DAT Files

Back to RCT home

Last Updated September 18, 2004

Many thanks go to Jonathon Wilson for determing much of the information on this page!

The visual items in RCT2 are stored in the g1.dat file in the data directory and as individual dat files in the objdata directory.

The dat files begin with a sixteen byte "DAT File Header". The first four bytes are flags. The next eight bytes are the ASCII characters of the file name (padded with trailing spaces as needed). The next four bytes are a checksum. The DAT File Header is followed by an encoded data chunk. It is the same type of encoding as described on the SV6/SC6 page. (The first byte specifies the type of encoding; the next four bytes are the size.) The remainder of the description here is based on the decoded file. This is a "work in progress"! I am using the following model for the Dat file structure:
DAT File Header
Object Header
String Table(s)
Group Info
Optional
Image Directory
Graphics Data

The first byte of the DAT File Header contains a flag to identify the type of dat file. Use the lower four bits to identify the type (0 through 0x0A) of the object. Every object has a DAT File Header, Object Header (different for each object type) and a String Table.

DAT File Header: The high nibble of the first byte of the Flags is used to determine if this is a standard (original=8, 1st expansion pack=1) or custom object (high nibble=0). Also, the lower four bits of the first byte determine the "Type" of the object as described below. The remainder of Flags can be ignored. The last byte of Flags is 0x00 for RCT2 custom files made with my editor, 0x09 for original RCT2 files, and 0x0C for RCT2 expansion pack files. Custom files made with other programs may have any value at this spot. I highly recommend using 0x00.

Flags : longword
filename : 8 bytes
checksum : longword

The Checksum is calculated by starting with the value 0xF369A75B. Read one byte at a time from the decoded file. Start with the first byte of the file, then skip the next three bytes. Then read the eight bytes of the Filename. Skip the four bytes of the checksum (you're calculating it now!). Then process each byte of the remainder of the (decoded) file.

Each byte is processed by XOR'ing it with the low byte of CheckSum. Then CheckSum is rotated left by eleven bits. (this was errantly listed as thirteen earlier)

Object
Type
Description Obj Header
Size
String Tables Group
Info
"Optional" Images

0

Ride/Shop 0x1C2 3 No variable size - It starts with a variable number of 3-byte structures. Start by reading the first byte after the string table. If that byte is 0xFF, then there are 32 structures. Otherwise, that byte is the value of how many 3-byte structures to read.

After these, there are four variable length structures. The first byte of each one indicates the length of that structure (not counting the first byte itself). However, if the first byte is 0xFF, use the next two bytes for the length (not counting the three bytes used to indicate length in this case).

These four structures specify the loading positions for peeps. There is a byte for each peep position on the ride. The upper and lower nibble specify the X/Y offsets. Some rides have more than one type of vehicle. For example, some rides have less seating in the first vehicle than in subsequent vehicles. Each structure specifies the loading for a vehicle subtype for the ride. For flat rides, the lower 5 bits of the sctructure length specify ? while the remaining upper bits specify ?

In the case of shops, there is a single 3-byte structure which contains three bytes of 0x00; while the four other structures are each of zero length.

Yes

1

Small Scenery 0x1C 1 Yes Animation Sequence - presence is conditional; determined by a flag in the Obj Header. Consists of a variable number of bytes to indicate the sequence of animation frames. A 0xFF indicates the end of the sequence. Objects such as gears have a simple up-count sequence. Objects such as the bat statues have an up/down sequence so the wings will spread open - then close smoothly. Some objects have a complicated sequence which involve partial up/down counts within the overall sequence. That allows the butterfly to open and close its wings partially as well as fully for a more interesting animation. Yes

2

large scenery 0x1A 1 Yes variable - first is a conditional block of 0x40E bytes if bit 3 of the Obj Header flag is set; this is for the "3D" letters for some of the sign objects in the game. Then, there are a variable number of 9-byte structures. Each structure represents a tile of the object. The structure contains the X, Y, base height and clearance height of the tile. There are also flags to indicate which quadrants are occupied and if walls can be built on the sides. The end of this sequence is signaled by a word of 0xFFFF. Yes

3

Walls 0x0E 1 Yes 0 Yes

4

Path Banners 0x0C 1 Yes 0 Yes

5

Paths 0x0E 1 No 0 Yes

6

Path additions (benches, etc) 0x0E 1 Yes 0 Yes

7

Scenery Group 0x10E 1 No variable size - names of assoc files in 16 byte structures:

Flag : 4 bytes
Name : 8 bytes
Checksum : 4 bytes

First byte of flag (0xFF indicates termination -no structure)

Yes

8

Park Entrance 0x08 1 No 0 Yes

9

Water 0x10 1 No 0 Yes

10

Scenario text 0x08 3 No 0 No

Object Header: Following the DAT File Header is a "Object Header" which is a different structure (and size) for each object type. Here are some Delphi definitions for some of the Object Headers and their flags:

TType1Header = packed record
{00} MsgRef        : word;     // zero
{02} Fill_1        : longword; // zero
{06} Flags         : longword; // zero
{0A} Height        : byte;
{0B} CursorSel     : byte;
{0C} BuildFee      : smallint;
{0E} RemoveFee     : smallint;
{10} GraphicsStart : longword; // zero in DAT files
{14} Anim1         : word;     // Delay between individual frames of animation - controls speed
{16} Anim2         : word;     // bits0..4: animation counter mask (ie. sequence length - 1)
                               // bit 5: 0=continuous animation (sequence length should be a power of 2)
                               // bit 5: 1=intermittent; bits 6 and up indicate interval length
{18} Anim3         : word;     // Length of animation sequence (limit to 0x80)
{1A} BaseIndex     : byte;     // zero in DAT files
{1B} Fill_2        : byte;     // zero in DAT files
end;

Flag Name Hex Value Description
T1_FULLSQUARE 00000001 Full square tile (else: a quarter tile object)
T1_OFFSET 00000002 Image vertical reference is based on the center of the tile (else: it is based on the top of the tile)
T1_FLAT 00000004 Must be on a flat surface. Also, walls can't occupy the same tile
T1_RARROW 00000008 Provide a rotation button in the scenery dialog
T1_ANIMATION 00000010 Animated object = multiple frames and animation sequence present
T1_GARDEN_DRAW 00000020 garden draw logic - three frames which progress over time without water (wither)
T1_GARDEN_UNK 00000040 garden draw logic - the frames can regress with water (allows handymen to water them)
T1_DRAW2DIALOG 00000080 Combine the first 2 frames when drawing the item in the scenery dialog
T1_SPACEA 00000100 Diagonal object - check T1_SPACEC
T1_GLASS 00000200 A "glass" object: the first image is the "frame" and the second image is the "glass"
T1_REMAP_1 00000400 Uses the first remappable color
T1_1SPRAY 00000800 Use fountain drawing logic = 2 frames: the first frame is stationary and the second is animated
T1_4SPRAY 00001000 Use fountain/4 drawing logic = the first frame is stationary; there are "back" and "front" animations (for 4 fountain sprays)
T1_CLOCK 00002000 Use clock drawing logic = the first frame is stationary; there are two animations (the hands of the clock - which are timed to real time)
T1_SWAMPGOO 00004000 Use the same image for all 4 views; plus animate 16 frames
T1_ANIMDATA 00008000 Has animation sequence data (a sequence after the "Group Info")
T1_DRAW2MAIN 00010000 This specifies that the object should use 2 frames instead of 1 for the object on the main game screen
T1_STACK 00020000 Can be stacked and/or placed on water (e.g. trees dont have this bit set)
T1_NOWALLS 00040000 Specifies that no walls may be built at the same location as this object (can be built below and above)
T1_REMAP_2 00080000 Uses the second remappable color
T1_NOSUPPORTS 00100000 No supports - useful for "building" components: walls/roofs, etc
T1_DIALOGFRAMES 00200000 First set of frames are only for the scenery dialog
T1_SMALL_COG 00400000 ? - only used for the small cogwheel
T1_UNKNOWN 00800000 ? - unknown
T1_SPACEB 01000000 Occupies half of a tile
T1_SPACEC 02000000 Occupies 3/4 of a tile - T1_SPACEA must be set also
T1_PAINT_SUPPORTS 04000000 Supports are painted with the first remappable color (else they are painted black)
T1_POLE 08000000 ? - only used for suppleg1.dat
T1_RESA 10000000 unused
T1_RESB 20000000 unused
T1_RESC 40000000 unused
T1_RESD 80000000 unused

TType2Header = packed record // Large Scenery : length = 1A
{00}reserved0 : word;        // Always zero in files
{02}reserved1 : longword;    // Always zero in files
{06}CursorSel : byte;
{07}flags     : byte;        // bit 3 = 3D sign
{08}BuildFee  : word;
{0A}RemoveFee : smallint;
{0C}reserved2 : longword;    // Always zero in files
{10}reserved3 : byte;        // Always zero in files
{11}Scrolling : byte;        // 0xFF if not scrolling, otherwise, indicates scrolling direction, location
{12}reserved4 : longword;    // Always zero in files
{16}reserved5 : longword;    // Always zero in files
end;
Flag Name Hex Value Description
T2_REMAP_1 01 uses first color selection
T2_REMAP_2 02 uses second color selection
T2_3DTEXT 04
T2_SCROLL 08 uses standard scrolling text technique
T2_PHOTOGENIC 10 guests appreciate the scenery object (and photograph it)
T2_UNUSED_1 20 unused
T2_UNUSED_2 40 unused
T2_UNUSED_3 80 unused

TType2TileSpec = packed record
  Row       : smallint; // div by 32
  Col       : smallint; // div by 32
  Z         : smallint; // div by 16
  Clearance : byte;     // div by 8
  Unknown1  : byte;     // bit 5 is set to indicate no supports
  Flags     : byte;     // upper nibble=tile occupation (F=full tile), lower nibble=walls (0=all sides)
end;


TType3Header = packed record // Walls : length = 14.
{00}reserved0 : word; // Always zero in files
{02}reserved1 : longword; // Always zero in files
{06}CursorSel : byte; //
{07}Flags     : byte;
{08}Clearance : byte; //
{09}Effects   : byte; // first nibble = visibility (0 = opaque), upper nibble: 1 = animated (8 frames)
{0A}BuildFee  : word; // X 10.
{0C}reserved2 : byte; // Always zero in files
{0D}Scrolling : byte; // 0xFF if not scrolling
end;

Flag Name Hex Value Description
T3_REMAP_1 01 uses first color selection
T3_GLASS 02 combine two frames
T3_FLAT 04 if set, cannot be built on sloped land
T3_TWOSIDES 08 has a front and a back
T3_DOOR 10 special processing for doorways (36 images)
T3_UNUSED 20 unused
T3_REMAP_2 40 uses second color selection
T3_REMAP_3 80 uses third color selection

TType4Header = packed record // Banners : length = 12.
{00}reserved0 : word;     // always zero
{02}reserved1 : longword; // always zero
{06}Scrolling : byte;     // 0xFF if not scrolling, otherwise, indicates scrolling direction, location
{07}Flags : byte;
{08}BuildFee : word;      // X 10. refund is 75% (rounded down)
{0A}reserved2 : word;     // always zero
end;

Flag Name Hex Value Description
T4_REMAP_1 01 uses first color selection

TType6Header = packed record // Path Additions : length = 14.
{00}reserved0 : word;     // Always zero in files
{02}reserved1 : longword; // Always zero in files
{06}Flags : word;
{08}Subtype : byte;
{09}CursorSel : byte;
{0A}BuildFee : word;      // X 10.
{0C}reserved2 : byte;     // Always zero in files
{0D}unknown1 : byte;      // Always zero in files
end;

Flag Name Hex Value Description
T6_HOLDTRASH 0001 has an extra static frame
T6_CANSIT 0002
T6_CANVANDAL 0004 has second static frame
T6_LIGHT 0008
T6_JUMPFOUNTAIN 0010
T6_JUMPSNOWBALL 0020
T6_UNKNOWN1 0040 set for benches and jumping fountains/snowballs and Litter bins
T6_UNKNOWN2 0080 set for benches and jumping fountains/snowballs
T6_QLINETV 0100

Subtypes:

0 = Lamp (edge centered, 1 dialog view, 2 frames of static (normal and vandalized)

1 = Litter bin (edge centered/inset, 1 dialog view, 3 frames of static (normal and vandalized, and full)

2 = Bench (edge centered/inset, 1 dialog view, 2 frames of static (normal and vandalized)

3 = Jump fountain (corners, 1 dialog view, 1 frame of static)


String Table(s): Folowing the Object Header is a string table containing text in different languages.Each string begins with a byte to specify the language.
Code Language 1st Expansion pack
0 British English English
1 American English (not used)
2 French French
3 German German
4 Spanish Spanish
5 Italian Italian
6 Dutch Dutch
7 Swedish Swedish
9 Korean? (not used)
10 Chinese Chinese
11 Chinese (not used)
13 Portugese (not used)

The string immediately follows that byte and is null terminated. An 0xFF for the Language code indicates the end of the strings. Type 0 and 10 objects have three string tables; other types have one string table.

Group Info: a sixteen byte structure. There is a four byte value. This is followed by an eight byte string indicating which scenery group file this item belongs to (if any). That is followed by a 4-byte value.

Flag : longword (first byte is 0xFF if default item - 87 for official groups, 07 for custom groups)
FileName : 8 bytes
Checksum: longword = 0

Image directory: First is a 4-byte value which specifies how many images are in the file. Then a 4-byte value which specifies the length of the scan line graphic data (starting after the image directory). Then there is a sixteen byte entry for each image. It uses the same format as the csg1i.dat file of RCT1.

TGraphicRecord = record
StartAddress : longword;
Width, Height, Xoffset, Yoffset : smallint; // signed two byte variables
Flags : word;
unused : word // to pad the structure to 16 bytes
end;

StartAddress points to the start of the scan line index in the file. It is an offset rather than an absolute address - the first scan line index has a StartAddress of 00000000.