Quick answer: Local Storage reads are asynchronous. Don’t read save data on “On start of layout” — request it there, then react in the On item get / On item missing triggers, and only then start the game.

A game reads LocalStorage.ItemValue for the high score on start of layout. It’s blank — the value hadn’t loaded yet.

Local Storage Is Async

“Check item exists” / “Get item” are requests. The result arrives later, on a separate trigger — not on the same tick you asked.

Request, Then React

On start of layout:
    LocalStorage → Get item "highscore"
    (show a loading state)

On item "highscore" get:
    Set highscore to int(LocalStorage.ItemValue)
    → ProceedToMenu

On item "highscore" missing:
    Set highscore to 0
    → ProceedToMenu

Both the “get” and “missing” triggers must lead into the same “now we’re ready” path — otherwise a first-time player (no save) hangs forever.

Batch Multiple Keys

Loading several keys? Request them all, count the responses, and proceed only when the count matches. Or store everything in one JSON key so it’s a single async round-trip.

Don't Block the First Frame

Show a brief loading state while the requests resolve. It’s usually milliseconds, but designing for “data arrives later” avoids the whole class of race bugs.

Verifying

Fresh browser (no save): game starts with defaults via the “missing” path. Returning player: real values load before the menu shows. No blank-data frame.

“Local Storage is async. Request on start, react on get/missing, then proceed.”

One JSON key for the whole save state turns N async round-trips into one — simpler and faster.