Categories
contributions

GSoC 2026: Director Engine and Visual Debugger

Hi, I am Ramyak. My work centered on the Macromedia Director preservation effort in ScummVM: extending the ImGui-based visual debugger (DT), fixing engine compatibility bugs surfaced by the Gus games, implementing embedded movie cast members, and building screenshot-diff tooling into the ScummVM buildbot. All links below point to the pull requests.

Please refer to the links at the end of this post for weekly breakdowns.

Key deliverables

  • Movie cast members (#7752):
    embedded Director movies that run as parallel sprites, managing separate execution states while sharing global variables.
  • Visual Debugger:
    • Major features and changes in debug tools like:
      Lingo execution tracer (#7816):
      a flamegraph view inside the debugger that records Lingo execution for performance and control-flow analysis.

  • ImageDiff on buildbot:
    brought screenshot-diff regression testing into the ScummVM buildbot dashboard, plus a set of Director regression test movies, so rendering changes can be caught visually.
pic of the tool from dev chat
  • Games compatibility:
    Mostly for gus games: detection entries and a series of engine fixes (film loops, mouse dispatch, digital video, sound channels) that make the Gus titles playable. Some work was also done on trektech. The goal initially also included The Journeyman Project but since there were a lot of bugs in gus games, I did more work there instead.
movie paused at a breakpoint

Before the coding period I made around 10 contributions building the initial Director visual debugger and fixing film loop rendering, which laid the groundwork for the GSoC work.

Most of the PRs below are merged, three are in review.

Director visual debugger (DT)

  • #7553 Fix bugs and crashes throughout the visual debugger
  • #7564 Improve search and add a Windows panel
  • #7577 Improve cast details, add script browser navigation and keyboard shortcuts
  • #7612 Fix script not rendering in the script viewer
  • #7646 Fix crashes, stale state, and navigation in the debugger
  • #7690 Call-stack highlighting, Cast window improvements, and paused redraw
  • #7781 ImGui debugger improvements (sortable cast lists, thumbnail refreshing)
  • #7816 Add a Lingo execution tracer that records execution as a flamegraph (in review)

Director engine fixes and features

  • #7563 Fix empty cast slot error and immediate sprite drag in D4+
  • #7598 Add detection entries for Gus Goes to Cyberopolis (Windows and Mac)
  • #7614 Add detection entry for Gus Goes to Cybertown
  • #7620 Fix film loop shift when swapping a cast member with Lingo
  • #7633 Fix mouseUp dispatching to the wrong sprite in D4
  • #7727 Fix film loop D4 and D5+ behavior (freeze during pauses)
  • #7752 Implement movie cast members as parallel interactive movies
  • #7780 Fix trail-sprite erasure and 0x0 digital-video sizing
  • #7825 Share sound channels across the Stage and MIAWs (in review)
  • #7854 Fix Lingo point/rect operations and bitmap picture assignment (in review)

Backend

  • #7779 BACKENDS: SDL: Preserve SDL text input for active ImGui text fields

ImageDiff and buildbot infrastructure (scummvm-sites)

  • #39 Integrate the ImageDiff screenshot diff viewer
  • #40 Add pagination and default to the last page
  • #41 Replace image comparison with a file check
  • #42 Add ImageDiff integration using the wsgi-dashboards plugin
  • #43 Fix imports after merging imagediff.py into main.py

Director regression test movies (director-tests)

  • #4 D4-win: Text wrapping test movie with reference rendering
  • #5 D4 test movies for mouseUp dispatch and text wrapping
  • #7 D4-win/D5-win: clickOn manual test movie in both D4 and D5

Timeline

  • May 2026: Community bonding, Introduction
  • Jun to Jul 2026 (Weeks 1 2 3 4 5 6)
    Debugger fixes, Gus game compatibility, ImageDiff on buildbot; midterm passed mid-July.
  • Jul to Aug 2026 (Weeks 7 8 9 10 11 12)
    Movie cast members, film loop behavior, Lingo execution tracer, final polish
Categories
Week 12

Final Week

This week was mostly about one thing: finishing the remaining Gus game bugs.

Gus Paint

One of the bugs was in the inside() Lingo function, which was causing the Paint and Play buttons in Gus Paint to crash. I found the fix, but it was slightly wrong in its assumptions. I figured that out a couple of days later when I looked at it again and made the required change.

The game passes a proper POINT and the rect of cBackground, but cBackground is temporarily VOID during the first few frames. This meant inside() received (POINT, VOID) and fell through without returning a value, causing a fatal error.

Fixed it to return FALSE for invalid arguments instead of crashing. Sev also suggested using the existing TYPECHECK macros for handling the different argument types.

There were some other smaller bugs I worked on, like a textbox getting disproportionally larger incrementally with text input. funniest bug so far. fixed it. This one along with some more bugs, will be listed in the PR.

I spent a lot of time simply going through the games and reproducing things that looked wrong.

Over the last few weeks I have gradually gotten better at narrowing those problems down. Instead of immediately assuming that the game itself is doing something unusual, I can now usually trace the failing Lingo call into the engine and figure out what assumption ScummVM is making that the original Director did not.

Looking back

This week was mostly about cleanup: playing through games, finding the remaining failures, tracing them into the engine, and getting them into a state where they can be fixed properly.

And with that, GSoC is coming to an end.

Over the last 12 weeks I have worked on a fairly wide range of things in the Director engine: the ImGui visual debugger, movie cast members, film loops, Lingo debugging and profiling, ImageDiff and buildbot integration (-_-), game detection, and a lot of small engine and game compatibility fixes.

It has been a pretty different experience from working on a normal project. A lot of the time I was dealing with code and file formats that are decades old, trying to figure out not just what the original game is doing, but what Director itself must have been doing underneath it.

I’ll soon be posting a separate write-up covering the work I did over the full 12 weeks.

Because they need some testing, I”ll push the PR for the bugs soon. (Updating soon)

Upadate: https://github.com/scummvm/scummvm/pull/7854

that’s it for week 12 : )

Categories
Week 11

Lingo Tracer

So the highlight of this week is, as the title suggests, the Lingo tracer. I mentioned it in a recent blog. When I shared a screenshot with sev of the prototype I made, he said it seemed like a good idea and green lit it. This week was spent mostly on it, and getting it working was not that hard. The hard part was making it easy to use and understand.

The tracer records Lingo as it runs: every handler that gets called, when the score changes frames, and when a script is frozen and later resumed. It draws all of that as a flamegraph inside the ImGui debugger, so you can see which handlers ran, how they nested, and how long each one took. There is also a small stats table that sums the total and self time per handler, so the expensive ones are easy to spot. It stays off until you tick Capture, so it costs nothing when you are not using it.

Most of my time went into the reading experience. Frames and freeze/thaw markers sit in a thin strip at the top so the flamegraph below stays clean, tiny sub-pixel slices get merged so a busy trace does not turn into noise, and hovering one call highlights every other call with the same name.

fix

The other fix this week was a sound bug in gusmuse. Entering or leaving an area stacked the music tracks on top of each other, and the previous one never stopped.

In Director the sound channels are one shared resource between the Stage and any movie-in-a-window, but in ScummVM each window had its own sound manager, so a track started from one window could not stop a track from another.

I routed every window’s sound through the Stage’s manager, and now the channels are truly global.

That’s it for the week : )

