Before you start
A coding agent, browser and basic comfort running a local development command.
Why this lesson exists
Patrick’s offline roguelike added the service worker last, after the grid, deterministic turns and save data worked. This lab practices that order, so “works offline” is something you test, not something you assume.
Do the exercise
Set your boundary
Use an original grid and placeholder art. Implement move, wait, one enemy and an exit before procedural generation.
Create one room, player and monster
Create one room, one player and one monster, plus an exit so a run can end.
Use a grid before graphics
Represent the world as a grid before adding graphics. Letters or plain shapes are enough.
Make turns deterministic
Make movement, waiting and the monster’s turn deterministic enough to test: the same moves from the same start give the same result.
Save and reload
Add save data: store the room and player state, reload the page and confirm the same state comes back.
Cache it for offline last
Add the PWA manifest and service worker last. Load the built game once online, then reopen the same address offline.
Next sessions, not today
- Inventory Add inventory only after the core loop is fun.
- Touch buttons Add touch buttons that call the same commands as the keyboard.
- Procedural rooms Add procedural generation after the hand-made room plays well.
A prompt to adapt
Replace the bracketed parts with your own details.
Help me build a tiny offline browser roguelike in [JavaScript or TypeScript] in a new practice folder. First version only: one grid room, one player, one enemy, move, wait and an exit, with placeholder art. No procedural generation, inventory or touch buttons yet. List the setup commands before changing any files. Then work in five checkpoints and, after each, tell me how to check it in the browser and which test covers it: 1. One room, one player, one monster and an exit. 2. The world as a grid before any graphics. 3. Deterministic movement, waiting and enemy turns. 4. Save the game state, reload and get the same state back. 5. A manifest and service worker, added last, so the built game reopens offline at the same address. My room theme: [one sentence].
Once it runs, paste your code and ask:
Review this input system. Keyboard input, and any touch buttons I add later, must call the same game commands. Identify duplicated logic and propose a command-based interface with examples for move, wait and exit, and show where pick up and inventory would plug in later.
Run this experiment
Start a run, move twice, save, reload and confirm the same state. After the production app has cached successfully, disconnect and reopen the exact same origin.
Check your result
Use evidence from your output. A confident explanation from the AI is not enough.
If it isn’t working
A service worker does not make an unvisited site available offline. Test the production build on the same host and record which assets were cached.
Optional. Progress stays in this browser.
Where this came from
Public project repository ↗. The practice lesson is an adaptation, not a verbatim transcript. About the sources.
Prepared September 2026. Tools and interfaces change; use current official setup instructions. Session lengths are estimates.
patrickz