Script bindings: Script flow¶
Verified against: SLUS_212.15 (NTSC-U, SHA1 e9cb2cc49aa046b9e494313dce2f5038ed17b2f4).
Bindings for running scripts, scheduled calls, callbacks and message handlers: 18 in all. Conventions, the other categories and how to read an entry are on the masterlist.
| Binding | Returns | Scripts | Boot | Mission 1 | Evidence |
|---|---|---|---|---|---|
doFile |
- | 39 | yes | no | confirmed (code) |
doInclude |
- | 0 | no | no | confirmed (code) |
FlushScheduledFuncs |
- | 134 | yes | yes | confirmed (code) |
gc |
- | 18 | yes | yes | confirmed (code) |
preLoadFile |
- | 61 | yes | yes | confirmed (code) |
RegisterUpdate |
- | 0 | no | no | confirmed (code) |
ScheduleFunc |
- | 204 | yes | yes | confirmed (code) |
ScheduleFuncArg1 |
- | 89 | yes | yes | confirmed (code) |
SetAllClearCallBack |
- | 2 | no | no | confirmed (code) |
SetArmiesMultiplayerCallback |
- | 0 | no | no | inferred |
SetCheatCallback |
- | 1 | yes | no | confirmed (code) |
SetGeneralCarMsgHandler |
- | 10 | no | no | confirmed (code) |
SetHatCallBack |
- | 2 | no | no | confirmed (code) |
SetMsgHandler |
- | 195 | yes | yes | confirmed (code) |
SetMsgHandlerEx |
- | 43 | yes | yes | confirmed (code) |
SetMultiplayerCallback |
- | 6 | yes | no | confirmed (code) |
SetObjZoneMsgHandler |
- | 5 | no | no | confirmed (code) |
SetStartGameCallback |
- | 116 | no | yes | confirmed (code) |
doFile¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | name |
string | Script name without extension, such as config_easy. |
Returns nothing.
Runs name .. ".lua" from the WAD synchronously in the current Lua state (script system slot +0x34).
Notes. A PC-style path under the current level's folder is built when 0x001458c0 returns 0, which it never does in
this build.
- Evidence: confirmed (code) at
0x003579a0; detail: traced - Wrapper
0x0036d648(registered byRegisterBindings); calls0x003579a0 - Used by 39 of 467 script chunks (80 references); boot to menu: yes; mission 1: no; result used: no
- Later in the story: 15 of 28 levels, first
level87(mission 3) - Coney: implemented
doInclude¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | name |
string | Script name without extension. |
Returns nothing.
The same as doFile (the same callee, 0x003579a0). No shipped script calls it.
- Evidence: confirmed (code) at
0x003579a0; detail: brief - Wrapper
0x0036d678(registered byRegisterBindings); calls0x003579a0 - Used by no script on the disc
- Coney: not implemented
FlushScheduledFuncs¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Name of the function whose pending calls to cancel; nil cancels every pending call. |
Returns nothing.
Cancels scheduled calls (slot +0xac).
- Evidence: confirmed (code) at
0x00386450; detail: traced - Wrapper
0x0036d848(registered byRegisterBindings); calls0x00386450 - Used by 134 of 467 script chunks (358 references); boot to menu: yes; mission 1: yes; result used: no
- Later in the story: 23 of 28 levels, first
level80(mission 2) - Coney: implemented
gc¶
No arguments.
Returns nothing.
Runs a Lua garbage collection now and pushes the next forced collection 2 s away (script system slot +0x1c).
- Evidence: confirmed (code) at
0x00386370; detail: traced - Wrapper
0x0036d700(registered byRegisterBindings); calls0x00386370 - Used by 18 of 467 script chunks (56 references); boot to menu: yes; mission 1: yes; result used: no
- Later in the story: 7 of 28 levels, first
level95(the hub) - Coney: implemented
preLoadFile¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | name |
string | Script name without extension. |
| 2 | callback |
string | Name of the Lua function to call once the script has loaded and run (for example a checkpoint's start function). |
Returns nothing.
Requests name .. ".lua" from the file manager asynchronously; when it arrives it is run and then the callback is
called. Level scripts load their checkpoint scripts this way.
Notes. The completion routine is 0x00356d00; that it calls the callback after running the file is inferred
(scripting.md, open question).
- Evidence: confirmed (code) at
0x00357a68; detail: traced - Wrapper
0x0036d6a8(registered byRegisterBindings); calls0x00357a68 - Used by 61 of 467 script chunks (94 references); boot to menu: yes; mission 1: yes; result used: no
- Later in the story: 28 of 28 levels, first
level80(mission 2) - Coney: implemented
RegisterUpdate¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Name of a Lua function to call every frame with the frame time in milliseconds, or nil to stop. |
Returns nothing.
Sets the script system's per-frame update function (slot +0xb4). No shipped script calls it.
- Evidence: confirmed (code) at
0x003863a0; detail: brief - Wrapper
0x0036d720(registered byRegisterBindings); calls0x003863a0 - Used by no script on the disc
- Coney: not implemented
ScheduleFunc¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Name of the Lua function to call (dotted names allowed); looked up when it fires, so it can be redefined meanwhile. |
| 2 | delayMs |
number, truncated to an unsigned integer | Delay in milliseconds on the game timer. |
Returns nothing.
Calls a Lua function once, with no arguments, after a delay (script system slot +0x94). A name that no longer resolves
to a function is dropped silently.
- Evidence: confirmed (code) at
0x003863d8; detail: traced - Wrapper
0x0036d750(registered byRegisterBindings); calls0x003863d8 - Used by 204 of 467 script chunks (1911 references); boot to menu: yes; mission 1: yes; result used: no
- Later in the story: 28 of 28 levels, first
level80(mission 2) - Coney: implemented
ScheduleFuncArg1¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Name of the Lua function to call. |
| 2 | arg |
number, truncated to an unsigned integer | The number passed to the function; converted to an unsigned 32-bit integer, so fractions are cut and negative values wrap. |
| 3 | delayMs |
number, truncated to an unsigned integer | Delay in milliseconds on the game timer. |
Returns nothing.
Calls a Lua function once with one number argument after a delay (slot +0x9c).
Notes. The argument order is (name, argument, delay): confirmed at 0x003572e8, which adds its last parameter to
the game time; scripting.md's ScheduleFuncArg1(name, ms, n) has the two numbers the wrong way round.
- Evidence: confirmed (code) at
0x00386410; detail: traced - Wrapper
0x0036d7b0(registered byRegisterBindings); calls0x00386410 - Used by 89 of 467 script chunks (293 references); boot to menu: yes; mission 1: yes; result used: no
- Later in the story: 23 of 28 levels, first
level80(mission 2) - Coney: implemented
SetAllClearCallBack¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Lua function name (copied, at most 31 characters, to W_GameState + 0x2bc), or nil to clear it. |
Returns nothing.
Sets the function called, with no arguments, when player 1's gang is in the clear: when its police wanted timer (gang
+0x5e8) runs out with no crime in progress and the police turn neutral again (0x00169a20, which also tells the HUD and
sets the last crime type to 0xe), or when its second timer (gang +0x5f0, set by GangRespond and GoalCallGang) runs
out.
Notes. Setting a name also clears game state byte +0x2db (the byte before the name). The callback is only called
if the name is a Lua function. Other readers of +0x2bc (0x0016cc60, Crime_UpdateLevel 0x0041c128) are not traced.
Wanted timers: Crimes.
- Evidence: confirmed (code) at
0x0041add0,0x0041adf8,0x001698f0,0x00169a20; detail: traced - Wrapper
0x003705d0(registered byRegisterBindings); calls0x0041add0,0x0041adf8GameState_SetAllClearCallback,0x001698f0Gang_UpdateWanted,0x00169a20Gang_ClearWanted - Used by 2 of 467 script chunks (3 references); boot to menu: no; mission 1: no; result used: no
- Later in the story: 1 of 28 levels, first
level20(flashback 4) - Coney: not implemented
SetArmiesMultiplayerCallback¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Lua function name, or nil. |
Returns nothing.
Like SetMultiplayerCallback, for the Armies of the Night mode (stored by 0x0041b2c8). No shipped script calls it.
- Evidence: inferred; detail: brief
- Wrapper
0x00370660(registered byRegisterBindings); calls0x0041b280 - Used by no script on the disc
- Coney: not implemented
SetCheatCallback¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Name of the Lua function to call when a cheat code is entered. |
Returns nothing.
Interns and stores the cheat callback's name (0x0050ca98); global.lua sets it to its debug cheat handler.
Notes. What calls it and with which arguments is not traced.
- Evidence: confirmed (code) at
0x00163e98; detail: traced - Wrapper
0x0036e488(registered byRegisterBindings); calls0x00163e98 - Used by 1 of 467 script chunks (1 reference); boot to menu: yes; mission 1: no; result used: no
- Coney: not implemented
SetGeneralCarMsgHandler¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | message |
number, truncated to an integer | Message number; every call passes 25 (0x19), the message a car sends itself when a hit damages it or it explodes. |
| 2 | callback |
string | Name of the Lua function to call, or nil to remove it. |
Returns nothing.
Registers one Lua callback for a message from any car: the car manager (0x00512c7c + 0x844) keeps the function's
reference in its slot for that number (+0x18 + 4 × message). Message 0x19 calls it as (car, other, n, flag): once per
part a hit damages (n = the part 1-25, other the human behind the hit, flag 1 when the hit broke the part), (car, human,
-2, 1) when that hit leaves every breakable part broken, (car, thrower, -1, 0) when a molotov sets the car alight, and
(car, NilHandle, -1, 1) when it explodes (Cars). It is the only way to hear a car: a
car has no handler component, so SetMsgHandler on a car is never called.
Notes. The store is confirmed (code) at 0x0038e538; the reference comes from the script system's slot +0xcc. The
car's message slot (vtable 0x00544c08 +0x44, 0x00389700) forwards every message to 0x0038ebf8, which calls the
marshaller with the stored reference when the slot is set (Cars: explosion).
- Evidence: confirmed (code) at
0x00386340,0x0038e538; detail: traced - Wrapper
0x0036d2e8(registered byRegisterBindings); calls0x00386340Script_SetGeneralCarMsgHandler,0x0038e538CarManager_SetMsgHandler - Used by 10 of 467 script chunks (20 references); boot to menu: no; mission 1: no; result used: no
- Later in the story: 8 of 28 levels, first
level34(mission 4) - Coney: implemented
SetHatCallBack¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Lua function name (copied, at most 31 characters, to W_GameState + 0x33c), or nil to clear it. |
Returns nothing.
Sets the function called as f(humanHandle, hatHandle, typeName) whenever a human takes a hat: the human message handler
(0x0024667c in Human_HandleMessage) stores the hat object's handle at human +0x364 and then calls it, with the hat's
object type name. Not called while a scene plays (game state +0x410) or when either handle no longer resolves.
Notes. Fires for any human (thugs going for hats included), not only the player. Setting a name clears game state
byte +0x35b. Cleared on every level load (0x00418c68). The message that leads there is not identified.
- Evidence: confirmed (code) at
0x0041af20,0x0041af48,0x0041af80; detail: traced - Wrapper
0x00370600(registered byRegisterBindings); calls0x0041af20,0x0041af48GameState_SetHatCallback,0x0041af80GameState_CallHatCallback - Used by 2 of 467 script chunks (2 references); boot to menu: no; mission 1: no; result used: no
- Later in the story: 1 of 28 levels, first
level11(flashback 5) - Coney: not implemented
SetMsgHandler¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | object |
number, truncated to an unsigned integer | Handle of the object or human whose messages to watch. |
| 2 | message |
number, truncated to an integer | Message number, 0-25 (for example 3 when a human enters a volume box or trigger sphere, 4 when it leaves, 8 when an AI arrives at a flag, 18 for a death); 0 also clears the object's interaction prompt first, whatever the callback (see SetMsgHandlerEx; confirmed at runtime at the gym). |
| 3 | callback |
string | Name of the Lua function to call (dotted names allowed), or nil to remove the handler. |
Returns nothing.
Registers a Lua callback for a message an object receives: the interned name goes in slot message of the object's
message-handler component (0x003860b8, made on demand). When the message arrives the callback gets arguments that
depend on the number, usually the object itself and the other object involved (the table is in
scripting.md#message-handlers). The most used binding in the scripts.
Notes. Messages reach Lua only while the level-end state (W_GameState + 0x14c) is 0, so no callback runs once a
mission is won, failed or left (0x00384c38). The arguments per number are confirmed (code) at 0x00384ce0; the senders of
3, 4, 5 (volume boxes, trigger spheres) and 8 (flags) are confirmed, the meaning of the others is inferred from the
scripts' handler names (references/script-events.md).
- Evidence: confirmed (code) at
0x00386298; detail: traced - Wrapper
0x0036d1c8(registered byRegisterBindings); calls0x00386298 - Used by 195 of 467 script chunks (3040 references); boot to menu: yes; mission 1: yes; result used: no
- Later in the story: 28 of 28 levels, first
level80(mission 2) - Coney: implemented
SetMsgHandlerEx¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | object |
number, truncated to an unsigned integer | Handle of the object or human (a door, a bouncer, a tag). |
| 2 | message |
number, truncated to an integer | Message number; 0 is the interaction (the scripts pass 0). |
| 3 | callback |
string | Lua function name to call, or nil. |
| 4 | prompt |
string | Text of the on-screen prompt shown when the player can interact (a string, often a GSTRING entry); nil or empty for none. |
| 5 | prompt2 |
string | A second text, kept in the context record's +0x14 and shown in the hint box while the player can interact; given alone (prompt nil), it still makes the record. |
Returns nothing.
Like SetMsgHandler but also gives the object an interaction prompt, the 'press to talk' text shown when the player is close; used for doors, bouncers and tags.
Notes. With message 0 and a callback, a non-empty prompt or a non-empty second text sets the object's prompt (vtable
+0x124; with the prompt nil the record has no prompt and only the second text shows); a nil callback, or both texts
nil or empty, clears it (+0x12c). On a world object the prompt is a kind-1 context record (1.1 m), which triangle
hands to the message-0 callback (Scripts).
- Evidence: confirmed (code) at
0x00386168; detail: traced - Wrapper
0x0036d348(registered byRegisterBindings); calls0x00386168 - Used by 43 of 467 script chunks (212 references); boot to menu: yes; mission 1: yes; result used: no
- Later in the story: 20 of 28 levels, first
level87(mission 3) - Coney: implemented
SetMultiplayerCallback¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Lua function name (at most 32 characters), or nil to clear. |
Returns nothing.
Sets the function called when a second player joins (kept at W_GameState + 0x3a4); global.lua uses it to give the
new player an inventory.
Notes. The store is confirmed; the trigger is inferred from the scripts' handler names.
- Evidence: confirmed (code) at
0x0041b0f0; detail: traced - Wrapper
0x00370630(registered byRegisterBindings); calls0x0041b0f0 - Used by 6 of 467 script chunks (7 references); boot to menu: yes; mission 1: no; result used: no
- Later in the story: 5 of 28 levels, first
level60(Armies of the Night 1) - Coney: implemented
SetObjZoneMsgHandler¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | zone |
number, truncated to an unsigned integer | Object zone number 0-254 (Object zones); not range-checked. |
| 2 | message |
number, truncated to an integer | Message number 0-25, as for SetMsgHandler (Script events); scripts use 1 (damaged) and 2 (broken). Not range-checked. |
| 3 | callback |
string | Lua function name, interned; nil clears the slot. |
Returns nothing.
Registers one Lua callback for a message on every world object of an object zone, in the object manager's table (255
zones of 26 slots, object manager +0x50 + zone * 0x68 + message * 4). Whenever a world object gets a message
(0x00392520), the manager finds its spawn record, and when that record's zone has a callback for the message it is
called like an object's own handler (same arguments, Scripts: message
handlers); the object's own handlers run after it.
Notes. Only objects spawned from the level's spawn table belong to a zone. The table is cleared when the spawn table is reset (0x00398130). Out-of-range zone or message numbers write past the table.
- Evidence: confirmed (code) at
0x00386308,0x0039a7e0,0x003982a0,0x00392520; detail: traced - Wrapper
0x0036d258(registered byRegisterBindings); calls0x00386308,0x0039a7e0ObjZone_SetMsgHandler,0x003982a0ObjZone_DispatchMessage,0x00392520 - Used by 5 of 467 script chunks (34 references); boot to menu: no; mission 1: no; result used: no
- Later in the story: 4 of 28 levels, first
level93(mission 10) - Coney: not implemented
SetStartGameCallback¶
| # | Argument | Read as | Meaning |
|---|---|---|---|
| 1 | callback |
string | Name of the Lua function (at most 31 characters) that InitLevel calls when the level is ready; nil clears it. |
Returns nothing.
Sets the function run once the level has finished loading (kept at 0x005e6d88).
- Evidence: confirmed (code) at
0x0015fe50; detail: traced - Wrapper
0x0036df98(registered byRegisterBindings); calls0x0015fe50 - Used by 116 of 467 script chunks (219 references); boot to menu: no; mission 1: yes; result used: no
- Later in the story: 26 of 28 levels, first
level87(mission 3) - Coney: implemented