Categories
Week 10

Small fixes and debugger polish

Mostly a normal week: two engine bugs, and a lot of sharpening the ImGui debugger.

Bugs.

Fixed the Cybertown cyberbud trails vanishing. The dirty channel check was comparing the raw _thickness byte, so a flipped tween bit falsely dirtied the channel and erased the trail. Fixed the Sink-or-Float “Prof. Gus’ face” (Talked about it here: week 5): a digital-video sprite the score sizes to 0×0 (an invisible timing clock) was being blown up to its native 240×180, so now it stays invisible. Also null-guarded a crash in endOfVideo().

Debugger (DT).

A sweep of bugs and quality of life fixes: killed ImGui::Text format string crashes in the script viewer, added some keyboard shortcuts, cached the cast browser rows, made the cast list sortable, added a Vars filter and copy value, refreshed stale thumbnails, added a movie cast member score viewer and a lot of other changes.

Lingo profiler.

I also spent part of the weekend on an experimental feature (for fun), a profiler for Lingo. It is still early, and I will come back to it later. For now the focus is wrapping up the Gus games.

Gus games status

  • gustown, guscarn: done
  • gusolis: 90% done
  • gusmuse: in progress
  • guspaint, guspark: remaining (still need to check how many bugs survive all the recent changes)

PRs

https://github.com/scummvm/scummvm/pull/7780
https://github.com/scummvm/scummvm/pull/7781
https://github.com/scummvm/scummvm/pull/7779