DDirectorWikiDirector & Lingo Encyclopedia

Lingo Basics

Script types, handlers, events, syntax styles, and how Lingo code is organized inside a Director movie.

The shape of Lingo

Lingo is an event-driven scripting language. Code lives in handlers (functions named after the event or message they respond to) inside script cast members. When something happens (mouse click, frame change, network completion), Director sends a same-named message through a defined hierarchy of scripts, and the first matching handler runs.

lingo
-- a complete Lingo script: two handlers
on mouseUp me
  puppetSound "click"
  go to frame "menu"
end

on helloWorld
  alert "Hello World"
end

Three facts orient everything else:

  1. Lingo is case-insensitive for identifiers and keywords (MouseUp, mouseup, and mouseUp are identical). String contents are case-sensitive.
  2. Lingo is dynamically typed; a variable holds any type and can change type.
  3. Almost everything reacts to the playback head: the loop of frame events documented in Event lifecycle.

The five script types

TypeLives whereGets events forTypical use
Behavior (sprite script)Attached to a sprite span in the ScoreThat spriteButtons, draggables, per-sprite logic
Behavior (frame script)The script channel of a frameThat framego to the frame loops, frame setup
Movie scriptIts own script cast memberThe whole movieGlobal handlers, utilities, startMovie
Cast member scriptAttached directly to a media cast memberAny sprite showing that memberShared click behavior for a member
Parent scriptIts own script cast memberNothing until instantiatedOOP: create child objects with new()

The script type is a property of the script cast member (scriptType: #movie, #score, or #parent). Behaviors attached to sprites and frames are both "score" scripts; a cast member script is stored on the member itself and does not appear as a separate cast member.

Which script receives an event first, and how events fall through, is defined by the message hierarchy.

Handlers

lingo
on customHandler me, arg1, arg2
  return arg1 + arg2
end
  • on name ... end defines a handler. Arguments are untyped and optional at call sites (missing args arrive as VOID; extra args are dropped; the paramCount reports how many were passed).
  • In behaviors and parent scripts the first parameter is conventionally me: a reference to the script instance receiving the message.
  • return expr exits with a value; bare exit leaves the handler with no value.
  • Calling a handler that returns a value requires parentheses: x = myFunc(3). Command-style calls without a return value can omit them: myCommand 3.

Two syntax styles

Verbose (classic) Lingo and dot syntax coexist from Director 7 onward. Old game code freely mixes both, so you must read both:

lingo
-- verbose (Director 4-6 style; still runs in MX 2004)
set the locH of sprite 1 to 100
put the text of member "Greeting" into t
set x = the mouseH

-- dot syntax (Director 7+; recommended in MX 2004)
sprite(1).locH = 100
t = member("Greeting").text
x = _mouse.mouseH

Rules of thumb when reading old code:

  • the propName reads a global system property (the milliseconds, the key, the frame).
  • the propName of sprite n / member m is verbose object property access; identical in effect to sprite(n).propName.
  • set a = b, set a to b, and put b into a are all assignment. Plain a = b also assigns in D7+ code.
  • put expr with no destination prints to the Message window (debug output).

JavaScript syntax (MX 2004)

Director MX 2004 added a JavaScript 1.5 syntax layer over the same object model. A script cast member is either Lingo or JavaScript syntax; both can coexist in one movie and call each other's handlers.

javascript
function mouseUp() {
  sprite(1).locH = 100;
  member("Greeting").text = "Hello";
  _movie.go("Main");
}

Notes for readers and emulator authors:

  • JavaScript syntax is case-sensitive; Lingo is not. The bridge normalizes handler names.
  • Lingo lists map to Director list objects (list(), propList()), not JS arrays; JS arrays are also available but are a different type.
  • Lingo symbols appear as symbol("name").
  • The global facades _movie, _player, _mouse, _key, _sound, _system, _global are the shared object model both syntaxes target.

In practice, preservation targets (1998-2005 web games, CD-ROMs) are almost entirely classic Lingo; JavaScript syntax movies are rare.

Comments, continuation, whitespace

lingo
-- this is a comment (double hyphen)
x = 5 -- trailing comments work too

-- line continuation: backslash in MX 2004 listings,
-- the "¬" character (Option-Return) in older code
total = price + tax + \
        shipping
  • Blank lines and indentation are insignificant (indentation is convention only).
  • One statement per line; there is no statement separator character.
  • The continuation character in pre-MX code is ¬ (0xAC); MX 2004 documentation shows \. Decompilers usually emit single long lines instead.

Minimal working examples

A frame loop (the single most common Lingo idiom in existence):

lingo
on exitFrame
  go to the frame
end

A button behavior:

lingo
property pDown

on mouseDown me
  pDown = TRUE
  sprite(me.spriteNum).member = member "btnPressed"
end

on mouseUp me
  pDown = FALSE
  sprite(me.spriteNum).member = member "btnNormal"
  if rollover(me.spriteNum) then doButtonAction me
end

Movie initialization:

lingo
global gScore

on prepareMovie
  gScore = 0
  the itemDelimiter = ","
end

Where to go next