DDirectorWikiDirector & Lingo Encyclopedia

Event Lifecycle

The exact order of movie startup, per-frame, and shutdown events - prepareMovie, beginSprite, prepareFrame, enterFrame, exitFrame, endSprite, stopMovie.

Why order matters

Every Director movie is written against an implicit contract: which handler runs before which. Games initialize globals in prepareMovie, position sprites in beginSprite, animate in prepareFrame, and read results in exitFrame. Get the order wrong in an emulator and logic silently corrupts. This page states the documented order; native verification status is tracked in Native stage, input, and timing.

Movie startup

text
prepareMovie
beginSprite      (for sprite spans present in the first frame)
prepareFrame     (before the first frame draws)
startMovie
[first frame renders]
enterFrame
...normal frame cycle continues
  • prepareMovie: first event. No sprites exist yet; the stage has not drawn. Initialize globals, parse startup parameters, install alert hooks.
  • beginSprite: fired as the playhead enters each sprite span; behavior instances are created just before delivery. In frame 1 this lands after prepareMovie, before prepareFrame.
  • prepareFrame: last stop before drawing; state changes here affect the imminent render.
  • startMovie: after the first frame is prepared; the classic "movie is ready" hook (Director 4 code often has ONLY this).

Every frame

text
beginSprite      (only for spans that START this frame)
stepFrame        (to every object in the actorList)
prepareFrame     (behaviors, frame script, movie script)
  [sprites drawn; stage updates]
enterFrame
  [tempo wait, idle events, mouse/key events dispatched while waiting]
exitFrame
endSprite        (only for spans that END this frame)
[playhead moves]

Facts per event:

EventReceived byNotes
beginSpriteNew sprite's behaviors, then normally routedOnce per span entry. Calculated properties (e.g. rect) may be unready; go, play, updateStage are disabled inside it.
stepFrameactorList objects onlyAlso fires on every updateStage(). Engine-dispatched; cheaper than message broadcast.
prepareFrameSprite behaviors, frame script, movie scriptRuns before drawing. The place to move sprites so the user never sees the pre-move state.
enterFrameSprite behaviors, frame script, movie scriptRuns after drawing. A frame script's enterFrame shadows the movie script's for that frame.
idleFrame script and movie script onlyFires repeatedly while Director waits out the tempo. Frequency capped by the idleHandlerPeriod (default 0 = as often as possible). Keep handlers tiny.
exitFrameSprite behaviors, frame script, movie scriptLast event in the frame. go to the frame here creates the idle loop that most movies live in.
endSpriteEnding sprite's behaviorsOnce per span exit; instance is destroyed after.

Mouse and keyboard events are delivered in the waiting window between enterFrame and exitFrame (and during idle time generally). They are not synchronized to a specific point in the frame cycle; see Input events.

Movie shutdown

text
endSprite        (for all live sprite spans)
stopMovie

stopMovie fires when playback halts or the movie is replaced by go to movie. On a cross-movie jump, the outgoing movie gets endSprite+stopMovie, then the incoming movie runs its full startup sequence. Globals, actorList, timeout objects, and windows persist across the jump (see Pitfalls).

updateStage() inside a handler

_movie.updateStage() redraws immediately without advancing the playhead:

text
caller handler (paused mid-execution)
  stepFrame        (actorList)
  [stage redraw]
caller handler continues

It does not fire prepare/enter/exitFrame. Code uses it for progress bars and blocking animations inside repeat loops. updateStage is disabled inside beginSprite/endSprite.

go, play, and re-entry

  • go to frame X inside a handler finishes the current handler first; the head then moves: current frame gets exitFrame (and endSprite for spans ending), target frame gets the entry half of the cycle (beginSprite, prepareFrame, ...).
  • go the frame re-runs the same frame's cycle without span changes (no beginSprite/endSprite, since no span boundary is crossed).
  • Navigation is deferred, not immediate: statements after go in the same handler still execute. (play done behaves likewise.)
  • Tight loops on one frame are the idiom for "game loop"; per-frame work belongs in exitFrame/prepareFrame handlers of that frame.

Timeout and network callbacks

Timeout handler messages and net-operation completions are delivered between frame events on the main thread (never preemptively during another handler). A blocked handler (long repeat loop) delays everything: rendering, input, timeouts, sound cues. The single-threaded model is a compatibility guarantee old code relies on: no handler ever observes another handler running mid-statement.

Test checklist for implementers

  1. Movie start: prepareMovie -> beginSprite(frame-1 spans) -> prepareFrame -> startMovie.
  2. Frame N->N+1 with a span starting at N+1: old frame exitFrame -> new beginSprite -> stepFrame -> prepareFrame -> enterFrame -> ... -> exitFrame.
  3. Span ending at N: endSprite after N's exitFrame, before N+1's beginSprite.
  4. updateStage() triggers stepFrame + redraw only.
  5. beginSprite restrictions: rect unready, go/play/updateStage inert.
  6. idle only reaches frame/movie scripts.
  7. Cross-movie jump ordering and state persistence.