All articles
Storage 2026-06-03 · 9 min read

Saving a best score with no account and no server

These games remember your best score without knowing who you are. That is a design decision as much as a technical one.

Every game here keeps a best score. None of them has a login, and none of them sends anything anywhere. The score lives in the player's own browser, which turns out to be both the simplest implementation and the most defensible one.

What local storage actually is

It is a small key-value store owned by the browser, scoped to the site's origin, and persisted between visits. Writing a number to it is one line; reading it back is one line. There is no server involved, so there is no latency, no failure mode when the network drops, and nothing stored about the player anywhere except their own device.

The limitations are worth stating plainly, because they are the reason a saved score is not a promise. It belongs to one browser on one device. Clearing browsing data deletes it. It does not follow the player to another phone, and it is not recoverable. For a high-score table on an arcade game, that is a fair trade. For anything a player would be upset to lose, it is not, and a product that cares about that has to accept accounts and a server.

Never assume the write succeeded

Storage can be unavailable: private browsing modes, storage disabled by policy, or a quota that has been exhausted. None of that should break a game. Every read here defaults to zero when anything at all goes wrong, and every write is wrapped so that a failure is silent. A player who cannot save should experience a game that simply forgets their score, not a game that throws an exception on the first frame.

The sandboxed-host case

A game running inside a host platform may not be allowed to touch local storage at all. Such a host provides its own key-value API instead, and the game uses it when it is present. That read is asynchronous, which has a real consequence: the game cannot know the stored score at the moment it starts drawing, so it begins with the best score treated as unknown and fills it in when the answer arrives.

It also means the read needs a timeout. A host API that never resolves would otherwise leave the game waiting forever before its first frame. Every host call here is guarded, given a short deadline, and treated as a default on failure — the game always starts, whatever the host does.

Store the least you can

The only thing persisted is a single integer. There is no player profile, no history, no settings object and no identifiers. The smaller the stored state, the smaller the surface for a bug, a quota problem or a privacy question, and a high score is genuinely all that is needed for a game whose sessions last a minute.

If a game does need more — a level reached, a set of unlocked items — the same rules apply: a single small object, written rarely, read defensively, and never depended on for correctness. The game must be fully playable by someone who is saving nothing at all.

Want to go deeper?

Building something for the browser? Send us a link and we will tell you honestly whether it fits.

Talk to us