LBA2 Binary Script command descriptions

Each command code is one byte long, and after it there are params (or not), or other things. After params there is a next command byte, and so on. At the end of the script there is a 0x00 (END) command.

This document describes the commands and their parameters in short form. It does not describe how particular commands work in details. For such kind of information see other sources (LBArchitect help may contain some).

"[no params]" means that the command does not have any additional bytes (next command starts immediately after this command byte).

Information marked with question mark (?) is guessed (highly uncertain).

===============================
 TRACK SCRIPT
===============================

0x00 ( 0) END - marks end of the script
          [no params]

0x01 ( 1) NOP - no operation (never used)
          [no params]

0x02 ( 2) BODY - changes body for current actor
          param1: 1 byte (-1..254) - ID of the new body for the Actor

0x03 ( 3) ANIM - changes anim for current actor
          param1: 2 bytes - ID of the new anim for the Actor

0x04 ( 4) GOTO_POINT - rotates actor towards the point
          param1: 1 byte (0..255) - ID of the Point to go to

0x05 ( 5) WAIT_ANIM - waits till the current anim finishes
          [no params]

0x06 ( 6) LOOP - unknown (never used)
          [no params]

0x07 ( 7) ANGLE - makes the actor rotate
          param1: 2 bytes signed (-32768..32767) - new angle

0x08 ( 8) POS_POINT - immediately moves actor to the point
          param1: 1 byte (0..255) - ID of the Point to move to

0x09 ( 9) LABEL - marks command group
          param1: 1 byte(0..255) - ID of the label

