Compiled Lua chunks (.lua)¶
Verified against: SLUS_212.15 (NTSC-U, SHA1 e9cb2cc49aa046b9e494313dce2f5038ed17b2f4) and the NTSC-U disc's
WARRIORS.WAD. This page documents the container only, never the scripts' contents (LEGAL.md).
Purpose¶
The game's 467 scripts ship as Lua 4.0 bytecode, the output of luac, in WAD entries named <name>.lua. What they
do and how the game runs them is on Scripting; this page is the file layout an extractor or a
loader needs. coney-tools extract writes the chunks as stored (scripts/), never decompiled.
Original structure¶
The loader is stock Lua 4.0's lundump.c, linked into the executable. Names are ours (after Lua's).
| Address | Name | Role | Evidence |
|---|---|---|---|
0x00333548 |
Lua4_LoadChunk |
reads the header, then the main function | confirmed (code) |
0x00333380 |
Lua4_LoadChunkHeader |
checks the signature, version 0x40, byte order and the size bytes |
confirmed (code) |
0x00333168 |
Lua4_LoadFunctionPrototype |
one function: source, line, parameters, vararg flag, stack size, locals, lines, constants, code | confirmed (code) |
0x00332db0 |
Lua4_LoadFunctionCode |
the instructions; the last must be END (0), else "bad code" |
confirmed (code) |
Data¶
All values little-endian (the byte-order flag is 1).
Header (13 bytes, then a test number)¶
| Offset | Value | Meaning |
|---|---|---|
+0x00 |
1B 4C 75 61 |
signature, ESC Lua |
+0x04 |
40 |
version 4.0 (the reader refuses above and below) |
+0x05 |
01 |
little-endian |
+0x06-+0x08 |
04 04 04 |
sizes of int, size_t and an instruction |
+0x09 |
20 |
bits per instruction (32) |
+0x0a |
06 |
bits of the opcode |
+0x0b |
09 |
bits of the B field |
+0x0c |
08 |
size of a number (double) |
+0x0d |
f64 | test number (Lua 4.0's 3.14159265358979e8), checked against the reader's own |
Confirmed (code) at 0x00333380 for every check. Disc check: all 467 Lua entries start with these 13 bytes.
Function prototype¶
Repeated for the main function and, recursively, every nested one (stock Lua 4.0):
string source "=(none)" on the disc (the chunk names were stripped)
int lineDefined
int numParams
u8 isVararg
int maxStackSize
int n; n x {string name, int startPc, int endPc} local variables (debug)
int n; n x int line info (debug)
int n; n x string string constants
int n; n x f64 number constants
int n; n x prototype nested functions
int n; n x u32 instructions (the last is END)
A string is a size_t length that counts its final NUL (0 for none), then the bytes. Disc check: all 467 chunks
parse to exactly their entry's size with this layout (python/src/coney_tools/lua4.py).
One difference from stock Lua 4.0 matters to a VM, not to the container: table constructors flush every 62 items, not 64 (Scripting).
Behaviour¶
doFile finds a chunk by its WAD name and runs it (Scripting).
Coney's implementation¶
Coney's VM loads the same bytecode (src/scripting/); coney-tools reads it for the reference lists
(lua4.py) and copies it for the extracted folder.
Open questions¶
- 111 of the 467 chunks have no recovered name (the extractor writes them as
<hash>.lua).