How large can a Tekken 4 stage be? Bigger than predicted
Four in-game tests of a memory model, one of which it got wrong
A desk model of Tekken 4’s stage memory predicted the game would fail once a stage’s main file passed about 7.6 MB. In PCSX2, stages of 6.0, 6.6, 7.4 and 7.7 MB all loaded and played: the game gave up its pose cache and then shrank a second buffer instead of failing. The same run confirmed the crowd budget and the start-region mechanism.
The first desk report on Tekken 4’s stages (Tekken 4’s stage format, and building a new stage from scratch) claimed about 7.8 MB of free space after a stage’s main file (j3). The adversarial verification refuted that: the memory right after the file is in live use. So how big can a custom stage be? A second desk pass modelled the memory that j3 shares and made predictions, and experiment E5 (2026-10-21) tested them in PCSX2.
Hypothesis
j3 is loaded at the base of a fixed region of 8,146,528 bytes. The space above it is a top-down “bump” allocator (descriptor at 0x1B3D6D8), whose floor is the end of j3. After loading, the game allocates from it, in order:
- A: a buffer sized by the stage’s content (514,592 bytes for the test stage);
- B: a scalable buffer, nominally 983,040 bytes;
- C: a pose cache for the 34 crowd figures, which takes whatever is left (it needs about 1.4 MB) and is skipped if almost nothing remains.
Nothing in the code checks j3’s size, so the model says a larger j3 squeezes these buffers from the top down.
Prediction
Written before the run:
| j3 size | Predicted effect |
|---|---|
| above 5,196,400 B | The pose cache starts to shrink |
| about 6,597,696 B | The pose cache is gone |
| above 6,648,880 B | Buffer B starts to shrink |
| about 7,631,440 B | Buffer B is disabled |
| above 7,631,936 B | Buffer A can’t be allocated: failure |
So the model predicted a hard wall at about 7.6 MB, with about 6.5 MB as the practical limit.
Control
The stock-size template stage: j3 of 5,145,424 bytes. The pose cache holds all 34 entries, buffer B is at full scale (0x1000), and 7–8 crowd figures are drawn.
Method
The test stage was rebuilt with j3 padded to about 6.0, 6.6, 7.4 and 7.7 MB. The exact byte sizes weren’t recorded. Each build was booted in PCSX2 by script, a Practice fight was started on the stage, and a savestate was taken during play. The pose-cache count and buffer B’s scale were read from that savestate’s memory, and the fight was checked to load and play normally. No one was at the controller (see Testing a PS2 game with no one at the controller).
Results
| j3 | Pose cache (of 34) | Buffer B scale | Fight |
|---|---|---|---|
| 5.1 MB (control) | 34 | 0x1000 | Normal |
| 6.0 MB | 18 | 0x1000 | Normal |
| 6.6 MB | 5 | 0x1000 | Normal |
| 7.4 MB | 0 | 0x646 | Normal |
| 7.7 MB | 0 | 0x164 | Normal, including a two-hit combo |
The first three rows behave as modelled: the cache drains first, then B begins to shrink.
The same run’s other tests
| Test | Change | Control | Result |
|---|---|---|---|
| Crowd budget | The stage’s limit-table entry at 0x2B13C0 set to A = 2, B = 1 | 7–8 crowd figures drawn | 0–1 drawn, while all 34 still exist. Confirmed: the table is a draw budget, not the playable-area limit the first report took it for |
| Start region | The initial start region forced to 1 in code (li v0, 1 at 0x1A7298) | Fighters spawn near the origin, around (−2244, −991) | They spawn at (12801, 5653). Confirmed: the region chosen there sets where the fight starts |
| Custom wall | A generated wall 1 m behind the fighter | Walking back for 5 s covers 2,006 mm | See Tekken 4 ignores a wall whose faces wind against their normal: ignored until its faces were rewound, then it stopped the fighter at 557 mm |
Verdict
- The arena model is refuted above 7.6 MB. A custom stage can be at least 7.7 MB.
- The crowd budget is confirmed.
- The start-region mechanism is confirmed, through a forced value; the variant byte itself wasn’t changed.
The evidence status is observed: each size ran once, in one mode, on one stage.
Threats to validity
- One boot per size. Nothing was repeated.
- Practice mode only. It loads j3 at a different address from versus modes (
0xAA1800rather than0xB17440), so its headroom may differ. - “Plays normally” is a coarse check. It means the fight loaded and accepted input, and a two-hit combo landed at 7.7 MB. Frame rate wasn’t measured, and losing the pose cache and most of buffer B probably costs something.
- Approximate sizes. The sizes are the recorded round figures, not exact byte counts.