Overview
Data for overworld background graphics begins at 1890000. Offsets 1890018-89153F are the pointer table. There are 0x2A5 (1890008-189000B) pairs of pointers. The first in a pair is the component's debug name (1891540-1892C6F). The second points to the beginning of the component's data. There are 4 types of components- palettes, tiles, chunk assembly, and image assembly.
Component usage
The types of components used for each graphic fall into 4 main groups:
Group 0- The basic group. It has a palette, tile/chunk data, and image assembly.
Group 1- Graphics with an excerpt. It has a palette, excerpt data, tile/chunk data, and image assembly. Examples include Rub-a-Dub River, Hill of the Ancients, and town areas.
Groups 2 and 3- Group 0 graphics with an overlay of group 0 or 1, respectively. They have a palette, data for their overlay, tile/chunk data, and image assembly. Examples include underwater friend areas and Luminous Cave.
Dream World/Dream Eater, the Aged Chambers, Crater, and the team base are special cases. Dream World and Dream Eater share tile/chunk and image assembly data but have different palettes. The Aged Chambers share tile/chunk data but have different image assembly data and palettes. Crater is group 2, but with a group 1 base layer. The team base is a series of type 1 graphics, each with multiple excerpts. The graphic used is determined by the player's type and construction progress while the excerpts used are determined by the player's species. Details are unknown.
Palettes
Offset
Length
Type
Name
Description
0x00
2
uint16
palcount
The number of palettes
0x02
2
uint16
unk1
0x04
palcount*60
RGBX
colortbl
A series of 16-color palettes
*Many graphics have several palettes that are identical but shifted over. This is likely to swap out palettes in order to animate tiles that change color but don't move.
Tile/chunk data
Graphics are broken into chunks, which are further broken into 8x8-pixel tiles. Each tile in a chunk and each chunk in a graphic is arranged in left-to-right rows going top-to-bottom.
Offset
Length
Type
Name
Description
0x00
2
uint16
chunkw
The chunk width, in tiles
0x02
2
uint16
chunkh
The chunk height, in tiles
0x04
2
uint16
tilecount
The number of tiles defined
0x06
8
byte?
unk3-10
0x0E
2
uint16
chkcount
The number of chunks defined
0x10
tilecount*32
tiledata
varies
chnkcount*2*chnkrows*chnkcols
chnkdata
varies
0-3
Padding to realign with 4-divisible offsets
Block data is 4bpp linear in reverse order. Some animated sections of a graphic are placed before the header of the main tile data. These include flowers and lily pads seen in town, the sun at Hill of the Ancients, and the water wheel at Rub-a-Dub River. They have their own header consisting of 2 shorts representing the excerpt's width and height in tiles followed by what is likely a series of integers representing the duration of each frame. What determines frame count is unknown.
Chunk data
In the chunk data, each tile gets 2 little-endian bytes. This table is listed from the lsb (first byte).
Offset
Bits
Description
0x00
10
Tile index*
0x0A
1
Flip the tile horizontally
0x0B
1
Flip the tile vertically
0x0C
4
Palette index
*Tiles are assigned consecutive indices based on their order in data. The first index is usually 1. However, in fully animated graphics and the aforementioned animated excerpts, the first index appears to vary. For excerpts, the indices continue where the main part ended.
Fully animated graphics such as attack animations precede the tiling data of each frame with an unidentified integer followed by a 16-byte header identical to the block data header (which is omitted from its typical location).
Image assembly
The data that encodes chunk order is preceded by a 12-byte header.
Offset
Length
Type
Name
Description
0x00
1
byte
camx
The horizontal position of the camera
0x01
1
byte
camy
The vertical position of the camera
0x02
1
byte
chunkw
The width of chunks, in tiles, redundant?
0x03
1
byte
chunkh
The height of chunks, in tiles, redundant?
0x04
1
byte
imgwidth
The width the image, in chunks
0x05
1
byte
imgheight
The height of the image, in chunks
0x06
6
uint16
unk10-12
boolean?
The each row has a series of Pair-24 NRL compressed values, one for each chunk column (rounded up to the nearest even number). These vaues are xor'ed with the respective indices of the previous row to get the actual indices of the chunks in the current row. The first row assumes all previous indices were 0.
This section works differently for the backgrounds of rest stops and boss rooms. It is believed it codes for mobility types instead. Locations of actual image assembly data in these cases is unknown.
Unknown data follows. It is likely NRL compressed and believed to code collision.