Playing Doom in Favicon

Created on 01 May 2026

The Setup

Open silentspacemarine.com. It runs Doom in WASM on a normal canvas, which means the frame data is just sitting there.

The game is still played on the page. The favicon is just the world's least practical spectator mode.

The Paste

Open the browser console and run this:

(() => {
    const source = document.querySelector("#canvas");
    if (!source) throw new Error("Canvas #canvas not found");

    const size = 32;
    const intervalMs = 200;

    const iconCanvas = document.createElement("canvas");
    iconCanvas.width = size;
    iconCanvas.height = size;

    const ctx = iconCanvas.getContext("2d", { alpha: false, willReadFrequently: true });

    let link = document.querySelector('link[rel="icon"], link[rel="shortcut icon"]');
    if (!link) {
      link = document.createElement("link");
      link.rel = "icon";
      document.head.appendChild(link);
    }

    let lastUrl = null;
    let lastCapture = 0;

    function looksBlack() {
      const data = ctx.getImageData(0, 0, size, size).data;
      let bright = 0;

      for (let i = 0; i < data.length; i += 4) {
        bright += data[i] + data[i + 1] + data[i + 2];
        if (bright > 2000) return false;
      }

      return true;
    }

    function capture(now) {
      requestAnimationFrame(capture);

      if (now - lastCapture < intervalMs) return;
      lastCapture = now;

      ctx.drawImage(source, 0, 0, source.width, source.height, 0, 0, size, size);

      if (looksBlack()) return;

      const nextUrl = iconCanvas.toDataURL("image/png");
      link.href = nextUrl;

      if (lastUrl && lastUrl.startsWith("blob:")) URL.revokeObjectURL(lastUrl);
      lastUrl = nextUrl;
    }

    cancelAnimationFrame(window.__doomFaviconRaf);
    window.__doomFaviconRaf = requestAnimationFrame(capture);

    console.log("Running. Stop with: cancelAnimationFrame(window.__doomFaviconRaf)");
  })();

What It Does

That is it. Doom, but compressed into the one part of the browser UI nobody asked to animate.