0x0A (10) GOTO - jumps to specified label
          param1: 2 bytes signed (-1..32767) - address (offset) in the script to go to. -1 causes stopping execution of the script (and even SET_TRACK Life command won't run it anymore until reset of the Scene)

0x0B (11) STOP - stops the track script
          [no params]

0x0C (12) GOTO_SYM_POINT - rotates actor away from the point
          param1: 1 byte (0..255) - ID of the Track to go to

0x0D (13) WAIT_NUM_ANIM - waits till the anim plays number of times
          param1: 1 byte (0..255) - number of animation repetitions to wait
          param2: 1 byte - dummy (used internally), must be always 0

0x0E (14) SAMPLE - plays sound sample
          param1: 2 bytes (signed?) (0..32767) - ID of a sound sample to play

0x0F (15) GOTO_POINT_3D - moves sprite actor to the point in 3D
          param1: 1 byte unsigned (0..255) - ID of the Point to go to

0x10 (16) SPEED - sets sprite actor movement speed
          param1: 2 bytes (signed?) (0..32767) - speed (?)

0x11 (17) BACKGROUND - controls redrawing of the sector
          param1: 1 byte (0..1) - (boolean) if Actor is backgrounded (flag)

0x12 (18) WAIT_NUM_SECOND - waits number of seconds
          param1: 1 byte (0..255) - number of seconds to wait
          param2: 4 bytes - dummy (used internally)

0x13 (19) NO_BODY - makes the actor disappear
          [no params]

0x14 (20) BETA - immediately sets new angle
          param1: 2 bytes (signed?) (-32768..32767) - new angle

0x15 (21) OPEN_LEFT - moves door to the top-left
          param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x16 (22) OPEN_RIGHT - moves door to the bottom-right
          param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x17 (23) OPEN_UP - moves door to the top-right
          param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x18 (24) OPEN_DOWN - moves door to the bottom-left
          param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x19 (25) CLOSE - returns door to the base position (after OPEN_XX)
          [no params]

0x1A (26) WAIT_DOOR - waits for door to open/close
          [no params]

0x1B (27) SAMPLE_RND - playes a sound sample with randomly lowered pitch
          param1: 2 bytes (signed?) (0..32767) - ID of the sample to play

0x1C (28) SAMPLE_ALWAYS - plays a sound sample repeatedly
          param1: 2 bytes (signed?) (0..32767) - ID of the sample to play

0x1D (29) SAMPLE_STOP - stops playing a sound sample
          param1: 2 bytes (signed?) (0..32767) - ID of the sample to stop

0x1E (30) PLAY_ACF - plays specified SMK movie
          param1: null-terminated string - name of the movie file to play

0x1F (31) REPEAT_SAMPLE - sets number of repetitions for SIMPLE_SAMPLE
          param1: 2 bytes (signed?) (0..32767) - ID of the sample to play

0x20 (32) SIMPLE_SAMPLE - plays sound sample a number of times
          param1: 2 bytes (signed?) (0..32767) - ID of the sample to play

0x21 (33) FACE_HERO (org. FACE_TWINSEN) - rotates actor towards the hero
          param1: 2 bytes - dummy

0x22 (34) ANGLE_RND - unknown (maybe the same as LBA 1?)
          param1: 2 bytes (signed?) (-32768..32767) - new angle
          param2: 2 bytes - dummy

0x23 (35) REPLACE (org. REM) - unknown
          [no params]

0x24 (36) WAIT_NUM_DECIMAL (org. WAIT_NB_DIZIEME) - waits secified number of thenths of a second
          param1: 1 byte (0..255) - number of 1/10 of a second to wait
          param2: 4 bytes - dummy (used internally)

0x25 (37) DO - unknown (never used)
          [no params]

0x26 (38) SPRITE - (guess) sets a new sprite for the actor
          param1: 2 bytes (signed?) (-1..32768 ?) - ID of the new sprite

0x27 (39) WAIT_NUM_SECOND_RND (org. WAIT_NB_SECOND_RND) - waits specified number of seconds
          param1: 1 byte (0..255) - number of seconds to wait
          param2: 4 bytes - dummy (used internally)

0x28 (40) AFF_TIMER - unknown (never used)
          [no params]

0x29 (41) SET_FRAME - unknown
          param1: 1 byte ? - ID of frame ?

0x2A (42) SET_FRAME_3DS - unknown
          param1: 1 byte ? - ID of frame ?

0x2B (43) SET_START_3DS - unknown
          param1: 1 byte ? - ID of start frame ?

0x2C (44) SET_END_3DS - unknown
          param1: 1 byte ? - ID of end frame ?

0x2D (45) START_ANIM_3DS - unknown
          param1: 1 byte ?

0x2E (46) STOP_ANIM_3DS - unknown
          [no params]

0x2F (47) WAIT_ANIM_3DS - unknown
          [no params] ?

0x30 (48) WAIT_FRAME_3DS - unknown
          [no params] ?

0x31 (49) WAIT_NUM_DECIMAL_RND (org. WAIT_NB_DIZIEME_RND) - (guessed) waits maximum number of tenths of a second, or a lower number randomly
          param1: 1 byte (0..255) - number of ???
          param2: 4 bytes - dummy (used internally)

0x32 (50) INTERVAL (org. DECALAGE, may also mean "lag", "shift", "gap", "interval", "space") - unknown
          param1: 2 bytes ?

0x33 (51) FREQUENCY - unknown
          param1: 2 bytes ?

0x34 (52) VOLUME - unknown
          param1: 1 byte ?

===============================
 LIFE SCRIPT
===============================

Some commands in the Life Script are virtual - this means that the command is present in decompiled script (text form), and does not serve any purpose in compiled (binary) form of the script, so it may or may not be there. Virtual commands still have opcodes associated to them.


0x00 (  0) END - marks end of the script
           [no params]

0x01 (  1) NOP - no operation (never used)
           [no params]

0x02 (  2) SNIF (IF type) - negated SWIF (internal use only)
           [no params]

0x03 (  3) OFFSET - jumps to specified offset (never used)
           param1: 2 bytes (unsigned?) (0..65535) - address (offset) in the script to go to

0x04 (  4) NEVERIF (IF type) - negated ONEIF (internal use only)
           [no params]

0x05 (  5) (unused)
0x06 (  6) (unused)
0x07 (  7) (unused)
0x08 (  8) (unused)
0x09 (  9) (unused)

0x0A ( 10) PALETTE - (guessed) sets a colour palette
           param1: 1 byte ? - ID of the palette ?

0x0B ( 11) RETURN - returns to beginning of current comportement
           [no params]

0x0C ( 12) IF (IF type) - tests if condition is true
           params: See conditions below

0x0D ( 13) SWIF (IF type) - tests if condition is true and alternating
           params: See conditions below

0x0E ( 14) ONEIF (IF type) - tests if condition is true once
           params: See conditions below

0x0F ( 15) ELSE (works the same as OFFSET)
           param1: 2 bytes (unsigned?) (0..65535) - address (offset) to go to (skip the next block)

0x10 ( 16) ENDIF (virtual)
           [no params]

0x11 ( 17) BODY - sets body for the actor
           param1: 1 byte ? (0..255) - ID of the new body for the Actor

0x12 ( 18) BODY_OBJ - sets body for another actor
           param1: 1 byte ? (0..255) - ID of the target Actor
           param2: 1 byte ? (0..255) - ID of the new body for the target Actor

0x13 ( 19) ANIM - sets animation for the actor
           param1: 2 bytes signed ? (-1..32767 ?) - ID of the new anim for the Actor

0x14 ( 20) ANIM_OBJ - sets animation for another actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 2 bytes signed ? (-1..32767 ?) - ID of the new anim for the target Actor

0x15 ( 21) SET_CAMERA - unknown
           param1: 2 bytes ? - ??? (or maybe two 1-byte params)

0x16 ( 22) CAMERA_CENTER - unknown
           param1: 1 byte - ???

0x17 ( 23) SET_TRACK - starts execution of track script
           param1: 2 bytes signed (-1..32767) - address (offset) in the Track Script to go to. -1 causes stopping execution of the script (and even SET_TRACK Life command won't run it anymore until reset of the Scene)

0x18 ( 24) SET_TRACK_OBJ - setarts execution of track script for another actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 2 bytes signed (-1..32767) - address (offset) in the target Actor's Track Script to go to. -1 causes stopping execution of the script (and even SET_TRACK Life command won't run it anymore until reset of the Scene)

0x19 ( 25) MESSAGE - displays dialog text
           param1: 2 bytes (signed?) (0..32767) - ID of the text entry to be displayed

0x1A ( 26) CAN_FALL (org. FALLABLE) - controls gravity for the actor
           param1: 1 byte (0..2) - 0 = Actor cannot fall, 1 = Actor can fall, 2 = ???

0x1B ( 27) SET_DIRMODE (org. SET_DIR) - controls movement mode for the actor
           param1: 1 byte (0..7 ?) - ID of the mode to set. If this param is 2 (follow) or 4 (follow_2) (or possibly 6:same_xz ?), then param2 exists, otherwise there is one param only.
           (param2): 1 byte (0..255) - ID of the Actor to follow

0x1C ( 28) SET_DIRMODE_OBJ (org. SER_DIR_OBJ) - controla movement mode for another actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 1 byte (0..7 ?) - ID of the mode to set. If this param is 2 (foolow) or 4 (follow_2) (or possibly 6:same_xz ?), then param3 exists, otherwise there are two params only.
           (param3): 1 byte (0..255) - ID of the Actor to follow

0x1D ( 29) CAM_FOLLOW - make the cameta follow spcified actor
           param1: 1 byte (0..255) - ID of the actor to be followed by the camera

0x1E ( 30) SET_BEHAVIOUR (org. COMPORTEMENT_HERO) - controls hero’s behaviour
           param1: 1 byte (0..?) - ID of the behaviour to set (0 = normal, 1 = athletic, 2 = aggressive, 3 = discrete, 4 = proto-pack)

0x1F ( 31) SET_VAR_CUBE - sets cube (local) variable
           param1: 1 byte (0..255 ?) - ID of the Cube Var to set
           param2: 1 byte (0..255 ?) - new value of the Var to be set to

0x20 ( 32) COMPORTEMENT (virtual)
           param1: 1 byte (0..255) - probably ID of the comportement

0x21 ( 33) SET_COMPORTEMENT - changes comportement
           param1: 2 bytes (signed?) (-1..32767) - address (offset) of the target comportement

0x22 ( 34) SET_COMPORTEMENT_OBJ - changes comportement for another actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 2 bytes (signed?) (-1..32767) - address (offset) of the target comportement in the target Actor's Life Script

0x23 ( 35) END_COMPORTEMENT - marks end of comportement
           [no params]

0x24 ( 36) SET_VAR_GAME - sets game (global) variable
           param1: 1 byte (0..255) - ID of the Game Var to set
           param2: 2 bytes ? unsigned ? (0..65535 ?) - new value of the Var to be set to

0x25 ( 37) KILL_OBJ - kills specified actor
           param1: 1 byte (0..255) - ID of the Actor to be killed

0x26 ( 38) SUICIDE - kills current actor
           [no params]

0x27 ( 39) USE_ONE_LITTLE_KEY - removes one little key from the hero’s pocket
           [no params]

0x28 ( 40) GIVE_GOLD_PIECES - removes amount of money from hero’s pocket
           param1: 2 bytes (signed?) (-32768..32767) - number of gold pieces to be given

0x29 ( 41) END_LIFE - stops executing the life script
           [no params]

0x2A ( 42) STOP_CURRENT_TRACK (org. STOP_L_TRACK) - pauses track script
           [no params]

0x2B ( 43) RESTORE_LAST_TRACK (org. RESTORE_L_TRACK) - continues track script
           [no params]

0x2C ( 44) MESSAGE_OBJ - displays dialog text said by another actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 2 bytes (signed?) (0..32767) - ID of the text entry to be displayed

0x2D ( 45) INC_CHAPTER - increments CHAPTER variable by one
           [no params]

0x2E ( 46) FOUND_OBJECT - displays ‘object found’ message
           param1: 1 byte (0..255) - ID of the inventory object to be displayed

0x2F ( 47) SET_DOOR_LEFT - sets door position to the top-left
           param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x30 ( 48) SET_DOOR_RIGHT - sets door position to the bootom-right
           param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x31 ( 49) SET_DOOR_UP - sets door position to the top-right
           param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x32 ( 50) SET_DOOR_DOWN - sets door position to the bottom-left
           param1: 2 bytes (signed?) (-32768..32767) - distance to move

0x33 ( 51) GIVE_BONUS - pops bonus from the actor
           param1: 1 byte (0..255) - ???

0x34 ( 52) CHANGE_CUBE - changes the scene
           param1: 1 byte ? (0..255) - ID of the target Scene? (or isometric cube?)

0x35 ( 53) OBJ_COL - controls actor’s collisions with other actors
           param1: 1 byte (0..1) - (boolean) 1 = Actor can collide with objects (other Actors)

0x36 ( 54) BRICK_COL - sontrols actor’s collisions with bricks (maybe with 3D terrain too?)
           param1: 1 byte (0..2) - (boolean???) 1 = Actor can collide with bricks, 2 = ???

0x37 ( 55) OR_IF (IF type) - tests if condition is true
           [no params]

0x38 ( 56) INVISIBLE - controls visibility of the actor
           param1: 1 byte (0..1) - (boolean) 0 = Actor will be visible, 1 = Actor will be invisible

0x39 ( 57) SHADOW_OBJ - (guessed) controls shadow display of the actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 1 byte ? - ???

0x3A ( 58) POS_POINT - immediately moves actor to specified point
           param1: 1 byte (0..255) - ID of the Track to move the Actor to

0x3B ( 59) SET_MAGIC_LEVEL - sets hero’s magic level
           param1: 1 byte (0..?) - new magic level for the Actor

0x3C ( 60) SUB_MAGIC_POINT - subtracts from hero’s magic points
           param1: 1 byte (0..255) - amount of magic points to be subtracted

0x3D ( 61) SET_LIFE_POINT_OBJ - sets life points of an actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 1 byte (0..255) - amount of life points to be set for the target Actor

0x3E ( 62) SUB_LIFE_POINT_OBJ - subtracts from an actor’s life points
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 1 byte (0..255) - amount of life points to be subtracted from the target Actor's life points

0x3F ( 63) HIT_OBJ - damages specified actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 1 byte (0..255) - damage amount

0x40 ( 64) PLAY_ACF - plays SMK movie
           param1: null-terminated string - name of the movie to play

0x41 ( 65) ECLAIR - unknown (lightning strike maybe?)
           param1: 1 byte - ???

0x42 ( 66) INC_CLOVER_BOX - increments number of hero’s clover boxes
           [no params]

0x43 ( 67) SET_USED_INVENTORY - marks inventory item as ‘used’
           param1: 1 byte (0..255) - ID of the inventory item

0x44 ( 68) ADD_CHOICE - adds text line to the choice pool
           param1: 2 bytes (0..32767) - ID of the text entry

0x45 ( 69) ASK_CHOICE - asks for choice
           param1: 2 bytes (0..32768) - ID of the text entry as the choice question

0x46 ( 70) INIT_BUGGY - (guessed) initializes the car?
           [no params] ?

0x47 ( 71) MEMO_SLATE (org. MEMO_ARDOISE) - enables magic slate image
           param1: 1 byte ?

0x48 ( 72) SET_HOLO_POS - sets holomap position
           param1: 1 byte (0..255) - ID of the holomap position to be set

0x49 ( 73) CLR_HOLO_POS - clears holomap position
           param1: 1 byte (0..255) - ID of the holomap position to be cleared

0x4A ( 74) ADD_FUEL - adds to the hero’s fuel
           param1: 1 byte (0..255) - amount of fuel units

0x4B ( 75) SUB_FUEL - subtracts from the hero’s fuel
           param1: 1 byte (0..255) - amount of fuel units

0x4C ( 76) SET_GRM - controls isometric fragment merging
           param1: 1 byte (0..255) - ID of the Fragment ?
           param2: 1 byte - switch (0 or 1) ? (as 0 = LBA1’s GRM_OFF?)

0x4D ( 77) SET_CHANGE_CUBE - unknown
           param1: 2 bytes - ???

0x4E ( 78) MESSAGE_ZOE - unknown
           param1: 2 bytes ? (0..32767) - ID of the message text?

0x4F ( 79) FULL_POINT - sets the hero’s magic and life points to full
           [no params]

0x50 ( 80) BETA - immediately sets angle of the actor
           param1: 2 bytes (signed?) (-32768..32767) - the new angle

0x51 ( 81) FADE_TO_PAL - fades to specified palette
           param1: 1 byte ? (0..255) - ID of the target palette ?

0x52 ( 82) ACTION - unknown
           [no params] ?

0x53 ( 83) SET_FRAME - unknown
           param1: 1 byte ? - ID of a frame ?

0x54 ( 84) SET_SPRITE - unknown
           param1: 2 bytes ? - ID of the new sprite ?

0x55 ( 85) SET_FRAME_3DS - unknown
           param1: 1 byte ? - ID of the new frame ?

0x56 ( 86) IMPACT_OBJ - unknown
           param1: 1 byte ? - ID of the target object ?
           param2: 2 bytes ? - ???
           param3: 2 bytes ? - ???

0x57 ( 87) IMPACT_POINT - unknown
           param1: 1 byte ? - ID of the target point ?
           param2: 2 bytes - ???

0x58 ( 88) ADD_MESSAGE - unknown
           param1: 2 bytes ? - ID of the new message ?

0x59 ( 89) BALLOON (org. BULLE) - controls character talk baloons
           param1: 1 byte ? - target ballloon state ?

0x5A ( 90) NO_SHOCK (org. NO_CHOC) - unknown
           param1: 1 byte (0..1) ? - turn shock on or off?

0x5B ( 91) ASK_CHOICE_OBJ - asks for choice as another actor
           param1: 1 byte (0..255) - ID of the target Actor
           param2: 2 bytes (0..32767) - ID of the text entry to be displayed as the choice question

0x5C ( 92) CINEMA_MODE - controls the lowered screen height (wide screen)
           param1: 1 byte ? - boolean cinema mode on/off ?

0x5D ( 93) SAVE_HERO - (guessed) saves hero state
           [no params] ?

0x5E ( 94) RESTORE_HERO - (guessed) restores hero state
           [no params] ?

0x5F ( 95) ANIM_SET - immediately changes animation
           param1: 2 bytes ? (0..32767) - ID of the animation to be set ???

0x60 ( 96) RAIN (org. PLUIE) - controls rain
           param1: 1 byte ? (0..255) - boolean rain on/off ?

0x61 ( 97) GAME_OVER - dispays the game over
           [no params]

0x62 ( 98) THE_END - (guessed) shows the ending credits
           [no params]

0x63 ( 99) ESCALATOR - unknown
           [no params] ?

0x64 (100) PLAY_MUSIC - plays music track
           param1: 1 byte ? (0..255) - ID of the CD track to be played

0x65 (101) TRACK_TO_VAR_GAME - (guessed) stores current track (id or address?) to a game variable
           param1: 1 byte ? - ID of the Var to store the current track to ?

0x66 (102) VAR_GAME_TO_TRACK - (guessed) restores track from a game variable
           param1: 1 byte ? - ID of the Var to restore the current track from ?

0x67 (103) ANIM_TEXTURE - (guessed) controls texture animation
           param1: 1 byte - ID of the texture animation ? (or maybe switch 0 or 1)

0x68 (104) ADD_MESSAGE_OBJ - unknown
           param1: 1 byte ? (0..255) - ID of the target Actor ?
           param2: 2 bytes ? (0..32767) - ID of the message ?

0x69 (105) BRUTAL_EXIT - unknown
           [no params]

0x6A (106) REPLACE (org. REM) - unknown
           [no params] ?

0x6B (107) SCALE (org. ECHELLE, may also mean "ladder", "companion") - unknown
           param1: 1 byte - ???
           param2: 1 byte - ???
           (or maybe one 2-byte param)

0x6C (108) SET_ARMOR (org. SET_ARMURE) - sets actor’s armor
           param1: 1 byte ? - new armor value ?

0x6D (109) SET_ARMOR_OBJ (org. SET_ARMURE_OBJ) - sets another actor’s armor
           param1: 1 byte ? - ID of the target Actor ?
           param2: 1 byte ? - new armor value ?

0x6E (110) ADD_LIFE_POINT_OBJ - sets life points of another actor
           param1: 1 byte ? - ID of the target Actor ?
           param2: 1 byte ? - amount of life points to add?

0x6F (111) STATE_INVENTORY - unknown
           param1: 1 byte - inventory item ID ?
           param2: 1 byte - new state ?

0x70 (112) AND_IF (IF type) - tests if condition is true
           [no params]

0x71 (113) SWITCH (IF type) - tests condition for multiple values
           [no params]

0x72 (114) OR_CASE - tests one value of SWITCH
           param1: 2 bytes - address to jump to when equal (command block)
           param2: 1 byte - operator
           param3: value to compare (size depends on the SWITCH variable)

0x73 (115) CASE - tests one value of SWITCH
           param1: 2 bytes - address to jump to when not equal (next CASE)
           param1: 1 byte - operator
           param3: value to compare (size depends on the SWITCH variable)

0x74 (116) DEFAULT - marks default code for SWITCH
           [no params] ?

0x75 (117) BREAK - marks end of code for CASE
           param1: 2 bytes ? - address of the END_SWITCH ?

0x76 (118) END_SWITCH - marks end of SWITCH block
           [no params] ?

0x77 (119) SET_HIT_ZONE - unknown
           param1: 1 byte ? - ???

0x78 (120) SAVE_COMPORTEMENT - (guessed) saves current comportement address
           [no params] ?

0x79 (121) RESTORE_COMPORTEMENT - (guessed) restores comportement address
           [no params] ?

0x7A (122) SAMPLE - unknown
           param1: 2 bytes ? (0..32767) - ID of the sample to play ?

0x7B (123) SAMPLE_RND - unknown
           param1: 2 bytes ? (0..32767) - ID of the sample to play ?

0x7C (124) SAMPLE_ALWAYS - unknown
           param1: 2 bytes ? (0..32767) - ID of the sample to play ?

0x7D (125) SAMPLE_STOP - unknown
           param1: 2 bytes ? (0..32767) - ID of the sample to stop ?

0x7E (126) REPEAT_SAMPLE - unknown
           param1: 2 bytes ? (0..32767) - ID of the sample ?

0x7F (127) BACKGROUND - controls redrawing of the sctor
           param1: 1 byte ? - boolean background on/off ?

0x80 (128) ADD_VAR_GAME - adds to game (global) variable
           param1: 1 byte ? - ID of the target Var ?
           param2: 2 bytes ? - value to add ?

0x81 (129) SUB_VAR_GAME - subtracts from game (global) variable
           param1: 1 byte ? - ID of the target Var ?
           param2: 2 bytes ? - value to subtract ?

0x82 (130) ADD_VAR_CUBE - adds to cube (local) variable
           param1: 1 byte ? - ID of the target Var ?
           param2: 1 byte ? - value to add ?

0x83 (131) SUB_VAR_CUBE - subtracts from cube (local) variable
           param1: 1 byte ? - ID of the target Var ?
           param2: 1 byte ? - value to subtract ?

0x84 (132) (unused) - unknown

0x85 (133) SET_RAIL - sets rail fork zone behaviour
           param1: 1 byte - (0..255) - rail zone ID (virtual)
           param2: 1 byte - (0..1) - flag: fork enabled

0x86 (134) INVERSE_BETA - (guessed) makes the actor turn by 180 degrees
           [no params]

0x87 (135) NO_BODY - makes the actor disappear
           [no params] ?

0x88 (136) ADD_GOLD_PIECES - adds to the actor’s money
           param1: 2 bytes ? - amount of gold pieces to add ?

0x89 (137) STOP_CURRENT_TRACK_OBJ (org. STOP_L_TRACK_OBJ) - pauses track script of another actor
           param1: 1 byte ? - ID of the target Actor ?

0x8A (138) RESTORE_LAST_TRACK_OBJ (org. RESTORE_L_TRACK_OBJ) - restores track script of another actor
           param1: 1 byte ? - ID of the target Actor ?

0x8B (139) SAVE_COMPORTEMENT_OBJ - (guessed) saves current comportement address of another actor
           param1: 1 byte ? - ID of the target Actor ?

0x8C (140) RESTORE_COMPORTEMENT_OBJ - (guessed) restores comportement of another actor
           param1: 1 byte ? - ID of the target Actor ?

0x8D (141) SPY - unknown
           param1: 1 byte ? - ???

0x8E (142) DEBUG - unknown
           [no params] ?

0x8F (143) DEBUG_OBJ - unknown
           param1: 1 byte ? - ID of the target Actor ?

0x90 (144) POPCORN - unknown
           [no params] ?

0x91 (145) FLOW_POINT - unknown
           param1: 1 byte ? - ID of the target Point ?
           param2: 1 byte ? - ???

0x92 (146) FLOW_OBJ - unknown
           param1: 1 byte ? - ID of the target Actor ?
           param2: 1 byte ? - ???

0x93 (147) SET_ANIM_DIAL - (guessed) sets animation for dialog
           param1: 2 bytes ? (0..32767) - ID of the animation ?

0x94 (148) PCX - displays full screen image
           param1: 2 bytes ? - ID of the fullscreen (PCX) image to show ?
           (or maybe two one-byte params?)

0x95 (149) END_MESSAGE - unknown
           [no params] ?

0x96 (150) END_MESSAGE_OBJ - unknown
           param1: 1 byte ? - ID of the target Actor ?

0x97 (151) PARM_SAMPLE - unknown
           param1: 2 bytes ? (0..32767) - ID of the sample ?
           param2: 1 byte ? - ???
           param3: 2 bytes ? - ???
           maybe more params like next one?

0x98 (152) NEW_SAMPLE - unknown
           param1: 2 bytes ? (0..32767) - ID of the sample ?
           param2: 2 bytes ? - length or pitch perhaps?
           param3: 1 byte ? - ???
           param4: 2 bytes ? - ???

0x99 (153) POS_OBJ_AROUND - unknown
           param1: 1 byte ? - ID of the target Actor ?

0x9A (154) PCX_MESS_OBJ - unknown
           param1: 1 byte - ID of the target Actor ?
           param2: 2 bytes - ID of the PCX image ?
           param3: 2 bytes - ID of the message text ?

Remarks:
1. Some Actors do not have any comportement (just SUICIDE, END) (like Scane 4, Cellar of Tavern, actor 3). In that case the main comportement should not be automatically created upon decompilation. It can probably be detected by checking if there is an END_COMPORTEMENT just before END.


================================
 SWITCH
================================

In parentheses there are byte sizes of the elements.

SWITCH(1) condition(1)
  CASE(1) addr_jump_if_not_equal_to_next_CASE(2) oper(1) value1(1/2)
    command block (executed when condition met)
  BREAK(1) addr_jump_to_END_SWITCH(2)
  CASE(1) addr_jump_if_not_met_to_next_OR_CASE(2) oper(1) value2(1/2)
    command block
  BREAK(1) addr_jump_to_END_SWITCH(2)
  OR_CASE(1) addr_jump_if_met_to_cmd_block(2) oper(1) value3(1/2)
  OR_CASE(1) addr_jump_if_met_to_cmd_block(2) oper(1) value4(1/2)
  CASE(1) addr_jump_if_not_met_to_DEFAULT_or_END_SWITCH(2) oper(1) value5(1/2)
    command block
  BREAK(1) addr_jump_to_END_SWITCH(2)
  DEFAULT(1) //not virtual, but why?
    command block
  BREAK(1) addr_jump_to_END_SWITCH(2)
END_SWITCH(1) //sometimes virtual, sometimes not

Remarks:
1. (OR_)CASE comparison values (the last param) are of variable size, depending on the return size of the Switch condition (variable).
2. BREAK is not required, but lack of it will not work like in C. Instead it will cause just more processing, but the script effect will be the same (e.g. Otringal, the lowest elevators, actor 0, where this is probably a mistake).
3. END_SWITCH is optional (e.g. Citadel Island Tavern, actor 8).
4. SWITCH can be nested (e.g. Baggage Claim 2nd room, actor 9), but the game engine does not stack up the switch variables, so all the variables used must return the same number of bytes (for CASE parameter). In original scripts there are some exceptions, like Demo Scene - Citadel Island, Twinsen & Zoé walking to Lighthouse, actor 3 - in such cases it is done so first top-level CASE has 2-byte param, then there is a nested SWITCH that uses 1-byte params, and subsequent top-level CASEs use one-byte param fromthat point. Not have to tell that it’s a really messy style.
5. The first command after SWITCH does not have to be CASE. In the original scripts there is sometimes a conditional block there (example: Citadel Island Tavern, actor 9), like this:

SWITCH condition1
  IF condition2 == v1
    CASE == v2
      commands
    BREAK
    CASE == v3
      commands
    BREAK
  ENDIF
  IF condition2 != v1
    CASE == v4
     commands
    BREAK
  ENDIF
END_SWITCH

The thing is that the last CASE and all BREAKs inside the first condition contain address of the first ENDIF, not of the END_SWITCH. In such construction the DEFAULT clause is probably not allowed.

6. Nested CASEs are possible (e.g. Hacienda 1st room, actor 6):

SWITCH condition
  CASE < v1
    CASE == v2
      commands
    BREAK
    CASE == v3
      commands
    BREAK
    DEFAULT
      commands
    BREAK
  BREAK
  CASE >= v4
    CASE == v5
     commands
    BREAK
  BREAK
END_SWITCH


====================================
 LIFE SCRIPT CONDITIONS (VARIABLES)
====================================

Conditions have opcodes and parameters, like regular commands, but they occur only after IF-type and CASE-type commands.
The conditional construction is following:

In case the condition doesn't have any parameters:

   byte: |     1     |      2      |     3     |        4         |  5 & 6
----------------------------------------------------------------------------
Command: |  IF-type  |  Condition  | Operator  | value to compare | address
----------------------------------------------------------------------------
Example: | 0x0C (IF) | 0x03 (ZONE) | 0x00 (==) |       0x03       | 0x002D

The bytes 5 and 6 are the address (offset) to jump to when the condition result is false (if it is true, the execution will continue to the lines following the conditional construction (no jump)).

In case the condition has a parameter:

   byte:|    1    |       2       |     3     |     4     |        5         |  6 & 7
--------------------------------------------------------------------------------------
Command:| IF-type |   Condition   | parameter | Operator  | value to compare | address
--------------------------------------------------------------------------------------
Example:|0x0C (IF)|0x04 (ZONE_OBJ)|   0x04    | 0x00 (==) |       0x03       | 0x002D

OR_IF - special case:
----------------------
OR_IF can be used to execute a block of code if at least one of the conditions is met. The syntax is following:

OR_IF ANIM == 1
OR_IF ANIM == 3
IF ANIM == 6
...code...
ENDIF

All the OR_IF lines must precede the IF line. Their compiled syntax is following:

   byte: |     1     |      2      |     3     |        4         |  5 & 6
----------------------------------------------------------------------------
Command: |   OR_IF   |  Condition  | Operator  | value to compare | address
----------------------------------------------------------------------------
Example: |   0x37    | 0x03 (ZONE) | 0x00 (==) |       0x03       | 0x002D

The syntax is the same as regular IF statement, but this time the addres bytes (5 and 6) contain an address where to jump when condition is TRUE. In case it is FALSE the execution will continue to the next line (no jump) (another condition should be there).

AND_IF - special case:
-----------------------
AND_IF can be used to execute a block of code if all of the conditions are met. The syntax is following:

AND_IF ANIM == 1
AND_IF ZONE == 2
IF CHAPTER == 3
...code...
ENDIF

and this is equivalent of nested IFs:

IF ANIM == 1
  IF ZONE == 2
    IF CHAPTER == 3
      ...code...
    ENDIF
  ENDIF
ENDIF

but ELSE will work slightly differently, because for the AND_IF the ELSE block will be executed if any of the condition has not been met. Achieving this with nested IFs would be much more complicated.

Order of the IF and AND_IF lines is not important.

The compiled syntax is following:

   byte: |     1     |      2      |     3     |        4         |  5 & 6
----------------------------------------------------------------------------
Command: |  AND_IF   |  Condition  | Operator  | value to compare | address
----------------------------------------------------------------------------
Example: |   0x70    | 0x03 (ZONE) | 0x00 (==) |       0x03       | 0x002D

The syntax is the same as regular IF statement, and the address bytes (5 and 6) have exactly the same meaning (where to jump when condition is false).

IF, AND_IF, and OR_IF can be mixed together in one conditional block, and their behaviour will depend on their order. Example 1:

AND_IF ANIM == 1
OR_IF ZONE == 2
IF CHAPTER == 3
...code...
ENDIF

The above code block will be executed if ANIM == 1 and (ZONE == 2 or CHAPTER == 3), while in this example:

OR_IF ZONE == 2
AND_IF ANIM == 1
IF CHAPTER == 3
...code...
ENDIF

the code block will be executed if ZONE == 2 or (ANIM == 1 and CHAPTER == 3).


Conditions (variables) list:
-----------------------------

Each condition has a specified range of values it can be compared with. For example COL can be compared to 1-byte values only. One can imagine the comparison values as "function return" values, but it doesn't exactly work this way. For example ZONE conditional will be always false if the Actor is not inside any Zone, no matter what value to compare is in the statement.


0x00 ( 0) COL - tests collision with another actor
          [no params]
          compare value: 1 byte (0..255) - ID of the Actor

0x01 ( 1) COL_OBJ - tests collision of two actors
          param1: 1 byte (0..255) - ID of the first Actor
          compare value: 1 byte (0..255) - ID of the second Actor

0x02 ( 2) DISTANCE - tests distance to another actor
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 2 bytes (0..32000) - distance to the target Actor in Scene units

0x03 ( 3) ZONE - tests if the actor is in a zone
          [no params]
          compare value: 1 byte (0..255) - ID of the Zone

0x04 ( 4) ZONE_OBJ -tests if another actor is in zone
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 1 byte (0..255) - ID of the Zone

0x05 ( 5) BODY - tests body of the actor
          [no params]
          compare value: 1 byte (-1..254) - ID of the body

0x06 ( 6) BODY_OBJ - tests body of another actor
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 1 byte (-1..254) - ID of the body

0x07 ( 7) ANIM - tests animation of the actor
          [no params]
          compare value: 2 bytes ? (0..32767) - ID of the animation

0x08 ( 8) ANIM_OBJ - test animation of another actor
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 2 bytes (0..32767) - ID of the animation

0x09 ( 9) CURRENT_TRACK (org. L_TRACK) - tests track label of the actor
          [no params]
          compare value: 1 byte (0..255) - ID of the Track Script LABEL

0x0A (10) CURRENT_TRACK_OBJ (org. L_TRACK_OBJ) - tests track label of another actor
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 1 byte (0..255) - ID of the Track Script LABEL

0x0B (11) VAR_CUBE - tests cube (local) variable
          param1: 1 byte (0..255) - ID of the Cube Var to test
          compare value: 1 byte (0..255) - value of the Cube Var to test

0x0C (12) CONE_VIEW - tests distance and angle to an actor
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 2 bytes (0..32000) - distance to the targer Actor in Scene units

0x0D (13) HIT_BY - tests if actor has been hit by another actor
          [no params]
          compare value: 1 byte (0..255) - ID of the Actor

0x0E (14) ACTION - test if player pressed ACTION button
          [no params]
          compare value: 1 byte (0..2) - 0 = no action, 1 = player is pressing "Action" command, 2 = unknown

0x0F (15) VAR_GAME - tests game (global) variable
          param1: 1 byte (0..255) - ID of the Game Var to test
          compare value: 2 bytes (0..65535 ?) - value of the Game Var to test

0x10 (16) LIFE_POINT - tests amount of life points
          [no params]
          compare value: 2 bytes (0..65535) - amount of life points to compare the current Actor's amount of life points with

0x11 (17) LIFE_POINT_OBJ - tests life points of another actor
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 2 bytes (0..65535) - amount of life points to compare the target Actor's amount of life points with

0x12 (18) NUM_LITTLE_KEYS - tests number of little keys kept by the hero
          [no params]
          compare value: 1 byte (0..255) - amount of little keys to compare the Hero's amount of little keys with

0x13 (19) NUM_GOLD_PIECES - tests number of gold pieces for the hero
          [no params]
          compare value: 2 bytes (0..999?) - amount of gold to compare the Hero's amount of gold with

0x14 (20) BEHAVIOUR (org. COMPORTEMENT_HERO) - tests hero’s behaviour
          [no params]
          compare value: 1 byte (0..?) - ID of the behaviour to test for the Hero (0 = normal, 1 = athletic, 2 = aggressive, 3 = discrete, 4 = proto-pack)

0x15 (21) CHAPTER - tests CHAPTER variable
          [no params]
          compare value: 1 byte (0..255) - value of the Chapter variable to test

0x16 (22) DISTANCE_3D - tests 3D distance to another actor
          param1: 1 byte (0..255) - ID of the target Actor
          compare value: 2 bytes (0..32000) - distance to the target Actor in Scene units

0x17 (23) MAGIC_LEVEL - tests hero’s magic level
          [no params]
          compare value: 1 byte (0..4) - Hero's magic level (0 = no level, 1 = yellow ball, 2 = green ball, 3 = red ball, 4 = fire ball)

0x18 (24) MAGIC_POINT - tests hero’s magic points
          [no params]
          compare value: 1 byte ? - amount of Hero's magic points ?

0x19 (25) USE_INVENTORY - tests if an inventory item has been used
          param1: 1 byte (0..255) - ID of the (inventory item to test?)
          compare value: 1 byte (0..255) - ???

0x1A (26) CHOICE - tests chosen answer to a question
          [no params]
          compare value: 2 bytes (0..32767) - ID of the text to check if it has been chosen

0x1B (27) FUEL - test amount of fuel for the hero
          [no params]
          compare value: 1 byte ? (0..255) - amount of fuel to test

0x1C (28) CARRIED_BY (org. CARRY_BY) - tests if actor is carried by another actor
          [no params]
          compare value: 1 byte (0..255) - ID of the Actor to test if the current Actor is being carried by it

0x1D (29) CDROM - (guessed) tests if cdrom is present
          [no params]
          compare value: 1 byte (0..255) - ???

0x1E (30) LADDER (org. ECHELLE, may also mean "scale") - unknown
          [no params] ?
          compare value: 1 byte ? - ???

0x1F (31) RND - tests for random value
          param1: 1 byte (0..255) ? - random range
          compare value: 1 byte (0..param1-1) ? - random value

0x20 (32) RAIL - tests for a rail zone state
          param1: 1 byte (0..255) - rail zone virtual ID
          compare value: 1 byte - zone fork state

0x21 (33) BETA - (guessing) tests for relative angle maybe
          [no params]
          compare value: 2 bytes ? - ???

0x22 (34) BETA_OBJ - (guessing) tests for relative angle between actors
          param1: 1 byte ? (0..255) - ID of the target Actor ?
          compare value: 2 bytes ? - ???

0x23 (35) CARRIED_OBJ_BY (org. CARRY_OBJ_BY) - tests if one actors carries another actor
          param1: 1 byte ? (0..255) - ID of the target Actor ?
          compare value: 1 byte ? - ID of the Actor to test if it is carried by the target Actor ?

0x24 (36) ANGLE - (guessing) tests for absolute angle
          param1: 1 byte - ???
          compare value: 2 bytes ? (-32768..32767) - ???

0x25 (37) DISTANCE_MESSAGE - unknown
          param1: 1 byte ? - ???
          compare value: 2 bytes ? - ID of the message ?

0x26 (38) HIT_OBJ_BY - tests if one actor has been hit by another actor
          param1: 1 byte ? - ID of the target Actor ?
          compare value: 1 byte ? - ID of the actor to test if he is being hit by the target Actor ?

0x27 (39) REAL_ANGLE - tests for real (absolute) angle
          [no params] ?
          compare value: 2 bytes (-32768..32767) - perhaps just shifted ANGLE

0x28 (40) DEMO - (guessing) tests for demo version?
          [no params] ?
          compare value: 1 byte ? - boolean if it is the demo version ?

0x29 (41) COL_DECORS - unknown
          [no params] ?
          compare value: 1 byte ? - ???

0x2A (42) COL_DECORS_OBJ - unknown
          param1: 1 byte ? - ID of the target Actor ?
          compare value: 1 byte ? - ???

0x2B (43) PROCESSOR - unknown
          [no params] ?
          compare value: 1 byte ? - ???

0x2C (44) OBJECT_DISPLAYED - unknown
          [no params] ?
          compare value: 1 byte ? - ???

0x2D (45) ANGLE_OBJ - (guessing) tests for absolute angle
          param1: 1 byte ? - ID of the target Actor ?
          compare value: 1 byte ? - ???

===============================
 LIFE SCRIPT OPERATORS
===============================

0x00 (0) ==  - tests if the Condition value is equal to the given value to compare

0x01 (1) >   - tests if the Condition value is larger than given value to compare

0x02 (2) <   - tests if the Condition value is less than given value to compare

0x03 (3) >=  - tests if the Condition value is larger or equal than given value to compare

0x04 (4) <=  - tests if the Condition value is less or equal than given value to compare

0x05 (5) !=  - tests if the Condition value is not equal to given value to compare

===============================
 GAME VARIABLES
===============================
  0: set to 1 after Twinsen gets the holomap
  2: set to 1 after Twinsen gets the darts. Probably the number of darts he has.
 40: set to 1 after Twinsen talks to Zoe at the beginning of the game.
194: set to 1 probably if Twinsen have done an action near the crashed spaceship (Citadel Island, at the Sendell’s Sign).
195: set to 1 if the wizards have been freed (at the Dark Monk’s Statue, room 1), otherwise it is 0.
