TETERI
How TETERI is built
Making It Work Offline Properly
Cache the shell, revalidate in the background, and never serve a mix of old and new modules.
A service worker turns the game into something that starts instantly and works with no connection. Doing it correctly requires a little care.
The precache
On install, the worker fetches and stores the app shell: the HTML, stylesheets, every JavaScript module, the icons and the manifest. Each is added individually so one missing file cannot fail the whole installation.
The serving strategy
Same-origin requests are served cache-first, then quietly re-fetched in the background and the cache updated. That is stale-while-revalidate, and it has one property that matters enormously for an ES module app:
A whole page load is served from one generation of the cache. You never get a new main.js alongside an old render.js, which would fail in ways that are extremely confusing to debug.
The cost is that a change lands on the player's second load rather than the first. Bumping the cache version drops the old cache entirely and makes it land immediately.
Navigations are different
Page navigations try the network first and fall back to cache. That way a fresh deploy is picked up promptly when a connection exists, while the game still opens when it does not.
Cross-origin is left alone
The web fonts come from a CDN. Those requests are network-first with the cached copy only as a fallback, so a font outage can never take the game down. The stylesheet is also loaded in a way that does not block first paint — measured with the CDN unreachable, that change took DOMContentLoaded from 12.9 seconds to 147 milliseconds.
What is not cached
Nothing about the player. The cache contains a copy of the site, not a record of anything anyone did.
The check that keeps it honest
Continuous integration verifies that every JavaScript module in the repository appears in the precache list. Adding a module and forgetting to list it would otherwise break offline play silently, and only for people who had already visited.
Read next
- Rendering: Sprite Caches and Layer BakingDrawing four hundred glowing blocks per frame is slow. Drawing four hundred cached bitmaps is not.
- Every Sound Is Generated, Not RecordedOscillators, filtered noise and a reverb impulse built from decaying random numbers. No audio files anywhere.
- The Soundtrack Is a Sequencer, Not a FileA four-bar progression with drums, bass, arpeggio and a lead, whose tempo and arrangement climb with your level.
- Online Play With No Server At AllWebRTC connects the two browsers directly; a public relay handles only the introduction.
- Plan in Sequences, Not PlacementsA piece that is awkward alone is often fine as the middle of a three-piece plan.
- Combo Pressure: Why Small Attacks Can Beat Big OnesContinuous garbage denies your opponent the quiet piece they need to survive.