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.