SCUMM internals and syntax for the sake of nostalgia

April 17, 2018

I spent an unbelievable amount of time playing games from the LucasArts franchise circa 1999 in an Intel 486. It was already an old computer at the time, but it was more than enough to play games like Maniac Mansion and Monkey Island.

As I grew up and learned more about computers, I found that "SCUMM" wasn't just the name of a bar in Monkey Island, it was the platform on which all my favorite childhood games were programmed on.

This post explores the SCUMM scripting language based on a list of sources, from talks to interviews and various posts.

Brief History

SCUMM stands for "Script Creation Utility for Maniac Mansion", and as the name implies, it was created as to serve as a toolset to develop Maniac Mansion.

The game had to work in a Commodore 64, so as it was done with other games at the time, it was first developed in Assembly.

Sooner than later, in order to deal with the complexity of the game (it had seven different characters and a huge amount of combinations), Ron Gilbert decided to create a higher level syntax:

I started kind of hand-coding it all in assembly language, [...] and it was just obvious this was going to be a very difficult task without some kind of a language to be able to abstract the gameplay.

Ron Gilbert, interview for IGN

Once Maniac Mansion was finished, they realized that SCUMM could be used as a general purpose tool to create adventure games.

It's worth noting that SCUMM wasn't only a scripting language, it also included other utilities named after body fluids like SPIT (a font editor) and FLEM (a graphical interface.)

Concepts and Syntax

The syntax of SCUMM scripts is really high level and strongly related to the graphics interface of the adventure games:

Screenshot of a scene of Maniac Mansion gameplay.
Screenshot of a scene of Maniac Mansion gameplay portraying a typical SCUMM interface: a character, objects to interact with and actions.

If you haven't played any of the old school LucasArts adventure games (and I really encourage you to do it), they consist of a story/puzzle to solve, you are in control of a character, which is able to interact with objects via a set of predefined actions placed at the bottom of the screen.

The scripting language itself is a very well done abstraction: it has almost a 1:1 mapping regarding what you see in the screen to what you code, and is based upon simple concepts/keywords like:

Doing a more detailed summary of the syntax would be pointless, but if you are interested, the SCUMM Tutorial is an in-depth resource. You can even compile your code later on with SCUMMC and SCUMM-8.

To give you a taste of what a bit of code may look like, let's try to code the scene in the image above (Dave in the doorstep)

room "doorstep" doorstep {
  sounds {
    "SFX/doorclos" door-close
    "SFX/dooropen" door-open
  }

costumes { "costumes\dave" dave-skin }

enter { ; Code to set up the room lives here, ; you can trigger sounds, animations, etc. }

exit { ; Things to do when exiting the room, ; cleaning states, stopping sounds, etc }

object Key { name is "key"

<span style="color:#204a87;font-weight:bold">verb</span> look-at {
  say-line "it is a key"
}

<span style="color:#204a87;font-weight:bold">verb</span> pick-up {
  pick-up-object key
}

} }

Multitasking

Probably the most distinctive part of SCUMM was that it was multi-tasking. This meant that multiple scripts could effectively run simultaneously. You might create a clock on the wall in Zak McKracken’s office and have it animate. There would be a single, very simple script just for the clock that would tell the animation engine to change from one image of the clock to the next, tell the sound engine to play the “tick” sound, and then tell the script to “sleep-for 1 second” and then repeat.

Aric Wilmunder, Gamasutra interview

Another of the outstanding points of SCUMM is how easy it made for the developer to add cooperative multitasking into the system. You could trigger a task with the do keyword and the task will keep running once per frame until it hits a break-here, then it runs the next task.

For example, in the next image, we can think that every ghost pirate and the shadow moving in the background is a separate script running on its own:

5ad7c8f06a421525259541

Here's a script transcripted from Gilbert's talk which details how you would make a clock tick:

script clock-tick {
  do {
    clock-state = not clock-state
    object living-room-clock state clock-state
    play-sound clock-tick
    break-here 60
  }
}

Other interesting bits

To wrap up, here are some bits that may be interesting:

Resources