daveisbest.org

Director’s commentary · Skip Intro

Running Flash in 2026

Can a Flash game from 2001 still run in a browser today? With Ruffle, yes. Where the original files are, and the period-style rebuild standing in for them until they turn up.

At college I lost an election in a building wallpapered with my name. I asked if I could help with the college website, they said no, so I made my own, in Flash, with games on it. After that, the computer room was wallpapered with my work instead. Disk 6 is meant to let you play one of those games: not a remake, the actual one. That raises two questions. Can you still run a Flash game from 2001 in a browser in 2026? And do I still have the files? The answers are yes, and not yet.

Flash after Flash

Adobe ended support for Flash Player at the end of 2020, and the browsers took the plug-in out. For a while that looked like the end of a whole era of the web. What saved it is Ruffle, an open-source Flash Player emulator written in Rust and compiled to WebAssembly. It runs .swf files in any modern browser with no plug-in, it can be self-hosted alongside the rest of a site, and it's what the Internet Archive uses to keep its Flash collection playable.

The timing helps me. A college site from 2001 would have been made in Flash 5 or Flash MX, with ActionScript 1, and that older half of Flash is the part Ruffle has supported longest and most completely. Later ActionScript 3 content has come a long way in Ruffle too, but a turn-of-the-millennium game with a preloader and some tweened buttons is exactly its home ground.

The hook that's waiting

The minigame host doesn't care what's inside a minigame. It hands over a DOM element and some context, and waits to be told the game is done. So the plan for real .swf files is written into the header of the rebuild: keep the period chrome around the stage, and swap the canvas for Ruffle's player.

/**
 * Canteen Dash (Disk 6, Skip Intro): one of the games from David's own college Flash site, rebuilt in
 * period style. Preloader stuck at 99%, an intro you can really skip, looping electronica with a
 * tiny mute button, then 45 seconds of catching chips and dodging homework.
 *
 * Options:
 *   duration  round length in seconds (5–120, default 45)
 *   best      previous best score from chapter state (default 0)
 *   intro     "skip" to go straight to the game's menu (replays, tests)
 *   swf       ignored for now; see the Ruffle note below
 *   autoplay  "1" makes the tray steer itself (dev harness and screenshots only)
 *
 * Completes, when the player presses "Back to the site", with
 *   { score: <last round>, skipped: false, data: { best, rounds, homeworkDodged } }
 *
 * Ruffle hook: if David finds the original .swf files, `options.swf` will carry a public path
 * (e.g. "/flash/canteen.swf"). Mount Ruffle's player (window.RufflePlayer.newest().createPlayer())
 * into `.fg-stage` in place of the canvas, keep the chrome, and call ctx.attempted() after the
 * first minute of play, since a real .swf can't tell us when a round ends.
 * TODO(David): do you still have the .fla or .swf files, and what were the games called?
 */
minigames/flash-game/index.tsx

The last clause is the interesting one. A real .swf can't tell the host when a round ends, and every minigame in the game can be skipped after one genuine attempt. So for an original file, a minute of play counts as the attempt. Ruffle would load only on this chapter, so the half a megabyte budget for the engine's JavaScript doesn't have to carry an emulator most visitors never need.

Canteen Dash, the stand-in

Until the files turn up, Disk 6 plays Canteen Dash, a period-style game standing in for the real ones. I don't remember what those were called, so this one is invented. You slide a lunch tray along the bottom of the screen, catch chips, pizza and the odd iced bun, and dodge the homework. It lasts 45 seconds, and the whole spawn schedule is worked out up front from a seed, so every round is repeatable and testable.

The details are where the period is. The stage is 550 by 400 pixels, which was Flash's default stage size, and a great many games of the era were exactly that shape. The type is Verdana. There's a looping electronica track with a mute button in the corner that's slightly too small. There's an intro, and its Skip intro button really does skip it. And there's a preloader that races to 99 percent and then sticks there for a moment, as the period demanded.

// The preloader: fast to 99%, then stuck there for a beat.
useEffect(() => {
  if (phase !== "preload") return;
  let raf = 0;
  const start = performance.now();
  const tick = (now: number) => {
    const t = now - start;
    if (t < PRELOAD_FILL_MS) {
      setProgress(Math.floor(99 * easeOut(t / PRELOAD_FILL_MS)));
    } else if (t < PRELOAD_FILL_MS + PRELOAD_STUCK_MS) {
      setProgress(99);
    } else {
      setProgress(100);
      later(() => {
        setPhase("intro");
        stageRef.current?.playIntro();
        startMusic();
      }, 180);
      return;
    }
    raf = requestAnimationFrame(tick);
  };
  raf = requestAnimationFrame(tick);
  return () => cancelAnimationFrame(raf);
}, [phase, later, startMusic]);
minigames/flash-game/index.tsx: fast to 99%, then stuck.
export const LANDSCAPE: Field = { width: 550, height: 400 };
export const PORTRAIT: Field = { width: 400, height: 520 };
minigames/flash-game/stage.ts: the default stage, and a taller one for phones held upright.

Phones held upright get a taller stage, because a 550 by 400 box on a portrait phone is a postage stamp. It only switches between rounds, so the field never changes shape under your tray.

The chapter around it goes Flash-era too. Its look posterises the whole 3D scene to six levels per channel, which is the old 216-colour web-safe palette, and adds a thin outline, so the college reads as flat vector art.

"skip-intro": look("skip-intro", {
  // Flash-era flat vector colour: six levels per channel is the web-safe palette
  post: ["grade", "posterize", "toon-outline"],
  params: { exposure: 1.02, contrast: 1.08, saturation: 1.1, posterize: 6, outline: 1.6 },
  uiSkin: "flash",
  background: "#cccccc",
  music: "flash-loop",
  ambience: "college",
}),
engine/looks/presets.ts

What's next

Finding the files. They could be on an old hard drive, a CD-R in a loft, or a college backup nobody has thought about in twenty years. The Wayback Machine may have captured my college site too, and it did sometimes keep the .swf files themselves as well as the pages around them. If the originals turn up, they run through Ruffle on an in-world monitor as genuine artefacts. If only the .fla source files turn up, they'd need opening and republishing first, which is a small archaeology project of its own.

And if they never turn up, Canteen Dash stays, and the narration says plainly that it's a rebuild. I'd rather have an honest remake than a fake original.