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;
}
}
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;
}
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)