Quick answer: GameMaker sprite_add_async returning a sprite that doesn't appear in objects until the next step? Async load fires after the current step; assign in next step or via Async Image Loaded event.

Set sprite_index = sprite_add_async(url). Object draws as default sprite until step boundary.

Assign on Async event

if async_load[? "id"] == loading_id {
  sprite_index = async_load[? "id"];
}

Wait for the event before assigning. Sprite is ready at that point.

Show a placeholder

While loading, draw a placeholder sprite. Replace on completion. Players never see a blank.

Cache loaded sprites

Once loaded, store the sprite ID in a global map keyed by URL. Subsequent requests reuse; load latency disappears.

“Async loading is async. Synchronous assignment doesn't bridge the gap.”

Build an AssetCache singleton. Centralized async + caching; per-object code stays simple.

Related reading