-
Notifications
You must be signed in to change notification settings - Fork 0
DTE Scripting Reference
A complete reference to Starlancer's mission trigger/event scripting language — the trigger conditions, Executor command set, AI-behaviour codes, and script-stream opcodes. This page fuses two independent reverse-engineering efforts and contains only original RE analysis (addresses + inferred meaning), no game source or assets.
-
Static RE of the game executable (this project; ImageBase
0x400000, Ghidra placeholder namesFUN_<addr>) — source of per-command implementation addresses + parameter counts, the trigger enum, and the bytecode VM. - Black-box RE by Captain Foster / "Starlancer ME" — blog https://starlancerme.blogspot.com/, YouTube @CaptainFoster. Source of the numeric opcode/command/AI/ship/pilot IDs and observed in-game semantics, plus a Python "Mission Ship Editor". Their empirical numbering and our disassembly agree wherever they overlap.
A .DTE carries data sections (ships, triggers, globals, strings) plus a block of script
bytecode, executed event-driven:
- An engine event (ship destroyed, proximity sphere entered, timer expired) looks up the
acting ship's trigger list and tests each record's condition (
TT_*at+0x15) and operands (FUN_0045CEA0). - On a match, the record's action id (
+0x16) spawns a script thread (FUN_0045B8D0); the block is prefixed by au16byte-length. - The interpreter
FUN_0045C980runs it: fetch one opcode byte → index the 256-entry handler tableDAT_004F6350→ advance the IP → call the handler, until one returns 0. A per-byte flag array (DAT_005294D8) marks yield points for multi-frame scripts. - Command opcodes (
0x21 <index>) dispatch through the command catalogueDAT_004F3AD0(installed byFUN_0045CE30), which holds each command's implementation, parameter count, name and parameter labels.
So a disassembler can always advance: 0x21, read the index, consume exactly that command's
parameter count of operands.
Condition type at trigger-record +0x15. 33 scriptable types, 0x00–0x20 — verified from
the FUN_0045B330 string array, identical to Starlancer ME's table. (The condition-descriptor
table DAT_0052952C has 35 entries; the 2 past 0x20 are internal/non-scriptable.)
00 TT_SHOTAT |
09 TT_JUMPED_IN |
12 TT_TARGETTED |
1B TT_TRACTOR_BEAM_BROKEN |
01 TT_DESTROYED |
0A TT_FG_JUMPED_IN |
13 TT_PLAYER_L1_DOUBLETAP |
1C TT_INSIDE_OBJECT |
02 TT_LAUNCHED |
0B TT_PLAYER_READY_TO_WARP |
14 TT_PLAYER_L2_DOUBLETAP |
1D TT_OUTSIDE_OBJECT |
03 TT_CAMERAREACHED |
0C TT_JUMPED_THROUGH_HOOP |
15 TT_PLAYER_R1_DOUBLETAP |
1E TT_DOCKED |
04 TT_SHIPREACHED |
0D TT_PLAYER_WANTS_BACKUP |
16 TT_PLAYER_R2_DOUBLETAP |
1F TT_UNDOCKED |
05 TT_PROXIMITY_CLOSE |
0E TT_RIPPER_GRABBED_OBJECT |
17 TT_PLAYER_L1_L2_R1_R2_PRESSED |
20 TT_BEING_CHASED |
06 TT_PROXIMITY_GENERAL |
0F TT_RIPPER_DROPPED_OBJECT |
18 TT_PLAYER_L1_R1_PRESSED |
|
07 TT_OBJECT_SCOOPED |
10 TT_CLOAKED |
19 TT_GAME_TIMER_EXPIRED |
|
08 TT_PLAYER_READY_TO_JUMP |
11 TT_DECLOAKED |
1A TT_TRACTOR_BEAM_LOCKED |
Index + name from Starlancer ME (validated in-game); parameter count + implementation address
from our decompiled catalogue DAT_004F3AD0 (matched by name). The blog index ≡ catalogue index
throughout; (blog only) = documented by the blog but not separately matched in our walk.
| idx | name | p | impl | idx | name | p | impl |
|---|---|---|---|---|---|---|---|
00 |
PrintShipName | 2 | 0x458AB0 |
30 |
SetNavPoint | 2 | 0x459270 |
01 |
CreateTimer | 4 | 0x45D210 |
31 |
SetEscortPoint | 2 | 0x4592F0 |
02 |
DestroyTimer | 1 | 0x45D290 |
32 |
ResetAfterBurners | 0 | 0x4594C0 |
03 |
CreateFlightGroup | 1 | 0x457C40 |
33 |
DisableMissiles | 2 | 0x459370 |
04 |
DestroyFlightGroup | 1 | 0x457FD0 |
34 |
DisableEngines | 2 | 0x4593E0 |
05 |
WaitNSeconds | — | (blog) | 35 |
DisableEject | 2 | 0x459450 |
06 |
PlaySpeech | 1 | 0x458090 |
36 |
SetHostile | 2 | 0x4594F0 |
07 |
WaitForSpeech | 0 | 0x458100 |
37 |
ResetToSpawnPositions | 0 | 0x4591B0 |
08 |
PlayCommsMovie | 3 | 0x458120 |
38 |
UpdateEnvironmentFXState | 0 | 0x4591A0 |
09 |
WaitForMovie | 0 | 0x458180 |
39 |
SetPrimaryTarget | 1 | 0x459550 |
0A |
PrintDebugMessage | 1 | 0x4581A0 |
3A |
WaitForJumpOrLaunch | 1 | 0x4595A0 |
0B |
SetAI | 4 | 0x4581F0 |
3B |
DoNotDisturb | 2 | 0x459640 |
0C |
ClearAI | 1 | 0x4588C0 |
3C |
SetEnvironmentFXNebula | 1 | 0x459190 |
0D |
SetPatrolRoute | 2 | 0x458860 |
3D |
StartShipAnimationReverse | 2 | 0x4587D0 |
0E |
SetPilot | 2 | 0x458830 |
3E |
SnapToPoint | 2 | 0x4596A0 |
0F |
SetTriggerState | 3 | 0x45D300 |
3F |
PlayFostersLastStand | 0 | 0x459740 |
10 |
StartDirectorCam | 5 | 0x4582E0 |
40 |
OpenInstrument | 1 | 0x45D9D0 |
11 |
StartShipAnimation | 2 | 0x458720 |
41 |
CloseInstrument | 1 | 0x45DA30 |
12 |
ShipFollowCurve | 3 | 0x4585D0 |
42 |
DestroySubObject | 2 | 0x459750 |
13 |
SetupLaunch | 3 | 0x458970 |
43 |
SetObjective | 2 | 0x459870 |
14 |
StartLaunch | 1 | 0x458A40 |
44 |
SetRescueProbabilities | 3 | 0x4598D0 |
15 |
DisplaySubTitle | 1 | 0x458A80 |
45 |
IsShipThisPlayer | 1 | 0x4598F0 |
16 |
GTextPilotDefine | — | (blog) | 46 |
SetFlybackMarker | 2 | 0x459910 |
17 |
ResetCodePriority | 1 | 0x458A90 |
47 |
ResetFlybackMarker | 0 | 0x4599E0 |
18 |
InterruptTriggerCode | 0 | 0x45D450 |
48 |
StopShipAnimation | 2 | 0x458770 |
19 |
CommsFromShip | 3 | 0x458AC0 |
49 |
SetShipAvoidance | 2 | 0x459A30 |
1A |
SetInvulnerability | 2 | 0x458BC0 |
4A |
MatchSpeed | 2 | 0x459A90 |
1B |
MovingShipFollowCurve | 4 | 0x4585A0 |
4B |
MovingShipBackupCurve | 4 | 0x458670 |
1C |
DisableObject | 2 | 0x4583C0 |
4C |
WaitForKey | 1 | 0x459AE0 |
1D |
PositionRelative | 2 | 0x4584D0 |
4D |
TerminateMission | 0 | 0x459BB0 |
1E |
WhenPlayerLastJumped | 0 | 0x458580 |
4E |
TurretSetTarget | 2 | 0x459BD0 |
1F |
StartMissileCam | 1 | 0x458B60 |
4F |
SetAnyTriggerState | 4 | 0x45D3A0 |
20 |
StartChaseCam | 1 | 0x458B80 |
50 |
WaitForDirectorCam | 0 | 0x459C90 |
21 |
SetPlayerTarget | 2 | 0x458C80 |
51 |
KillAllScriptExecutionExceptMe | 0 | 0x45D990 |
22 |
SetTargetable | 2 | 0x458D50 |
52 |
StackDirectorCam | 5 | 0x458300 |
23 |
PlayMusic | 2 | 0x458DF0 |
53 |
Scanner | 1 | 0x459CB0 |
24 |
StopDirectorCam | 0 | 0x458E30 |
54 |
ReplaceSubObject | 2 | 0x459CF0 |
25 |
SetActionCentre | 2 | 0x458E60 |
55 |
Fire | 2 | 0x459DD0 |
26 |
RadiusOfSphere | — | (blog) | 56 |
MultiplayerScriptSync | 1 | 0x459DF0 |
27 |
ShipToDock | — | (blog) | 57 |
FriendlyFire | 0 | 0x459F30 |
28 |
DisableTaunts | 1 | 0x458F40 |
58 |
EntityToCloak | — | (blog) |
29 |
ShipPointToFlyTo | — | (blog) | 59 |
ReplenishWeapons | 1 | 0x459FA0 |
2A |
CommsFromShipOnce | 3 | 0x458FD0 |
5A |
WillsBlag | 1 | 0x45A1C0 |
2B |
DisableLights | 2 | 0x459070 |
5B |
ShowHudIcon | 2 | 0x45A1F0 |
2C |
SetEnvironmentFX | 2 | 0x459170 |
5C |
DisableListing | 2 | 0x45A210 |
2D |
MultiPlayerSync | 0 | 0x4591E0 |
5D |
DisableObjectAtNextJump | 2 | 0x45A250 |
2E |
DisableGenericComms | 1 | 0x4591F0 |
5E |
DarrensNaughtyBlag | 2 | 0x45A290 |
2F |
DisableGuns | 2 | 0x459200 |
5F |
Test_AI_Function | 2 | (head) |
Dev-original names (PlayFostersLastStand, WillsBlag, DarrensNaughtyBlag) confirm these are
recovered symbols. Parameter labels are recoverable from catalogue debug strings — e.g.
SetInvulnerability modes 0 none / 1 player-can-hit / 2 fully-invulnerable / 3 eject-before- exploding; SetObjective state 0 Inactive / 1 Active / 2 Current.
From Starlancer ME's AI Codes page, 0x00–0x44:
00 Do Nothing · 01 Fly Aimlessly · 02/03 Launch Missile · 04 Warp In · 05 Warp Out ·
06 Fly · 07 Run Away · 08 Land · 09 Escort · 0A Find New Target · 0B Explode ·
0C Ripper grabs object · 0D Object Attach · 0E Formation Regroup · 0F Patrol Route ·
10 Toggle Cloak · 11 Ship Follow Curve · 12 Slow Rotate · 13 Jump In · 14 Jump Out ·
15 Find Scoop Up · 16–18 Random Spin Slow/Med/Fast · 19/1A Fixed Gate Jump In/Out ·
1B Formation · 1C/1D Fixed Gate Open/Close · 1E Eject · 1F Fixed Gate Collapse ·
20 Match Speed · 21 Dark Reign shoot · 22 Move to spawn pos · 23 Object lights on ·
24 Boridin breakaway · 25 FAIL · 26 Rotate Boridin warp projector · 27 Ripper drop object ·
28 Jump In · 29 Jump Out · 2A (unknown) · 2B Huge explosion · 2C Zero velocity+rotation ·
2D Fly backwards · 2E Player Control · 2F Multiplayer Control · 30 Avoid Target ·
31 Torpedo · 32 Launch · 33 Fight · 34 Destroy itself · 35 Scoop Up · 36 Eject Spin ·
37 Dock · 38 Dark reign shoot · 39 Ripper end drop · 3A Ripper attach pod to Mammoth ·
3B Eject fighter attack · 3C Disrupted · 3D/3E Capship list left/right · 3F Friendly Fire ·
40 Eject Player · 41 Ship Follow Curve Backwards · 42 Mill · 43 Deathmatch Respawn Effect ·
44 Deathmatch Dark Reign target.
| opcode | meaning |
|---|---|
0x21 <i> |
Call Executor command #i (consumes that command's params) |
0x32 <i> |
Set AI behaviour #i
|
0x2A <n> |
Play speech (index n; some copies embed an inline .ut filename) |
0x2C <o> / 0x2D <g>
|
Single-object / flight-group reference |
0x22 <p> / 0x4D <p>
|
Script "part" marker / branch into part |
0x27 <i> / 0x40 <i>
|
Read global value / push global address (write) |
0x3F <i> |
Push array-slot address (lvalue); land-loop branch in the ending context |
0x23/0x24 · 0x28 · 0x02/0x03 · 0x14
|
push-immediate · wait/operand · compare !=/== · squad test |
Win/lose (Starlancer ME's observation, matching our decode): the kill condition's 0x40
writes a flag; at mission end 0x27 reads it and 0x02/0x03 selects SUCCESS vs FAIL. Missions
default to "Failure" and are promoted to one of five grades: Failure / Partial Failure / Partial Success / Success / Success + Bonus (0–4, selector DAT_0052A428).
Numeric opcode/command/AI/ship/pilot tables and runtime semantics: Captain Foster / Starlancer ME (https://starlancerme.blogspot.com/, @CaptainFoster). Implementation addresses, parameter counts, the VM and struct layouts: this project's static decompilation. See Missions, AI & Scripting for the file format and lifecycle.