PRK files use CRC-32 checksums extensively. An example of the algorithm can be found here. The process is much the same, except the checksums are not inverted in PRK files. The following function should be used instead of the crc function in that link.

    unsigned long prk_crc(unsigned char *buf, int len)
    {
        return update_crc(0xffffffffLU, buf, len);
    }

A PRK file consists of an X,Y position and X,Y length. These values may range from 0 up to and including 58. The largest park has X and Y positions of 0, and X and Y lengths of 58. For vertical position (referred to as a Z position in this document), the value 0 is used to indicate the default ground level, +15 is used to indicate the maximum position an object may be raised to, and -15 is used to indicate the minimum position an object may be lowered to. It has been my effort to make all positional values consistent with the values listed above.

This document uses a soft red colour to indicate unsigned values, a soft blue colour to indicate sections, a soft cyan colour to indicate two's complement values, a soft green colour to indicate zero-padded fixed-width ASCII strings, a soft yellow colour to indicate IEEE-754 values, gray to indicate padding or an unknown format, and a solid red colour to indicate undocumented sections. All arithmetic values are stored in the little-endian byte order, and bits are indexed in this document from their low-order bits to high-order bits. Unless otherwise specified, sections are padded with zeroes to their designated sizes. Ranges, of the form "bytes N to M" is intended to be read as "from and including byte N, up to but excluding byte M", whereas the form [N,M] is entirely inclusive.

An earlier analysis of the PRK file format is available here. It is my hope that the updates presented in this analysis help clear up a few of the unknowns in that forum post.

Save File Layout
Pre-made parks don't use this container. For those files, see Park Layout.
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 Checksum of bytes 0 to Padding offset (with this field zero-filled)
2
4 Checksum of Values
6
8 Size of Values
10
12 Padding offset
14
16 6
18
20 Values
...
+0 Park
...
+0 Padding (value=0x69) ...
... ... ...
35840
Save File Values
Type Description
18 Value is 0 with a size of 0 bytes.
16 Value in range [1,255] with a size of 1 byte.
17 Value in range [256,] with a size of 2 bytes.
13 Value is checksum with a size of 4 bytes.
3 Value is a null-terminated string of arbitrary length.
Layout
Type Identifier Value
16-18 num_edited_goals (0xe1ec606f) Goal Count
16-18 maxplayers (0xb7e39b53) Maximum Players
16-18 num_gaps (0xe6121ed0) Gap Count
16-18 num_pieces (0xfff3dc35) Object Count
16-18 theme (0x688a18f7) Theme
13 tod_script (0x4c72ed98) default (0x1ca1ff20)
0x90 0xef X Length
16-18 length (0xfe82614d) Y Length
3 filename (0xc3f4169a) Park Name
0
Park Layout
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 0xc
1 Checksum of "park_editor_map" (0x337c5289)
3
5 0x1 0xa6
7 0xe
8 Map
...
15008 0xa
15009 Checksum of "park_editor_goals" (0xd8eb825e)
15011
15013 0xc
15014 Checksum of "goals" (0x38dbe1d0)
15016
15018 Goal Data
...
+0 0xc
+1 Checksum of "createdrails" (0x244550a6)
+3
+5 Rails
...
+0 0x10
+1 Checksum of "maxplayers" (0xb7e39b53)
+3
+5 Maximum Players
Map Layout
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 Checksum of bytes 4 to 15000
2
4 Section Size (92 + 58*58 + ObjectCount*8 + GapCount*48)
6 0x24 0x4e
8 Theme
10
12 X Position Y Position
14 X Length Y Length
16 Object Count
18 Gap Count
20 Maximum Players
22
24
26
28 Park Name
...
92 Ground Height (x=0,y=0) Ground Height (x=0,y=1)
... ... ...
3456 Objects and Gaps
...
15000
Object Layout
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 Identifier X Position
2 Y Position
4 Rotation Vertical Position+16
6
Gap Layout
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 Side1: X Position Side2: X Position
2 Side 1: Vertical Position+16 Side 2: Vertical Position+16
4 Side 1: Y Position Side 2: Y Position
6 Side 1: Length Side 2: Length
8 Side 1: Rotation Side 2: Rotation
10 Gap Name
...
42 Score
44 Type
46
Rail Layout
If no rails are present, this section is two bytes: 0x00, 0x00
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 0xa
1 Rail Element Count
3 Rail Elements
...
Rail Element Layout
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 0xc
1 Checksum of "points" (0xd84571d6)
3
5 0xa
6 Point Count
8 Points
...
+0
Point Layout
If the point is without a visible post, bytes 17 to 26 aren't present.
Offset 0 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 6
1 Checksum of "pos" (0x7f261953)
3
5 X Position*120 - 3480
7
9 Z Position*48
11
13 Y Position*120 - 3480
15
17 0xd
18
20
22 Checksum of "haspost" (0xdcded772)
24
26