Quick answer: Drive the progress bar from the loadingprogress system expression (0–1), don’t do heavy work on the loader layout, and confirm it’s assigned as the Loader Layout in Project Properties.

A custom loading screen layout shows a progress bar frozen at 0% — the bar never reflects asset loading.

Use loadingprogress

Every tick:
    Set ProgressBar.Width to 400 * loadingprogress

loadingprogress is a System expression from 0 to 1 representing asset load completion. The custom loader layout updates it as files download — bind your bar to it directly.

Set It as the Loader Layout

Project Properties → Loader style = “Use loader layout”, and pick your layout. If the property still points at the default (or none), your custom layout never runs as the loader.

Don't Block the Loader Tick

The loader layout still needs to tick to update progress. Heavy synchronous work in its event sheet (big JSON parse, long loops) freezes the tick — progress appears stuck even though loading continues underneath.

First Layout Loads Fully

By default Construct loads all assets before the first real layout. The loader layout is what shows during that. If your first layout is huge, the loader has a lot to show — that’s expected; the bar should still move.

Verifying

On a fresh load (clear cache), the bar fills smoothly from 0 to 100% as assets download, then the first layout appears.

“Bind the bar to loadingprogress, assign the loader layout in Project Properties, keep its tick light.”

Test the loader with throttled network in DevTools — on fast connections it flashes by and you can’t tell if it actually works.