DEV Community

SkyWalker
SkyWalker

Posted on

A Capability-First Loading Screen for Browser Horror Games

Browser horror games often fail at the moment immersion is supposed to begin: audio is blocked, pointer lock is denied, a fullscreen request happens without a gesture, or saved settings are unavailable. A capability-first start screen turns those surprises into clear choices.

Detect support, but request permission later

Feature detection can happen during setup. Permission requests must stay behind a user action.

const support = {
  webAudio: "AudioContext" in window || "webkitAudioContext" in window,
  pointerLock: "pointerLockElement" in document,
  fullscreen: "fullscreenEnabled" in document,
  storage: storageAvailable()
};

function storageAvailable() {
  try {
    const key = "__horror_test__";
    localStorage.setItem(key, "1");
    localStorage.removeItem(key);
    return true;
  } catch {
    return false;
  }
}
Enter fullscreen mode Exit fullscreen mode

Do not call requestPointerLock() or resume an audio context during page load. Browsers expect a trusted click or key press.

Make one explicit start action

The start button can initialize audio and request pointer lock. Fullscreen should remain a separate opt-in control because it changes the whole display.

async function startExperience(canvas, audioContext) {
  const results = [];

  try {
    await audioContext.resume();
    results.push({ feature: "audio", ok: audioContext.state === "running" });
  } catch (error) {
    results.push({ feature: "audio", ok: false, error });
  }

  try {
    await canvas.requestPointerLock();
    results.push({ feature: "pointerLock", ok: true });
  } catch (error) {
    results.push({ feature: "pointerLock", ok: false, error });
  }

  return results;
}
Enter fullscreen mode Exit fullscreen mode

Failure should not trap the player. Offer keyboard turning when pointer lock is unavailable, captions when audio is muted, and a windowed layout when fullscreen is disabled.

Show a readable preflight summary

A small checklist is better than a generic compatibility warning:

  • Audio: ready, muted, or needs interaction
  • Mouse capture: available or keyboard fallback
  • Save data: persistent or session only
  • Motion: full or reduced
  • Flash effects: enabled or disabled

For reviewing how browser horror experiences introduce controls and different subgenres, Online Horror Games is a useful third-party directory reference. It should be presented as a curated directory, not as the developer of every listed game.

Preserve atmosphere without hiding consent

A start screen can still be atmospheric, but permission buttons need direct labels. “Enter” may look dramatic; “Start with sound” tells the player what will happen. Never disguise a fullscreen or notification request as ordinary navigation.

Listen for pointerlockchange and visibilitychange. When capture is lost or the tab is hidden, pause input and expose a clear resume action. Do not recapture the pointer automatically.

Test the failure paths

Test with autoplay blocked, sound muted at the operating-system level, pointer lock rejected, local storage disabled, reduced motion enabled, keyboard-only input, and a mobile browser without mouse capture. Also verify that pressing Escape restores a usable menu.

Capability checks are not about excluding older devices. They let the game choose a safe fallback before tension depends on a feature that might not be available. That creates a more reliable opening and avoids turning browser security prompts into the scariest part of the experience.

Top comments (0)