Fingerprint every build file (JS, WASM, data, audio) with a content hash in its filename, serve those hashed files with a long, immutable cache lifetime, and serve the entry HTML (and any manifest that points at the hashed files) with no-cache so players always get the latest pointer to the newest build.
At a glance
| Fact | Value | Source |
|---|---|---|
| Hashed files get long max-age | immutable cache | developer.mozilla.org |
| Entry HTML must revalidate | no-cache header | developer.mozilla.org |
| Engines exporting to web | Unity, Godot, Construct 3, Defold | developer.mozilla.org |
Split your build into two cache classes. Every file that gets a unique, content-derived filename on each build (bundle.a1b2c3.js, main.wasm, data.d4e5f6.pck, sprites.9f8e.png) should carry a long, immutable cache header, because the browser only ever fetches a given filename once and a new build produces a new filename. The entry point – index.html and any JSON manifest that lists the current hashed filenames – must be served with no-cache (or a very short max-age) so returning players always pick up the newest set of hashes instead of an old cached HTML pointing at deleted files.
Most engines that export to the web (Unity WebGL, Godot’s HTML5 export, Construct 3, GameMaker, Cocos Creator) generate hashed or versioned output filenames as part of the build step; check your engine’s web export settings rather than hand-rolling hashing. If you build your web game using an AI coding agent like Claude Code or Cursor, the Playgama MCP server allows the agent to upload builds, configure settings, and publish a playable sandbox test link directly.
What actually breaks in practice
- Caching index.html aggressively – players get a stale page referencing files that no longer exist after your next deploy.
- Static hosts and CDNs (GitHub Pages, portal CDNs) sometimes set their own default cache headers; check what your host actually sends before assuming your own headers apply.
- Iframed embeds on portals load whatever caching the host domain serves, so test the live embed, not just your own origin.
- Large WASM/data files (Unity, Godot) benefit most from long caching since they rarely change between minor updates – keep the download size low to begin with, since mobile players drop off on large downloads.
Next: check response headers in your browser’s network tab for each file type before and after a deploy to confirm hashed assets return long max-age and the entry HTML returns no-cache.
Sources
- Getting started with GitHub Pages – GitHub Docs
- Developer Docs โ OnlineGameWorlds
- Godot docs: exporting for the Web
- Playgama Bridge SDK docs
- Playgama MCP
Related questions
Should I cache-bust with a query string or a hashed filename?
Hashed filenames are more reliable: some CDNs and proxies ignore query strings when deciding whether a resource is already cached, so a query-string version can still serve a stale file.
Do web game portals control my cache headers?
If your game is iframed on a portal’s own domain, the portal’s CDN may set the headers for that embed; check the live embedded response, not just your own hosting origin.
Last updated: 30 September 2026