Tekken 4’s stage format, and building a new stage from scratch
Geometry, floors, walls, crowds and start positions, decoded far enough to add stage 17
Each Tekken 4 (PS2) stage is four archive files, and the biggest is a 15-section container holding the geometry, textures, floor, walls, crowd and start positions. The geometry and wall formats rebuild the stock stages byte for byte, and a new stage 17, with its own geometry, textures, props and collision, loads and plays in PCSX2.
Tekken 4 has 17 fight stages, and the game reserves table space for 26. This entry describes how a stage is stored, how that was confirmed, and what it took to add a stage 17 with its own geometry rather than a retexture of an existing one. The limits of the format (how big a stage can be, how the crowd is budgeted) are covered by the experiments in How large can a Tekken 4 stage be? Bigger than predicted.
Four files per stage
Stage n is archive records 991 + 4n to 994 + 4n (see Tekken 4’s 2.57 GB archive keeps its index in the executable for the archive):
| File | Holds | Loaded to |
|---|---|---|
| j0 | The stage’s sound bank | Sound RAM at 0x12B090 (at most 213,120 bytes) |
| j1 | Character Data for non-player figures (the crowd) | A 64 KB window |
| j2 | Their motion banks | A 256 KB window |
| j3 | The stage itself: a 15-section container | 0xB17440 in versus modes (an address hard-coded in three places), 0xAA1800 in Practice |
Stages 0–16 are populated. Records for 17–25 exist with size zero.
The crowd files turned out to reuse the moveset format. All 77 Character Data files across the stock stages parse and rebuild byte-identical with the same tool used for fighters (Tekken 4’s moveset files, decoded and edited in game), so the crowd are fighters that never fight.
The j3 container
j3 starts with a count (15) and fifteen (offset, size) pairs:
| Section | Holds |
|---|---|
| 0, 1 | Crowd models and textures |
| 2 | Lighting |
| 3 | The camera’s collision outline (optional, empty on 12 of 17 stages) |
| 4, 5, 6 | Placement lists: the crowd and locators, hittable objects, and fighter start regions |
| 7 | Texture banks |
| 8 | Geometry (MAPTK4) |
| 9 | Fighter walls |
| 10 | The floor (UNDNEW) |
| 11 | A stub |
| 12 | A packed motion-bank container, role unknown |
| 13, 14 | Empty |
Geometry
The geometry section holds two models: a sky dome (2 nodes, 394 vertices) and the stage. The street stage used as the template has 922 nodes, 9,322 triangle strips, 47,598 vertices and 28,954 triangles.
- Coordinates. Millimetres, with Y up. The floor is at y = 0 and the fight starts at the origin.
- Nodes (160 bytes each). A bounding sphere, a 4×4 matrix that is not applied (vertices are already in world space), and 80 bytes of flags and ids.
- Batches. Each is a GIF register block followed by a VIF stream of colours (8-bit), texture coordinates, normals and positions.
The format was confirmed three ways:
- The exported mesh’s counts match the header counts exactly.
- Both models rebuild byte-identical from the parsed form.
- An adversarial verifier re-derived the counts independently.
The rendering rules came from building, not reading:
- One trailer entry per batch. Each chunk ends with a trailer that needs one entry per batch. A single entry for a whole node drew only its first strip.
- Back-face culling. The renderer culls, so the first triangle of each strip must wind so that
(v1 − v0) × (v2 − v0)points along the face normal. - Material mode at header
+0x28. Mode 0 uses the vertex texture coordinates. Mode 7 is a reflection map computed from the view-space normal, which ignores texture coordinates entirely; doubling them changed no pixel. The template stage carried mode 7, which is why the first custom geometry came out wrong. - Lighting. Header
+0x2C= 0 leaves geometry unlit, and lighting uses the vertex normals. - The view is mirrored. Looking north, +x is on the left of the screen.
Walls and floor
Walls (section 9) use a format the notes call MHO:
- A 0x98-byte header and a table of 0x60-byte objects: a root, floor tiles, walls and solids.
- Then a grid of cells, each listing the objects it touches.
- Each face is four corners from y = −5000 to +5000 plus a horizontal normal.
- The grid size is stored in each file. It ranges from 5×5 to 32×16 cells, with cells 2 to 7 metres across.
The project’s wall writer rebuilds all 17 stock fight-stage wall files byte-identical. Generated with a 400 mm margin, its cell lists miss none of the 7,106 cell references in Namco’s own.
One rule only showed up in game: a wall whose faces wind against their normal is ignored. That has its own entry, Tekken 4 ignores a wall whose faces wind against their normal.
The floor (section 10) is seven lists of surfaces, sorted by flag bits. Type 5 is a plain floor and works in game; the template street’s pavement sits 294 mm above the road. The roles of the other flags are inferred, not tested.
Start positions, variants and the crowd
- Stage number. It comes from a global at
0x357D5C, not from the setup structure the first report named. - Variant. A variant byte (random in arcade mode) picks the stage’s select card and the fighters’ initial start region. The game then re-picks the region nearest the fighters. The first report said the variant also picked lighting or time of day; it doesn’t.
- The limit table at
0x2B12B0is a crowd budget: how many crowd figures are drawn, plus distance-fade limits. The first report read it as playable-area limits. The in-game test that settled it is in How large can a Tekken 4 stage be? Bigger than predicted.
Adding stage 17
A new stage needs table entries as well as files:
- an entry in the stage table at
0x2BC390(26 slots); - a select card (the card table is clamped to 17 entries);
- an arcade-mode slot (seven round lists at
0x30F2D0); - a music id;
- a crowd budget.
The select-card pictures live in one file that can’t grow: one extra picture blanks the select screen. So stage 17 reuses existing card pictures with a new label.
The stage was then built in stages, each proven in game before the next:
- A lift test (2026-10-20). One node of the template stage was raised 400 mm. It floated at knee height and the fighters’ legs passed through it: geometry edits load with no checksum or bounds trouble.
- Own geometry and textures (2026-10-21). Street, pavement, building fronts and pillars generated from scratch, rendering with seven new textures.
- A real layout. A small-town post office and its surroundings, with sky, lighting, and props that are wall solids, so the fighters collide with them.
Textures needed the most care. The stage’s texture section is a sequence of GS uploads, and the game rebases their addresses by 0x2668 blocks. Rebuilding the uploads in a new arrangement (“repack”) hangs the stage load: a black screen, no music, frozen fighters. Bisecting showed the new images themselves are fine. Keeping the stock upload count and sizes and writing new pictures into the existing slots (“in place”) works. Why the repack hangs is still open.
Corrections
The adversarial verification and the build overturned several readings in the first report:
- The wall grid isn’t a fixed 16×16 of 3 m cells covering a “48 m window”. It’s set per file.
- The longest strip isn’t 50 vertices. That was the builder’s own cap; stock strips reach 60.
- The sound and crowd files are separate buffers, not slots inside j3.
- The crowd list is section 4, not section 6. Section 6 is the fighter start regions.
- “7.8 MB of headroom” after the stage file was wrong. The space right after it is live data. How big a stage can really be is the subject of How large can a Tekken 4 stage be? Bigger than predicted.
- Stages 2 and 5 do upload textures. The original count was a script error.