DDirectorWikiDirector & Lingo Encyclopedia

Native Runtime Architecture

The binaries behind Director MX 2004 and Shockwave - Dirapi.dll, Iml32.dll, Proj.dll - plus the reverse-engineering methodology and evidence standards used in this section.

What this section is

The pages under Native Internals document original reverse-engineering research into the Director MX 2004 / Shockwave native runtime, conducted with Ghidra against the retail binaries. Where the manuals describe what an API does, these pages record how the engine actually implements it: symbol tables, property descriptors, dispatch routes, compositor callbacks, and presentation logic.

Function names are Ghidra-style addresses (FUN_680c8c3e = function at that virtual address in Dirapi.dll). They are stable identifiers for the analyzed binaries, not official names.

Evidence levels

Every claim in this section carries an implicit strength grade:

LevelMeaning
manualStated in official MX 2004 documentation.
native tableName/symbol/string table found in the binaries: proves a surface exists, not its behavior.
native codeDecompiled implementation path: proves mechanics of that path.
microtestVerified against a real Director runtime with a fixture movie.
implementedReproduced in an emulator and confirmed by test/screenshot.

Rule of thumb: native code and microtests outrank guesses, other emulators' behavior, and AI review. A table slot proves a name exists; only tracing the consumer proves what it does.

The binaries

BinarySize (MX 2004)Role
Director.exe5.4 MBAuthoring app; contains authoring-side Lingo and API truth.
Dirapi.dll1.5 MBThe core runtime: Lingo VM, symbol registry, property descriptors, score engine, event dispatch, sprite channels.
Iml32.dll630 KBImaging/media layer: bitmap import, palettes, rects, windows (ImlWinCls), blitting, final compositor callbacks.
Proj.dll151 KBProjector shell: window creation, flag parsing, message loop, bridging to Dirapi ordinals.
Shockwave 10 dirapiX.dll / iml32X.dll1.7 MB / 611 KBThe browser player's equivalents; closest comparison layer for Habbo-era (2000-2005) behavior.
Shockwave 12 dirapi.dll / iml32.dll1.8 MB / 1.0 MBLate players; useful for spotting changed semantics.
*.x32 XtrasvariesNative plugins (TextXtra, Multiusr, NetLingo, Sound Control...).

Division of labor, as recovered:

  • Proj.dll parses projector settings, creates the stage window through IML32, and drives the runtime through a small set of Dirapi ordinals (idle pump, status readback, window rebinding).
  • Dirapi.dll owns everything scripting-visible: the symbol/descriptor machinery (Native Lingo internals), channels and their dirty flags, event routes.
  • Iml32.dll owns pixels and windows: rect helpers, DIB/palette Windows API usage, the final per-pixel compositor callback families (Native rendering).

Methodology

The workflow that produced these findings, reusable for further research:

  1. Define the question in Director terms (e.g. "what does ink 8 do to 4-bit sources?").
  2. String probe: locate API name strings and their addresses in the target binary.
  3. Table probe: follow references to those strings; Director API names sit in dense pointer tables, and the table neighborhood reveals the API family grouping.
  4. Decompile the consumers: never decompile a data table slot itself; find the code that reads the table and decompile that.
  5. Registry/descriptor dumps: for scripting symbols, decode the registrar call sites to get symbol ID -> descriptor pointer mappings (arguments often travel through callee-saved registers, so instruction-context dumps are the ground truth for missing immediates).
  6. Classify and trace: descriptor first-word distributions, branch classification in the shared executor, callback family mapping.
  7. Microtest: build a minimal fixture movie in real Director that exercises exactly one behavior, and log/compare.

Headless Ghidra automation ran each step; probe outputs (Markdown + JSON) are kept as evidence artifacts separate from conclusions, and conclusions link back to the artifact and address ranges.

Failure modes to avoid

Documented mistakes from this research, so others skip them:

  • Treating a table slot as code: decompiling data produces garbage; failure to decompile does not mean "no behavior".
  • Assuming neighboring names share a handler: table adjacency is organizational, not semantic.
  • Treating a string reference as the implementation: the reference is usually a registry row; the implementation is behind a dispatcher.
  • Trusting a fan emulator as ground truth: emulators encode their authors' guesses; verify against native code or a real runtime.
  • Row number = symbol ID assumptions: Director's symbol interner reuses IDs for duplicate names, so table position and ID diverge after the first duplicate (details in Native Lingo internals).
  • Changing runtime behavior in an emulator before the native owner is known: symptom-level patches (per-room, per-window offsets) always regress somewhere else.

Map of the findings

PageCovers
Native Lingo internalsSymbol bootstrap and interning, the 169-row API registry, descriptor record layout, the descriptor executor's branch families, emitted opcodes, native error codes.
Native renderingThe IML32 blit route, operation state, final compositor callback families (keyed copy, blends, arithmetic, color filter), matte/mask coverage streams, the sprite property to compositor bridge.
Native stage, input, and timingProjector flags and ordinals, presentation rect recompute (CenterStage/ResizeStage), window rebinding and channel rebuild, the input pipeline contract, score/timing table surfaces.