Quick answer: Modern browsers block audio playback until the user interacts with the page (click, tap, or key press). If you play audio on “On start of layout” without a prior user gesture, the browser silently blocks it. Fix this by adding a “Click to start” screen, preloading audio files, including both WebM Opus and AAC formats, and handling mobile touch events to resume the audio context.
Here is how to fix Construct 3 audio that will not play in the browser. You add background music to your game, set it to play on start of layout, and preview it in Chrome. Silence. No errors in the console, no indication that anything went wrong. The game runs perfectly except there is no audio. Switch to Safari and the same thing happens. This is not a Construct 3 bug — it is a browser security policy, and it has a straightforward fix once you understand what is happening.
The Symptom
Audio does not play when the game starts. Background music set to play on start of layout produces no sound. Sound effects triggered by events (collisions, button clicks) may or may not work depending on whether the user has interacted with the page before the sound fires.
The browser console may show a warning like: “The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.” In Chrome, this appears as a small icon in the address bar. In Safari, there is no visible warning at all — the audio is just silently blocked.
You might also see audio work in the Construct 3 preview (because the editor page already has user interaction) but fail in an exported build opened in a new browser tab. Or audio works on desktop but not on mobile, where the restrictions are even stricter.
What Causes This
There are four common causes:
1. Browser autoplay policy. Since 2018, all major browsers implement an autoplay policy for audio. The Web Audio API context starts in a “suspended” state and cannot produce sound until a user gesture (click, tap, key press) resumes it. Construct 3 uses the Web Audio API for all audio playback. If you try to play audio before any user interaction, the browser queues the request but does not execute it. There is no error thrown — the playback simply does not happen.
2. Audio files not preloaded. Even after the user interacts with the page, audio files need to be downloaded and decoded before they can play. If you trigger a sound effect at the exact moment a collision occurs and the audio file has not been preloaded, there will be a delay or the sound may be skipped entirely. On slow connections, this delay can be several seconds.
3. Audio format incompatibility. Construct 3 supports WebM Opus and AAC (m4a) formats. If you only include one format and the user’s browser does not support it, the audio will not play. Safari historically has poor WebM Opus support, and some older browsers may not support AAC. Including both formats ensures every browser has a compatible option.
4. Mobile browser restrictions. Mobile browsers (iOS Safari, Chrome on Android) have additional restrictions beyond the desktop autoplay policy. iOS Safari requires a user gesture for each new audio element, and the gesture must be a direct tap — not a programmatic click event. Some mobile browsers also restrict the number of simultaneous audio channels, which can cause sounds to be dropped when many play at once.
The Fix
Step 1: Add a “Click to Start” screen. The most reliable fix is to require a user interaction before any audio plays. Create a title screen or start screen with a button that the player must click before the game begins.
// Title Screen layout event sheet:
+ Mouse: On click
-> Audio: Play "BackgroundMusic" looping at volume 0 dB (music tag "bgm")
-> System: Go to layout "Level1"
// Alternative: Use Touch for mobile support
+ Touch: On any touch start
-> Audio: Play "BackgroundMusic" looping at volume 0 dB (music tag "bgm")
-> System: Go to layout "Level1"
// Best practice: Handle both input methods
+ Mouse: On click
OR
+ Touch: On any touch start
OR
+ Keyboard: On any key pressed
-> Audio: Play "BackgroundMusic" looping at volume 0 dB (music tag "bgm")
-> System: Go to layout "Level1"
The first user gesture unlocks the Web Audio context. All subsequent audio playback works without restrictions for the rest of the session.
Step 2: Preload audio files. Use the Audio plugin’s Preload action to download and decode audio files before they are needed.
// Preload audio on the title screen while waiting for user input
+ System: On start of layout
-> Audio: Preload "BackgroundMusic"
-> Audio: Preload "JumpSound"
-> Audio: Preload "CoinCollect"
-> Audio: Preload "EnemyHit"
-> Audio: Preload "Explosion"
// For many audio files, preload in batches across ticks:
+ System: On start of layout
-> Audio: Preload "BackgroundMusic"
-> Audio: Preload "JumpSound"
+ System: Wait 0.1 seconds
-> Audio: Preload "CoinCollect"
-> Audio: Preload "EnemyHit"
Step 3: Include both audio formats. When importing audio into Construct 3, ensure both WebM Opus and AAC versions are generated. Construct 3’s audio importer does this by default, but if you are importing manually, check both formats exist in the Files folder.
// In the Project Bar > Sounds folder, each audio file should show:
// JumpSound.webm (WebM Opus - Chrome, Firefox, Edge)
// JumpSound.m4a (AAC - Safari, all browsers as fallback)
// If a format is missing, right-click the sound and re-import
// Make sure "Auto-convert" is enabled in the import dialog
// You can check format support at runtime with JavaScript:
// const audio = new Audio();
// console.log("WebM Opus:", audio.canPlayType('audio/webm; codecs="opus"'));
// console.log("AAC:", audio.canPlayType('audio/mp4; codecs="mp4a.40.2"'));
Step 4: Handle mobile audio context explicitly. On mobile browsers, you may need to resume the audio context explicitly in response to a touch event. Construct 3 handles most of this automatically, but for edge cases, use the scripting API.
// JavaScript: Explicitly resume audio context on user gesture
runOnStartup(async runtime => {
document.addEventListener("pointerdown", () => {
if (runtime.audio && runtime.audio.audioContext.state === "suspended") {
runtime.audio.audioContext.resume();
console.log("Audio context resumed");
}
}, { once: true });
});
Step 5: Use the silent audio workaround for persistent audio. If you need background music to start as early as possible without a dedicated start screen, you can play a silent sound on the first user interaction and then crossfade to the real music.
// Play a silent buffer on first interaction to unlock audio
// Then start the real music
+ System: On start of layout
-> System: Set GameStarted to 0
+ Mouse: On any click
+ System: GameStarted = 0
-> System: Set GameStarted to 1
-> Audio: Play "BackgroundMusic" looping at volume -60 dB (music tag "bgm")
-> Audio: Fade "bgm" volume to 0 dB over 1 second
Why This Works
Each fix addresses a specific point in the browser audio pipeline:
User gesture before audio satisfies the browser’s autoplay policy. When the user clicks, taps, or presses a key, the browser marks the page as “user-activated” and allows the Web Audio API context to transition from “suspended” to “running”. All audio played after this point works normally. This is a browser-level security feature designed to prevent websites from autoplaying annoying sounds, and it cannot be bypassed programmatically.
Preloading eliminates download latency. Without preloading, the first playback request triggers a network fetch, decode, and buffer creation sequence that can take hundreds of milliseconds. For sound effects tied to fast gameplay events, this delay causes the sound to arrive noticeably late or be skipped. Preloading front-loads this cost to a less critical moment.
Dual format support ensures codec compatibility. WebM Opus is the preferred format (smaller files, better quality at low bitrates) but Safari only added full support in recent versions. AAC is universally supported but produces larger files. By including both, you get the best format for each browser automatically — Construct 3’s Audio plugin handles the selection.
Explicit context resume handles edge cases where the automatic resume fails. Some mobile browsers have stricter requirements about which types of touch events count as “user gestures” for audio unlocking. Using pointerdown on the document ensures the broadest compatibility.
"Every browser game needs a start screen. It is not just good UX — it is the only reliable way to ensure audio works across all browsers and devices. Accept the autoplay policy and design around it."
Related Issues
If your game has a black screen instead of audio issues after a layout transition, see Construct 3 layout not loading / black screen on transition. For collision-triggered sounds that fire inconsistently, check Construct 3 collision not detected / overlap not triggering to ensure the collision events are firing correctly before investigating audio. And if animations that should trigger sounds are not playing, Construct 3 animation not playing or stuck on first frame may help resolve the root cause.
Start screen first, audio second. Every browser game, every time.