Quick answer: The loader layout is stuck because it is either not set as the first layout, it contains heavy objects that themselves need loading, the loader style is misconfigured, or large audio files set to preload are blocking progress. Make the loader the first layout, keep it lightweight, disable music preloading, and use the “On loader layout complete” trigger to transition to your game.
You built a loading screen with a progress bar and a nice logo. You set it as the first layout. You export the project, open it in a browser, and the loading screen appears — but the progress bar stays at 0%. Or it creeps to 30% and stops. The game never starts. Refreshing does not help. This is one of the most frustrating Construct 3 issues because the loading screen is supposed to be the simplest part of your game.
The Symptom
When you run your exported Construct 3 game (or sometimes even in preview), the loader layout appears but loading never completes. The behavior varies depending on the root cause:
The progress bar stays at exactly 0% and never moves. The page appears responsive (you can still interact with the browser), but the game never progresses past the loading screen. In the browser console, there may be no errors at all, which makes this especially confusing.
Alternatively, the progress bar reaches some percentage (often around 30–60%) and then stops. This usually indicates that a specific asset is failing to load or taking an extremely long time. The game appears frozen at that percentage indefinitely.
In some cases, the loader layout itself never appears. You see a blank white or black screen, and the browser’s loading spinner continues indefinitely. This is a different issue from the loader layout being stuck — this means the loader layout’s own assets cannot load.
What Causes This
There are five common causes for a stuck loader layout:
1. The loader layout is not set as the first layout. Construct 3’s loader system only works on the first layout in the project. If your game layout is first and the loader layout is second, the engine tries to load everything for the game layout before showing anything, and the loader layout is never used for its intended purpose. The order in the Project Bar determines which layout is first.
2. The loader layout contains objects that need preloading. This creates a chicken-and-egg problem. The loader layout is supposed to show loading progress while the rest of the game loads. But if the loader layout itself has a large Sprite with many animation frames, a complex Spritefont, or other heavy objects, those objects need to be loaded before the loader can display — and there is nothing to show progress while they load. This is the most common cause of a blank screen before the loader appears.
3. Large audio files are set to preload. Music files can be 5–15 MB each. If you have several music tracks set to preload, the loader has to download all of them before it can finish. On slow connections, this can take minutes, and the progress bar may appear stuck because the download progresses slowly. Worse, if the audio file URL is incorrect or the server has a CORS issue, the download will hang indefinitely.
4. The loader style is set to “None” without a custom implementation. If you set the project’s Loader style to “None,” Construct 3 will not display any built-in loading bar. If you also do not implement a custom progress display using the loader layout events, you will see a blank screen for the entire loading duration. The game may actually be loading fine, but there is no visual feedback.
5. The “On loader layout complete” trigger is missing or broken. After all assets are loaded, the engine fires the On loader layout complete system trigger. If your loader layout’s event sheet does not have this trigger, or if the action inside it does not navigate to another layout, the game will sit on the loader layout forever. Loading finished, but nothing told the game to continue.
The Fix
Step 1: Ensure the loader layout is the first layout in the project.
In the Project Bar, layouts are listed in order. The first one in the list is the one that runs first. Right-click your loader layout and select Set as first layout if it is not already first.
// Project Bar layout order should be:
// 1. LoaderLayout <-- This must be FIRST
// 2. MainMenu
// 3. GameLevel1
// 4. GameLevel2
// ...
// If GameLevel1 is first, no loader is shown.
// The engine tries to load ALL of GameLevel1's assets
// before displaying anything.
Step 2: Keep the loader layout as lightweight as possible.
Only use objects that have minimal loading overhead on the loader layout. Good choices are:
// SAFE objects for loader layout (tiny or no texture):
// - Text (no texture, renders from system font)
// - Tiled Background with a tiny 2x2 pixel image
// - Drawing Canvas (renders procedurally)
// - 9-Patch with a tiny source image
// - Sprite with a SINGLE small frame (e.g., 64x64 logo)
// AVOID on loader layout:
// - Sprites with many animation frames
// - Large background images (1920x1080+)
// - Spritefont with a large font sheet
// - Any plugin that loads external files
// - Particle effects with custom textures
Step 3: Build a progress bar with lightweight objects.
Create a visual progress bar using a Tiled Background or Drawing Canvas:
// Using a Tiled Background as a progress bar:
// Create a small (2x2 pixel) solid color image for the bar
// Place it on the loader layout, name it "ProgressBar"
// Set initial width to 0
Event: System > Every tick (on loader layout)
Action: ProgressBar > Set width to
lerp(ProgressBar.Width, LoadingProgress * ScreenWidth, 0.1)
// Also update a Text object with the percentage:
Action: LoadingText > Set text
round(LoadingProgress * 100) & "%"
Step 4: Disable preload on all music files.
In the Project Bar, expand the Sounds and Music folders. Click on each music file and in the Properties panel, set Preload to No. Short sound effects can remain set to preload.
// For each audio file in the project:
//
// Music files (large, 2-15 MB):
// background_music.ogg -> Preload: No
// boss_theme.ogg -> Preload: No
// menu_music.ogg -> Preload: No
//
// Sound effects (small, 10-200 KB):
// jump.ogg -> Preload: Yes (OK)
// coin_pickup.ogg -> Preload: Yes (OK)
// explosion.ogg -> Preload: Yes (OK)
// Load music on demand when you actually need it:
Event: On start of layout ("MainMenu")
Action: Audio > Preload "menu_music"
Event: Audio > On "menu_music" preload complete
Action: Audio > Play "menu_music" looping volume -10 dB
Step 5: Add the “On loader layout complete” trigger.
This is the trigger that tells the game to move past the loading screen. Without it, loading finishes but the game stays on the loader layout.
// In the loader layout's event sheet:
Event: System > On loader layout complete
Action: System > Go to layout "MainMenu"
// IMPORTANT: Do NOT use "On start of layout" to switch layouts.
// The loader layout starts immediately, before assets are loaded.
// If you switch layouts on start, the next layout's assets
// won't be loaded yet.
// WRONG:
// Event: On start of layout
// Action: Wait 3 seconds
// Action: Go to layout "MainMenu"
// This switches before loading is done!
Step 6: Debug loading issues with the browser console.
// Open browser DevTools (F12) and check the Network tab
// while the game loads. Look for:
//
// - Failed requests (red entries) - asset URL is wrong
// - Pending requests (grey) - download is stalled
// - Very large files - taking too long to download
//
// In the Console tab, check for CORS errors:
// "Access-Control-Allow-Origin" errors mean your
// assets are hosted on a different domain without
// proper CORS headers.
// You can also log loading progress from a script:
const runtime = getRuntime();
runtime.addEventListener("loadingprogress", (e) => {
console.log("Loading:", Math.round(e.progress * 100) + "%");
});
Why This Works
Construct 3’s loading system has a specific architecture. When the game starts, the engine loads only the assets needed for the first layout (the loader layout). Once those are loaded and the loader layout is displayed, it begins loading the assets for subsequent layouts in the background. The LoadingProgress system expression reports progress from 0 to 1 as these background assets download.
By keeping the loader layout lightweight, you ensure it can appear almost instantly. The engine only needs to load a few kilobytes of loader assets before it can start showing progress for the main game assets. If the loader layout itself has heavy assets, those must load first with no visual feedback, creating the appearance of a stuck or blank screen.
Disabling music preloading works because music files are by far the largest individual assets in most projects. A single 5 MB music file at typical broadband speeds takes less than a second, but on mobile networks it can take 10–30 seconds. Removing these from the preload list lets the loader complete with just sprite and sound effect data, which is typically much smaller.
The “On loader layout complete” trigger is the final piece of the pipeline. It fires exactly once, when all preloaded assets have finished downloading and are ready to use. This is the only reliable signal that the game is ready to begin.
“Treat the loader layout like a tent — it should go up fast with minimal materials. Everything else gets unpacked after the tent is standing.”
Related Issues
If your game loads but then crashes with a black screen, see WebGL context lost errors for GPU memory issues that can occur right after loading. If your game state disappears after navigating from the loader to the game layout, check global variable resets on layout restart. For multiplayer games where the loading screen causes connection timeouts, multiplayer signaling connection failures explains how to handle delayed connections. And if objects load but appear in the wrong visual order, Z order not updating at runtime covers rendering order issues.
Loader layout should be tiny. If it needs loading, who loads the loader?