Saving the Masters of the Elements From Getting Lost to Time: Part 3
Published at , last update 2025-08-31 16:40:09#windows #retrogaming #preservation
Table of contents
I briefly talked about Xtras and XObjects in the first part of this series. To recap, Xtras and XObjects are specially crafted libraries that extend Macromedia Director’s functionality by exporting additional functions that can then be used in the Lingo scripts powering the individual application. This allows a deeper integration with the operating system, since the Xtras and XObjects can provide a bridge between Macromedia Director and the operating system’s API.
Masters of the Elements uses such a third-party XObject for controlling the mouse cursor as we discovered in the previous articles.
Now that we know how it breaks the game and what it actually does, it is time to look for a proper replacement.
Finding the Xtra
Thankfully, the Macromedia Director community was very active back in the day, featuring countless developers who created both commercial and non-commercial Xtras. When looking for an Xtra that covers a specific function, the place to go is the Director Mile High Table O’Products provided by Dean’s Director Tutorials. This website is an incredible resource for anything related to Macromedia Director, so I highly recommend checking it out if you are interested in learning more!
In the Mouse and Keyboard section of this list, I spotted two possible candidates for a replacement: SetMouseLoc Xtra by Laurent Cozic, and SetMouseXtra by Stephan Eichhorn from Scirius Development.
According to the Director Mile High Table O’Products list, SetMouseLoc Xtra is only compatible with Macromedia Director 8.5 and higher. Since we are working with a game made with Director 6.0.2, choosing this Xtra is not a viable option. SetMouseXtra, however, claims to be compatible with Macromedia Director 5 to 11. Since SetMouseXtra is distributed as freeware without any special licensing requirements, this seems to be an excellent choice.
Looking at the interface description of SetMouseXtra reveals that this Xtra is not only a viable option, but a complete match. It exports one function, and expects the same parameters as PUTCURS.dll does: The x and y coordinates.
xtra SetMouseXtra -- Version 1.0
-- --------------------------------------------------------------------
-- this Xtra allows to set the mouse position through Lingo
-- --------------------------------------------------------------------
1997 by Stephan Eichhorn, Scirius Multimedia
-- e-mail: <redacted>
-- WWW: http://www.scirius.com
* SetMouse integer x,integer y -- set the cursor to position x,y
-- all x,y are in screen coordinates,
-- not relative to the stage!
The Integration
After downloading the .zip archive with the Xtra files, I extracted the file SMXTRA.X32 from the Windows directory inside the archive to the XTRAS directory of my copy of the game.
Contrary to the old XObjects, the newer Xtras introduced with Macromedia Director 5 support autoloading. As soon as the Xtra is placed in the application’s XTRAS directory, all functions will be available immediately after startup without having to use OpenXLib. Both the old XObject and our new Xtra are so similar that we can use it as a simple drop-in replacement by modifying the moveTheCursor function, where we replace the old myMouse(mSet...) call with SetMouse().
Old function call
on moveTheCursor X, y
...
if platform = #windows then
set offSetX to the stageLeft + (4 * (the runMode = "Author"))
set offSetY to the stageTop + (42 * (the runMode = "Author"))
myMouse(mSet, integer(X + offSetX), integer(y + offSetY))
else
...
end
New function call
on moveTheCursor X, y
...
if platform = #windows then
set offSetX to the stageLeft + (4 * (the runMode = "Author"))
set offSetY to the stageTop + (42 * (the runMode = "Author"))
SetMouse(integer(X + offSetX), integer(y + offSetY))
else
...
end
This is how the final script looks after replacing the “broken” calls to the old XObject with the new ones from our replacement Xtra:
on definePlatform
global platform
if the machineType = 256 then
set platform to #windows
else
set platform to #macintosh
end if
end
on initCursorObject
global myMouse, platform, objectPath
if platform = #windows then
else
openXLib(objectPath & "MoveMous.XOB")
set myMouse to MoveMouse(mnew)
end if
end
on exitCursorObject
global myMouse, platform, objectPath
if platform = #windows then
else
closeXLib(objectPath & "MoveMous.XOB")
end if
end
on moveTheCursor X, y
global myMouse, platform, offSetX, offSetY
if platform = #windows then
set offSetX to the stageLeft + (4 * (the runMode = "Author"))
set offSetY to the stageTop + (42 * (the runMode = "Author"))
SetMouse(integer(X + offSetX), integer(y + offSetY))
else
myMouse(mSetMouseLoc, integer(X), integer(y))
end if
set a to the mouseH
end
What about Macintosh?
The modified script works on both Windows and Macintosh, since I left the parts specific to Macintosh intact. However, it is very unlikely that this modified file will ever affect a Macintosh version. Masters of the Elements is distributed as a so-called “Hybrid disc”, which means that the disc contains two distinct file systems. The ISO9660 file system, which you probably know from .iso files, contains all the files that are responsible for the Windows version. The Macintosh files, however, are stored in a separate HFS file system on the same disc.
On a Windows system, the HFS partition won’t even be visible without using third-party tools. Hence, the chance of unvoluntarily overwriting the “wrong” file is pretty much zero, but for the sake of completeness, I didn’t unnecessarily remove the Macintosh integration.
There and Back Again
Finally, after more than 20 years, the game is fully playable again. I replayed the first scene in the Room of Gravity and successfully solved the Room of Warmth. Yes, I had to cut the video a bit; I’m not that great at baking pancakes, and I couldn’t trigger the shortcut through the egg at the juggling puzzle.
Fun fact: If you are running the game on a slower system, it gives you an advantage by slowing down the animation speed. “Slower” in this context means something along the lines of a Pentium 133. To determine the system speed, the game runs a couple of checks at the beginning of the game, where it tries to draw sprites and transitions as fast as possible. If you are below a certain threshold, then the code path that slows down the entire game triggers.
I wonder if I can use this to create a cheat that makes the game easier. Oh, and there’s one thing left to do.
Do you have any comments or suggestions regarding this article? Please drop an e-mail to feedback@fabulous.systems!