From aadcbc6efbebe9b6451c3216a30f974a77afce4c Mon Sep 17 00:00:00 2001 From: 44r0n7 <44r0n7+gitea@pm.me> Date: Sat, 24 Oct 2026 00:20:18 -0400 Subject: [PATCH] Several worlds: a Worlds list with load, rename and delete; old save migrates to World 1 Co-Authored-By: Claude Opus 5.5 --- docs/DESIGN.md | 3 ++ docs/PROJECT_MAP.md | 14 +++---- docs/agent-log.md | 24 ++++++++++++ src/shell.html | 8 ++++ src/styles/style.css | 10 +++++ src/ui/loop.js | 6 ++- src/ui/saves.js | 89 +++++++++++++++++++++++++++++++++++++++----- src/ui/session.js | 59 +++++++++++++++++++++++------ src/ui/settings.js | 12 ++++-- src/ui/state.js | 2 +- test/play.py | 82 +++++++++++++++++++++++++++++++++++++++- 11 files changed, 274 insertions(+), 35 deletions(-) diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 1ae4351..e563fbf 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -196,6 +196,9 @@ above, including: - **Screw tubes carry bars**, one whole bar at a time, in line with the grains: a belt pushes a bar into a tube's side, it rides through corners and leaves the mouth. The owner asked how bars should be moved and chose tubes over a separate bar lift. +- **Several worlds are kept.** Each world has its own save and autosave; the title screen's Worlds + list loads, renames and deletes them, and a new or imported world never overwrites another. An + old single save becomes 'World 1'. The owner asked for multiple saves. ## Ideas not built yet diff --git a/docs/PROJECT_MAP.md b/docs/PROJECT_MAP.md index f43ec35..0a5a084 100644 --- a/docs/PROJECT_MAP.md +++ b/docs/PROJECT_MAP.md @@ -369,16 +369,16 @@ The title screen art. - functions: buildTitleCells, drawTitle - variables: FONT5, TITLE -### src/ui/saves.js (106 lines) +### src/ui/saves.js (177 lines) Saves in IndexedDB, world files (export / import) and the blueprint library. -- functions: saveWorld, newestSave, b64FromBytes, bytesFromB64, gz, exportWorld, importWorldFile, libLoad, libSave, bpEncode, bpValid, bpDecode -- variables: DB +- functions: newWorldId, worldWrite, listWorlds, putWorldEntry, worldNewest, deleteWorld, renameWorld, migrateWorlds, saveWorld, newestSave, b64FromBytes, bytesFromB64, gz, exportWorld, importWorldFile, libLoad, libSave, bpEncode, bpValid, bpDecode +- variables: DB, worldIdTime, worldIdCounter, worldWrites -### src/ui/session.js (87 lines) +### src/ui/session.js (122 lines) Starting, loading and quitting a game; modal dialogs; the pause menu. -- functions: showLoading, enterGame, startNewWorld, startFromSave, quitToTitle, refreshContinue, anyModal, openModal, closeModal, closeAllModals, topModal, dialog, openPause +- functions: showLoading, enterGame, startNewWorld, startFromSave, quitToTitle, refreshContinue, anyModal, openModal, closeModal, closeAllModals, topModal, dialog, openPause, renderWorlds -### src/ui/settings.js (116 lines) +### src/ui/settings.js (122 lines) The settings screen. - functions: openSettings, renderSettings, applySettings, toggleFullscreen, confirmWipe - variables: SET_TABS, setTab @@ -430,7 +430,7 @@ Previews drawn under the cursor: build ghosts, drill aim and pulses, selections, Events from the simulation (emit) turned into sounds, toasts and cards. - functions: drainEvents -### src/ui/loop.js (117 lines) +### src/ui/loop.js (119 lines) The frame loop and boot. - functions: scanVisible, frame, boot - variables: lastT, acc, lastRender, frameMs, simMs, fpsSm, ambientT diff --git a/docs/agent-log.md b/docs/agent-log.md index 53fc56e..83fabd7 100644 --- a/docs/agent-log.md +++ b/docs/agent-log.md @@ -4,6 +4,30 @@ What agents have done, newest first. Add an entry for every piece of work: the d note or request it was for, what changed, the files touched, the tests run, and anything left open or not verified. Keep each entry short; the git history has the details. +## 2026-10-24: several worlds, with a Worlds list (Claude Code, with Codex) + +Note: "support multiple saves". The owner chose a world list. + +- `src/ui/saves.js`: each world has an id and its own `:main` / `:auto` saves, plus an + index record `worlds` (name, seed, size, created, saved, playtime). A save writes the world + and its index entry in one transaction. `GAME.worldId` is the open world. +- Migration: an old single `main` / `auto` save is copied to "World 1", every byte compared, + and only then are the old keys deleted (in the same transaction that writes the index). If + anything fails the old save is kept and a toast says so. +- Title screen: Continue loads the most recently saved world; a Worlds button opens a list + with Load, Rename (trimmed, at most 40 characters, escaped when shown) and Delete (with a + confirmation). New and imported worlds get new ids. Settings' "Delete saves" became "Delete + all worlds" with a confirmation. `shell.html`, `session.js`, `loop.js`, `settings.js`, + `state.js`, `style.css`, `docs/DESIGN.md`, `docs/PROJECT_MAP.md`. +- `test/play.py` (149 checks): migration of an old save, two worlds listed, load switches, + rename survives a reload, HTML in a name shows as text, long names cut to 40, delete and + cancel, Continue picks the newest, import adds a world. All 11 headless suites pass; + `t_smooth.py` passed in Codex's run and failed its known flaky check in mine. +- Shots: `shots/worlds-{pixel,smooth}.png` and `-900` versions. +- Not committed: a line in `AGENTS.md` about running `kandown work` appeared in the working + tree during this task; it was not part of the task and is left for the owner. +- Open: nothing. + ## 2026-10-24: screw tubes carry bars (Claude Code, with Codex) Note: "how do you transport bars? belts work but tubes do not, should they?" The owner chose diff --git a/src/shell.html b/src/shell.html index 61d9252..6aa332f 100644 --- a/src/shell.html +++ b/src/shell.html @@ -47,6 +47,7 @@

Dig. Smelt. Cast your own tools. Every grain is simulated, and nothing turns into anything unless the physics says so.

+
+ +