Quick answer: GameMaker async_load[? "progress"] occasionally going backward? Mid-load events fire out of order; treat progress as best-effort.

Loading bar bounces back and forth as progress reports come in.

Max-track progress

progress = max(progress, async_load[? "progress"]);

Never reduce. Display monotonic.

Or aggregate multiple loads

If loading many assets, track per-asset progress; aggregate. Single bar; per-asset weighted.

Verify with multiple downloads

Issue 5 loads simultaneously. Progress should remain non-decreasing despite per-load variability.

“Async progress is best-effort. Display it deliberately.”

Loading bar UX is a small but visible polish point. Most loading bars are 'progress = whatever the engine says'; better than that with one line of code.

Related reading