Riven external commands
Riven scripts make use of "external commands" to perform complex actions. External commands are code blocks living outside Mohawk files (hence "external"); probably they are part of the engine executable itself. Many complex devices in the game are implemented with external commands (for example the domes and the fire marbles puzzle); this is bad news because no reverse-engineering can be done on them easily. An alternative engine would have to implement custom code for those devices.
This page tries to clarify the role of each external command. It was put initially together by looking into NAME 3 resources, which store external command names used within each stack. Arguments and role of each external command were found or guessed by reading scripts.
Each command is reported in a way similar to C functions: command_name(argument1, argument2...). Names without trailing '()' have not yet been investigated.
- 1 a_Data
- 1.1 xastartupbtnhide()
- 1.2 xasetupcomplete()
- 1.3 xaatrusopenbook()
- 1.4 xaatrusbookback(), xaatrusbookprevpage(), xaatrusbooknextpage()
- 1.5 xacathopenbook()
- 1.6 xacathbookback(), xacathbookprevpage(), xacathbooknextpage()
- 1.7 xtrapbookback(), xatrapbookclose(), xatrapbookopen()
- 1.8 xarestoregame()
- 1.9 xadisablemenureturn(), xaenablemenureturn()
- 1.10 xalaunchbrowser()
- 2 b_Data
- 3 g_Data
- 4 j_Data
- 4.1 xflies(u0, u1)
- 4.2 xjplaybeetle_600(), xjplaybeetle_950()
- 4.3 xreseticons()
- 4.4 xicon(a)
- 4.5 xcheckicons(), xtoggleicon(a)
- 4.6 xjtunnel103_pictfix(), xjtunnel105_pictfix(), xjtunnel106_pictfix(), xjtunnel104_pictfix()
- 4.7 xvga1300_carriage()
- 4.8 xhandlecontroldown()
- 4.9 xhandlecontrolmid()
- 4.10 xhandlecontrolup()
- 4.11 xjplaybeetle_1450(), xjplaybeetle_1050(), xjplaybeetle_550()
- 4.12 xjlagoon700_alert()
- 4.13 xjlagoon800_alert()
- 4.14 xjlagoon1500_alert()
- 4.15 xschool280_playwhark()
- 4.16 xjatboundary()
- 5 o_Data
- 6 p_Data
- 7 r_Data
- 8 t_Data
- 8.1 xtexterior300_telescopedown(), xtexterior300_telescopeup()
- 8.2 xtisland390_covercombo(button)
- 8.3 xtatrusgivesbooks(), xtchotakesbook(), xthideinventory()
- 8.4 xt7500_checkmarbles()
- 8.5 xt7600_setupmarbles()
- 8.6 xt7800_setup()
- 8.7 xdrawmarbles()
- 8.8 xtakeit()
- 8.9 xtscpbtn()
- 8.10 xtisland4990_domecheck()
- 8.11 xtisland5056_opencard()
- 8.12 xtisland5056_resetsliders()
- 8.13 xtisland5056_slidermd(), xtisland5056_slidermw()
- 8.14 xtatboundary()
Used in the main menu card. Hides the "setup" (or "play riven") button by filling the hotspot rectangle with black and disabling the hotspot.
Called when clicking the "continue" button in the "volume adjustment" card.
Called after loading Atrus's journal card.
xaatrusbookback(), xaatrusbookprevpage(), xaatrusbooknextpage()
Called when clicking hotspots in Atrus's journal card.
Called after loading Catherine's journal card.
xacathbookback(), xacathbookprevpage(), xacathbooknextpage()
Called when clicking hotspots in Catherine's journal card.
xtrapbookback(), xatrapbookclose(), xatrapbookopen()
Called when clicking hotspots in the trap book card.
DVD Only: Called when clicking the restore game button in the main menu.
Demo Only: Called to allow you to return to the main menu from the game.
Demo Only: Called to start an internet browser to connect to the online store to buy the full game.
Called by the display update handler of card 278 (Gehn's lab journal). It must display the correct picture since the script doesn't.
Called by two hotspots of card 278 (Gehn's lab journal). They must handle the correct variable (probably blabbook) and update the display accordingly, since the script does nothing.
Called by several cards in their load handler (e.g. card 282, 284, 286, 288, 289).
Used by hotspots in cards 282 and 284 when acting on the boiler controls. It can have one or two args, both taking small numbers (1 to 4).
Used by hotspots in card 284 when acting on the boiler controls. The command is invoked towards the end of the scripts. Among other things it probably reloads (or redraws) the card to reflect the updated controls, as the scripts don't.
Called by the open handler for card 372 if the expression (bytramtime==0 && bytrap==1 && bbait==1) is true.
Called by the open handler for card 372 if bytramtime is not 0. a is 0.
Triggered by mouse down events in the bait (card 372).
Called when opening the ytram trap in card 372, if bytrapped is 1. Probably it just needs to play the movie showing the escaping ytram.
Triggered by mouse down events in the bait plate (card 372).
Reacts to mouse movements to let the user control the steam valve at the center of the lake (card 415). It must set variable bvalve accordingly.
The mouse tracking algorithm looks very complicated.
Called by the chipper lever hotspot (card 498) when the steam is correctly directed to the chipper. It must play the MLST record with code=2. Why an external?
Start the "flies" realtime effect. u0 seems always 0, u1 is a small number (< 10).
The effect is quite complicated as it randomly moves "flies", which look like tiny icons, around the card. Depending on parameters, their number seems to vary and different kinds of flies may be introduced (e.g. blinking ones).
Called in the load handler for card 66 and 82 respectively. Seems to just set jplaybeetle to 1 when the card beetle movie is to be played.
Called by an hotspot in card 191. Probably it resets the rebel puzzle icons.
Called by the load handler for some cards (e.g. 246, 247, 248).
Called by hotspots in cards belonging to the rebel puzzle icons (e.g. 217, 220, 221, 222...). Maybe a is an icon ID.
xjtunnel103_pictfix(), xjtunnel105_pictfix(), xjtunnel106_pictfix(), xjtunnel104_pictfix()
Called by display update handlers for cards 215, 216, 219 and 229 respectively. Probably they "fix" the picture by drawing the pressed icons.
Called by an hotspot in card 277.
Called when clicking on the handle inside the jungle elevator, when the elevator is at the top. It must track mouse movements, play the elevator movie and set involved variables.
Apparently, the algorithm is triggered by a single mouse movement, directed towards the bottom.
Called when clicking on the handle inside the jungle elevator, when the elevator is at ground level. It must track mouse movements, play the elevator movie and set involved variables.
Apparently, the algorithm is triggered by single mouse movements, directed towards the top or the bottom.
Called when clicking on the handle inside the jungle elevator, when the elevator is underground. It must track mouse movements, play the elevator movie and set involved variables.
Apparently, the algorithm is triggered by a single mouse movement, directed towards the top.
xjplaybeetle_1450(), xjplaybeetle_1050(), xjplaybeetle_550()
Called in the load handler for card 372, 408 and 68 respectively. Seem to just set jplaybeetle to 1 when the associated card beetle movie is to be played.
Called by the open handler for card 627. It handles the sunner reaction to the player presence.
Called by the open handler for card 629. It handles the sunner reaction to the player presence.
Called by the open handler for card 632. It handles the sunner reaction to the player presence.
Called when using the whark toy in the school (card 769). It must take care of playing the correct movies and all. Apparently it uses the jwharkpos variable to know the toy position.
Demo Only: Called when reaching the end of the demo.
Called in the open handler for card 9. Probably it handles the final scrolling credits.
Triggered by hotspots in card 35. It must play the closing book movie. Why an external for this?
xbookclick(movie_sref, start_time, end_time, u0)
Used in the open handler for card 2, with different parameters depending on the value of variables agehn and atrapbook. Maybe it handles clicks in the trap book while Gehn is holding it. start_time and end_time are large numbers, which I believe are milliseconds indicating when to listen for clicks. u0 may indicate one of the card hotspots.
Triggered by hotspots in card 81. It must play the closing drawer movie and maybe set ostanddrawer=0. Why an external for this?
Called in the display update handler of card 88. Probably places the correct journal picture in the card, using the variable value.
Called by hotspots in card 88. They must do everything to handle the journal.
Called when clicking on the watch hotspot in card 84. It must do everything (i.e. play the movie and the correct sound sequence, maybe set some variable).
Called in the open card handler for card 2. It must handle the scrolling credits and everything after that.
Called by the mouse down handler of a hotspot covering the whole screen (card 11).
Called by the mouse down handler of the journal hotspot in card 11.
Called in the load card handler for card 21.
Called when hitting the telescope button in card 137. Which external will be called depends on the state of variable ttelehandle (0→up, 1→down). The externals must
- inspect ttelecover, ttelepin, ttelescope, ttelevalve and ttelehandle
- increment/decrement ttelescope if needed
- play the correct movie span and the correct sound
- take care of playing the ending sequence if the variables are set correctly.
Called when clicking the telescope cover buttons. button is the button number (1...5).
xtatrusgivesbooks(), xtchotakesbook(), xthideinventory()
Called in this sequence in the "open card" handler for card 155, which is where the intro movie sequence takes place.
Called by the waffle activation button (card 221). It must check that the fire-marbles are placed correctly and set apower to 1 if this is the case, 0 otherwise.
Called on display update of card 223: it must draw the marbles at the correct locations in the waffle plate. This is not trivial since prespective must be applied! The marble icons are located in separate tBMP resources (IDs 526-531 in the CD version).
Called in load handler of card 225. Probably it takes care of moving the marble hotspots to the right locations.
Called on display update of card 225. Probably it takes care of drawing the waffle plate with the marbles at the right locations.
Called by marble hotspots in card 225, on mouse down. It must track mouse movements until mouse up, determine the new marble location, set any involved variable and load the card.
Apparently it must only play the dome scope button movie.
Used in the dome scope button click handler to determine if the button was hit at the right time. Sets variable domecheck to 1 if this is the case.
Called when opening card 386. It must display the slider to reflect its actual settings.
Called when hitting the dome button or closing the card (all in card 386). It must play the "slider reset" animation (with the ticking sound), bring back the sliders and maybe other things.
Both called by an hotspot laid over the whole dome slider, in its mouse down and mouse within handlers respectively (card 386). They must track mouse movements, play the ticking sound, set the slider value accordingly and enable/disable the two hotspots laid over the dome button if the combo is correct or incorrect.
Demo Only: Called when reaching the end of the demo.