Terrain profiles
The game defines 15 river bank shape profiles, each 16 bytes long (one byte per scanline within a terrain fragment). Each byte is the X offset for the left bank edge at that line. The right bank is computed as a mirror.
Profiles 1-2 have bit 7 set, which triggers special bridge/road rendering in render_terrain_fragment.
Profile Type Description
0 Normal Standard river section
1 Special Pre-bridge approach (bit 7 set)
2 Special Bridge structure (bit 7 set)
3 Normal Post-bridge transition
4-10 Normal Various river widths
11 Narrow River narrows significantly
12 Wide River widens significantly
13-14 Normal Additional variations
Profile data: data_terrain_profiles (240 bytes total).
Island shapes
36 island shape definitions, each 3 bytes. Islands appear as terrain features within the river, splitting it into channels.
Byte Contents
0 Profile index (0-14): selects shape from data_terrain_profiles
1 Width offset: shifts edge position
2 Edge mode: 0=direct, 1=mirror (right = 120 - left), 2=fixed-width (right = 60 + left)
Island data: data_islands (108 bytes total). Referenced from terrain fragment byte 3 (upper 6 bits = island index x 4). Initialized by handle_island.
Terrain fragments
Each of the 48 game levels (bridge sections) is defined by 64 terrain fragments, stored as 4 bytes each (256 bytes per level). Fragments are loaded sequentially by render_terrain_row as the terrain scrolls.
Byte Contents
0 Profile (0-14): index into terrain profiles at data_terrain_profiles. Values 1-3 mark bridge approach, bridge, and post-bridge
1-2 Row offset (16-bit): shifts bank position horizontally
3 Bits 0-1: edge mode. Bits 2-7: island index (divide by 4 for data_islands lookup)
Terrain data: level_terrains (48 levels x 256 bytes = 12,288 bytes).
Object spawn tables
Each level has 128 spawn slots (2 bytes each, 256 bytes per level) that define which objects appear at each scroll position. Read by spawn_objects_from_level_slot during scroll.
Byte Contents
0 Object definition: bits 0-2 = type (OBJECT_* constants), bit 3 = rock flag (SLOT_BIT_ROCK)
1 X position ($00 = empty slot, $01-$FF = spawn coordinate)
When the rock flag is set, bits 0-1 select rock variant (0-3). Most slots are empty (X = $00), making this a sparse encoding.
Object data: level_objects (48 levels x 256 bytes = 12,288 bytes).