A stadium's collision is not in its model block. Each stadium directory holds a small separate collision file next to its models, and the ball, fielders and items test against it. Decoded from main.dol (US) and checked against every vanilla file, each of which parses to its last byte (2026-10-18). All values are big-endian. Nothing in the tools writes these files yet.
Two tables in main.dol have the same shape, {u16 dir, u16 file[3]} per stadium id, indexed by the time of day (variant 0, 1, 2): 0x806D99E0 names the collision file, 0x806D9980 the model file. Several variants can share one file.
| Id | Dir | Stadium | Model files (0/1/2) | Collision files (0/1/2) |
|---|---|---|---|---|
| 0 | 7 | Mario Stadium | 0/1/2 | 3/3/3 |
| 1 | 8 | Bowser Castle | 0/1/2 | 3/3/4 |
| 2 | 9 | Wario City | 0/1/0 | 2/2/2 |
| 3 | 10 | Yoshi Park | 0/1/2 | 3/3/4 |
| 4 | 11 | Peach Ice Garden | 0/1/2 | 3/3/3 |
| 5 | 12 | DK Jungle | 0/1/2 | 3/3/3 |
| 6 | 13 | Luigi's Mansion | 0/1/0 | 2/2/2 |
| 7 | 14 | Daisy Cruiser | 0/1/2 | 3/3/3 |
| 8 | 15 | Bowser Jr. Playroom | 0/1/2 | 3/3/4 |
| 9 | 16 | Toy Field | 0/1/0 | 2/2/2 |
The three "file 4" collisions are tiny flat arenas (one region, ±26 to 36 units wide), most likely the minigame fields of variant 2; not verified.
Loading. fn_804B8620 loads the file through fn_80398080 and keeps its handle in the stadium object (*(r13-0x148): +0 id, +4 variant, +6 model handle, +8/+0xC/+0x10 collision handles). The completion callback fn_804B8B60 stores the data pointer at *(r13-0x138) and runs the fix-up fn_8038FB38; fn_804B8BA0 frees it.
u16 regionCount N, u8 0x43, u8 relocated (0 in the file; the fix-up sets 1)
u32 offset[N+1] file-relative; the fix-up turns them into pointers
offset[0]: N boxes, 6 x f32 each: xmin ymin zmin xmax ymax zmax
offset[i], i = 1..N: region i's triangles, as a list of blocks:
u8 0, u8 kind, u16 count kind 1: a strip of count+2 vertices
kind 0: a list of count*3 vertices
vertex: f32 x, f32 y, f32 z, u16 attr, u16 0
... more blocks; a block header with count 0 ends the region
(x, -y, -z) of game space. The fix-up negates y and z of every box and vertex (and swaps the boxes' min and max for them). Game space is model space: y up, the outfield towards -z, the fence at the distance in the table at 0x80625770 (90 in Mario Stadium, 95 in Yoshi Park). So a collision coordinate is the model coordinate with y and z negated.fn_8038FCB0) first collects every region whose box the tested segment can touch (outcodes of both endpoints, fn_805A44D8), then tests those regions' triangles (fn_8038F774). Nothing else uses the split, so a new object can be a new region with its own box, or extra blocks in a region whose box already contains it.(v1-v0) x (v2-v0) faces; strips alternate as usual. The closest hit in [0, 1] along the segment wins. In vanilla data the ground faces up, and fences, foul poles and foul-area walls face the field.A triangle's attribute is the attr of its last vertex (strip vertex k+2, list vertex 3k+2); the first two vertices' values are unused. The query returns it (0 means no hit) with the hit point and normal. Its callers (about 47, among them ball flight fn_800B6184, a ground probe fn_800B71A4, fielders and items) read the low 7 bits as the surface type and bit 0x80 separately. Meanings from the data:
| Low 7 bits | Observed as | Where |
|---|---|---|
| 1 | Flat ground at y = 0 (grass, general field) | Every stadium |
| 6 | Flat ground at y ≤ 0.2 (infield dirt, mound) | Mario Stadium, Yoshi Park, Bowser Jr. Playroom variant |
| 2 | Vertical, 4-8 high at the fence distance (outfield fence) | Mario Stadium, Bowser Castle, Yoshi Park, DK Jungle, Daisy Cruiser, Bowser Jr. Playroom |
| 3 | Walls and stands beyond the fence, up to 24-36 high, mixed facing | Most stadiums |
| 4 | Vertical at the foul-pole corners (foul poles) | Mario Stadium, Yoshi Park, Wario City |
| 5 | Vertical wall pieces 4-8 high; the fence kind used instead of 2 | Peach Ice Garden, Wario City, Luigi's Mansion and others |
| 0xC | Low sloped ground near the fence | DK Jungle only |
| 0xD | Flat ground at a radius of about 106 (the deck beyond the fence?) | Daisy Cruiser only |
| bit 0x80 | Foul territory: set on every triangle whose centroid is outside the foul lines and on none inside | Every stadium |
One ball check (fn_8011688C) treats types 2, 3, 5, 7, 8 and 0xD alike (solid: the ball stops or bounces). Other checks look at 0xD, 0xB and the range 0x20-0x36, which no stadium file contains. The per-type physics (bounce, sound) are not traced; the fence distance table, not the collision, decides home runs.
*(r13-0x94), fn_804CEEE8).fn_805A3744, test in fn_8038FF20), so the collision follows the rocking ship.Query entry point for reference: fn_804B8424(stadium, p0, p1, outPoint, outNormal, low7Only, scaleZ, ...); the segment matrix comes from fn_8038F6C8, and the result keeps the attribute at +0x44 and the normal at +0x30.