fuzzyworld

nordic-skating / commit

docs: the sky's visitors, the weather, and what is named and not yet built

0045befdc5e82500548b520b0b6dec068204b8fa · Pavel Safronov · 2026-10-10 08:36:58 -0700 · parents 236f7d0357de

Claude Code usage: this commit ≈0 out / ≈0 cached · cost unknown (no per-model trailer) · session 1 tally 1.0K in / 886.4K out / 125.6M cached · usage by commit and session

docs: the sky's visitors, the weather, and what is named and not yet built

Screenshots of snow, a blizzard, a comet and an aeroplane. The plan has
the three things asked for and not built: snow drifts, cracks made by
the skater, and a long island with water both sides of it.

Usage: 1K in / 886.4K out / 125.6M cached (session tally)
rtk:   1.7M saved, 25.3% over 2681 cmds (global/lifetime)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
 PLAN.md                           |  44 +++++++++++++++++++++++++++++++++++++-
 README.md                         |  39 ++++++++++++++++++++++++++++++---
 docs/screenshots/about.png        | Bin 223387 -> 223868 bytes
 docs/screenshots/aeroplane.png    | Bin 0 -> 384016 bytes
 docs/screenshots/aurora-phone.png | Bin 256152 -> 255430 bytes
 docs/screenshots/aurora.png       | Bin 308040 -> 308507 bytes
 docs/screenshots/autopilot.png    | Bin 226224 -> 231399 bytes
 docs/screenshots/blizzard.png     | Bin 0 -> 197232 bytes
 docs/screenshots/comet.png        | Bin 0 -> 264905 bytes
 docs/screenshots/dusk.png         | Bin 256885 -> 262119 bytes
 docs/screenshots/far.png          | Bin 264297 -> 271905 bytes
 docs/screenshots/fork.png         | Bin 338327 -> 342342 bytes
 docs/screenshots/islets-dusk.png  | Bin 199662 -> 206712 bytes
 docs/screenshots/islets.png       | Bin 300899 -> 304547 bytes
 docs/screenshots/landscape.png    | Bin 280727 -> 283927 bytes
 docs/screenshots/night.png        | Bin 259964 -> 261510 bytes
 docs/screenshots/pass.png         | Bin 223547 -> 231057 bytes
 docs/screenshots/sea.png          | Bin 231845 -> 237546 bytes
 docs/screenshots/settings.png     | Bin 218026 -> 215007 bytes
 docs/screenshots/snow.png         | Bin 0 -> 275512 bytes
 docs/screenshots/steering.png     | Bin 179001 -> 178739 bytes
 docs/screenshots/thin-ice.png     | Bin 284179 -> 287907 bytes
 tools/screenshots.mjs             |  37 ++++++++++++++++++--------------
 23 files changed, 100 insertions(+), 20 deletions(-)

diff --git a/PLAN.md b/PLAN.md
index dcc043e..7efb122 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -93,6 +93,48 @@ how hilly, the colour of the aurora, how fast it moves.
 **Ideas for more settings**, none started: speed, how far the autopilot carves, how long
 the strides are, how much the ice cracks, falling through, the haze.
 
+### 2b. More in the scene — partly built
+
+Pavel, 2026-10-10: more details in the scene are welcome, and named these.
+
+**Built, waiting to be looked at.**
+- **In the sky**: shooting stars at night; a comet over one night lake in three; an
+  aeroplane and its trail over two day or dusk lakes in three.
+- **Weather**: clear, snow, or a blizzard, as a setting that starts on "Surprise me".
+  Falling snow that streams past the skater, wind from a direction of the lake's own,
+  the wind's sound, cloud over the sky, and less distance to see through.
+
+**Still to judge.** Is a blizzard thick enough, and is 200 m too little to see by? Is
+the wind too loud over the ice? Are shooting stars too frequent? The aeroplane is
+silent; should it be?
+
+**Named and not yet built.**
+- **Snow drifts**: snow lying on the ice in streaks blown by the wind, building up in
+  a blizzard. They would want to slow a skater and deaden the ice's sound where they
+  lie, which is the "bad ice" of the first description of this app.
+- **Cracks made by the skater**: on ice thin enough to crack, the cracks that are now
+  only heard would be seen, spreading from under the skates and left behind. This
+  needs a way to draw on the ice where the skater has been, which would also give
+  skate tracks, loops and all, as in the film.
+- **A long island in the middle of the lake**: see "Channels that part and join again".
+
+**Further ideas, none started**: a moon and its phase; mist that thins and thickens;
+dawn; how wooded and how hilly the banks are; the colour of the aurora; birds; a far
+shore with the lights of a house at night; satellites; a bare rock, as in the film.
+
+### Channels that part and join again
+
+**Pavel's question**: is this something like a long island of grass in the middle of a
+lake or river? **Yes.** Today a fork's two channels draw apart and never meet again:
+the lake is a tree. The other kind is an island with water both sides that comes back
+together beyond it: a few hundred metres long, low, covered in reeds like the islets,
+or wooded like the banks. The skater picks a side, and both lead on to the same lake.
+
+It is a smaller thing to build than it sounds, since a fork already is two channels
+drawn side by side: this is a fork whose channels come back to the same line. What it
+needs that forks do not have is the rejoining: both channels drawn all the way along
+the island, and the skater's channel becoming the one channel again at its far end.
+
 ### 3. Installable app — built, not yet tried on a phone
 
 A web manifest and a service worker, made by `vite-plugin-pwa`. Installed, the app has
@@ -140,7 +182,7 @@ And at 1:17 the ice is measured on camera: 45 mm. The sound alone gives 41 mm.
 - Are there too many islets, or too few? Do the reeds look like reeds?
 
 **Not done, and wanted or possible.**
-- Forks of three, and channels that part and join again.
+- Forks of three. Channels that part and join again: see the section of that name.
 - A bare rock, as in the film. A drawing of the skater's own tracks on the ice, as in
   the film: with loops now possible, they would show them.
 - Forks cannot be gone back through: a skater who turns back above a fork stays in the
diff --git a/README.md b/README.md
index 9cbde2d..99b1f1c 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,8 @@ a pitch set by how thick it is there. Thin ice is black, sings high and cracks u
 you. Nobody falls through: how thick the ice is decides only how it sounds.
 
 Every visit is to a different lake, one of a million, by day, at dusk, at night under
-the Milky Way, or under the northern lights.
+the Milky Way, or under the northern lights; in clear air, in falling snow, or in a
+blizzard; with, some nights, a comet, and some days an aeroplane drawing its trail.
 
 <img src="docs/screenshots/aurora.png" alt="The lake at night under green curtains of aurora" width="640" />
 
@@ -79,6 +80,7 @@ Each takes effect as it is touched, behind the box, and is remembered for next t
 | Setting | Choices | To begin with |
 |---|---|---|
 | Time of day | Surprise me, Day, Dusk, Night, Aurora | Surprise me: whichever the lake comes with |
+| Weather | Surprise me, Clear, Snow, Blizzard | Surprise me: whichever the lake comes with |
 | Impossible ice | on or off | off |
 | Lake | Another lake (the same as Randomize); a link back to this one | a different lake every visit |
 
@@ -109,7 +111,8 @@ Browsers give a page the phone's tilt only over HTTPS, which the live site is an
 ### A different lake every visit
 
 A lake is a number from 1 to 999,999, and everything about it follows from the number:
-its bends, widths and forks, its ice, its trees, and the time of day it comes with.
+its bends, widths and forks, its ice, its trees, the time of day and the weather it
+comes with, which way its wind blows, and what is in its sky.
 Opening the app picks a number, and so do Randomize and reloading the page: each is a
 new lake under a new sky. Settings shows the number and a link to it, and `?seed=1234`
 on the address asks for a lake by number, which is how to come back to one or send it
@@ -136,6 +139,34 @@ address asks for a time whatever the settings say.
 
 <img src="docs/screenshots/night.png" alt="The lake at night, the Milky Way overhead" width="640" />
 
+### What else is in the sky
+
+- **Shooting stars**, at night and under the aurora: one every quarter of a minute or
+  so, somewhere in the sky, gone in under a second.
+- **A comet**, over one night lake in three: ahead and low, with a tail.
+- **An aeroplane**, over two day or dusk lakes in three: a bright speck crossing the
+  sky ahead in four or five minutes, drawing a trail that widens and fades behind it,
+  white by day and pink at dusk. When it has gone, a while later another comes.
+
+<img src="docs/screenshots/comet.png" alt="A comet with a long tail over the lake at night" width="640" />
+
+### Weather
+
+| Weather | Snow | How far you can see | The sky | Wind | How often a lake comes with it |
+|---|---|---|---|---|---|
+| Clear | none | 600 m | as the time of day has it | none | 64% |
+| Snow | falling quietly | 420 m | mostly cloud | 0.5 to 3 m/s | 26% |
+| Blizzard | thick, and driven | 200 m | all cloud | 7 to 16 m/s, in gusts | 10% |
+
+Snow is a box of flakes that stays round the skater (`src/render/snow.ts`): they fall,
+the wind carries them, and they stream past as the skater moves, which is most of what
+makes a blizzard feel fast. Each lake's wind blows from a direction of its own. The wind
+can be heard, louder and higher in its gusts. Cloud hides the stars, the aurora and
+whatever else is up there, and takes the colour out of a sunset. `?weather=snow` on the
+address asks for a weather whatever the settings say.
+
+<img src="docs/screenshots/snow.png" alt="Snow falling over the lake by day" width="640" />
+
 Steering turns the skater: the harder the steer, the tighter the curve, up to a circle
 16 m in radius, with a moment to lean into it. Held over, the skater turns right round
 and can skate back up the lake, or round and round; that needs open water, about 24 m
@@ -289,6 +320,7 @@ measured the spreading directly, with instruments on the ice.
 - **The ring**: at each stride, every 1.4 to 3.2 s, a skate strikes the ice, which answers with a narrow band
   of noise at its note, starting a little high and falling onto it, then dying away.
 - **The hum and the scrape**: the gliding blade keeps the note faintly alive and hisses.
+- **The wind**, when there is one: low, loose noise, louder and higher in its gusts.
 - **The cracks**: every few seconds the ice cracks somewhere between 40 and 600 m off,
   and the chirp for that distance and that thickness arrives. The falling chirp is a
   sine wave and stops the moment it lands on the note; what rings on after it is the
@@ -321,7 +353,8 @@ npm run icons  # remake the home-screen and tab icons from assets/skate-shoes.pn
 ```
 
 On the address: `?seed=1` asks for lake number 1, `?time=night` for a time of day (`day`,
-`dusk`, `night`, `aurora`), and `?s=2500` starts that many metres down the lake. The
+`dusk`, `night`, `aurora`), `?weather=snow` for a weather (`clear`, `snow`, `blizzard`),
+and `?s=2500` starts that many metres down the lake. The
 screenshots use all three, so that they are of the same thing every run.
 
 The screenshots and the sound check need Playwright's Chromium once:
diff --git a/docs/screenshots/about.png b/docs/screenshots/about.png
index c684294..9a6b17f 100644
Binary files a/docs/screenshots/about.png and b/docs/screenshots/about.png differ
diff --git a/docs/screenshots/aeroplane.png b/docs/screenshots/aeroplane.png
new file mode 100644
index 0000000..5fc73da
Binary files /dev/null and b/docs/screenshots/aeroplane.png differ
diff --git a/docs/screenshots/aurora-phone.png b/docs/screenshots/aurora-phone.png
index 14dd639..c7d6e12 100644
Binary files a/docs/screenshots/aurora-phone.png and b/docs/screenshots/aurora-phone.png differ
diff --git a/docs/screenshots/aurora.png b/docs/screenshots/aurora.png
index f5cbb0c..e1613be 100644
Binary files a/docs/screenshots/aurora.png and b/docs/screenshots/aurora.png differ
diff --git a/docs/screenshots/autopilot.png b/docs/screenshots/autopilot.png
index 4be3eef..c7688f7 100644
Binary files a/docs/screenshots/autopilot.png and b/docs/screenshots/autopilot.png differ
diff --git a/docs/screenshots/blizzard.png b/docs/screenshots/blizzard.png
new file mode 100644
index 0000000..f7ff35a
Binary files /dev/null and b/docs/screenshots/blizzard.png differ
diff --git a/docs/screenshots/comet.png b/docs/screenshots/comet.png
new file mode 100644
index 0000000..8450f05
Binary files /dev/null and b/docs/screenshots/comet.png differ
diff --git a/docs/screenshots/dusk.png b/docs/screenshots/dusk.png
index 8961610..516e977 100644
Binary files a/docs/screenshots/dusk.png and b/docs/screenshots/dusk.png differ
diff --git a/docs/screenshots/far.png b/docs/screenshots/far.png
index 2d0b531..27e20e7 100644
Binary files a/docs/screenshots/far.png and b/docs/screenshots/far.png differ
diff --git a/docs/screenshots/fork.png b/docs/screenshots/fork.png
index f1438b8..5c49207 100644
Binary files a/docs/screenshots/fork.png and b/docs/screenshots/fork.png differ
diff --git a/docs/screenshots/islets-dusk.png b/docs/screenshots/islets-dusk.png
index 943ab2d..809cba2 100644
Binary files a/docs/screenshots/islets-dusk.png and b/docs/screenshots/islets-dusk.png differ
diff --git a/docs/screenshots/islets.png b/docs/screenshots/islets.png
index e38e926..4a4b063 100644
Binary files a/docs/screenshots/islets.png and b/docs/screenshots/islets.png differ
diff --git a/docs/screenshots/landscape.png b/docs/screenshots/landscape.png
index 097cd56..6481b1b 100644
Binary files a/docs/screenshots/landscape.png and b/docs/screenshots/landscape.png differ
diff --git a/docs/screenshots/night.png b/docs/screenshots/night.png
index 4f034b9..907d94c 100644
Binary files a/docs/screenshots/night.png and b/docs/screenshots/night.png differ
diff --git a/docs/screenshots/pass.png b/docs/screenshots/pass.png
index 28222a9..862f4a1 100644
Binary files a/docs/screenshots/pass.png and b/docs/screenshots/pass.png differ
diff --git a/docs/screenshots/sea.png b/docs/screenshots/sea.png
index bf8fcd3..62fb7ac 100644
Binary files a/docs/screenshots/sea.png and b/docs/screenshots/sea.png differ
diff --git a/docs/screenshots/settings.png b/docs/screenshots/settings.png
index a13248e..03a04c8 100644
Binary files a/docs/screenshots/settings.png and b/docs/screenshots/settings.png differ
diff --git a/docs/screenshots/snow.png b/docs/screenshots/snow.png
new file mode 100644
index 0000000..d7746cc
Binary files /dev/null and b/docs/screenshots/snow.png differ
diff --git a/docs/screenshots/steering.png b/docs/screenshots/steering.png
index 5923e50..d2157d2 100644
Binary files a/docs/screenshots/steering.png and b/docs/screenshots/steering.png differ
diff --git a/docs/screenshots/thin-ice.png b/docs/screenshots/thin-ice.png
index b881552..3d1ddea 100644
Binary files a/docs/screenshots/thin-ice.png and b/docs/screenshots/thin-ice.png differ
diff --git a/tools/screenshots.mjs b/tools/screenshots.mjs
index a696c72..805a7c3 100644
--- a/tools/screenshots.mjs
+++ b/tools/screenshots.mjs
@@ -16,34 +16,39 @@ const PHONE = { width: 390, height: 844 }
  * time of day by name, so that the pictures are of the same thing from one run to the next.
  */
 const SHOTS = [
-  { name: 'autopilot', query: '?seed=1&time=day&s=400', act: async () => {} },
+  { name: 'autopilot', query: '?seed=1&weather=clear&time=day&s=400', act: async () => {} },
   {
     name: 'steering',
-    query: '?seed=1&time=day&s=2600',
+    query: '?seed=1&weather=clear&time=day&s=2600',
     act: async (page) => {
       await page.keyboard.down('ArrowRight')
       await page.waitForTimeout(1500)
     },
   },
   // The first fork: the island between its two channels is a little way ahead.
-  { name: 'fork', query: '?seed=1&time=day&s=790', viewport: { width: 844, height: 390 }, act: async () => {} },
-  { name: 'pass', query: '?seed=1&time=day&s=6400', act: async () => {} },
-  { name: 'sea', query: '?seed=1&time=day&s=3400', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'fork', query: '?seed=1&weather=clear&time=day&s=790', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'pass', query: '?seed=1&weather=clear&time=day&s=6400', act: async () => {} },
+  { name: 'sea', query: '?seed=1&weather=clear&time=day&s=3400', viewport: { width: 844, height: 390 }, act: async () => {} },
   // Impossibly thin ice lies to the left of the middle here, faintly lit from within.
-  { name: 'thin-ice', query: '?seed=1&time=day&s=2795', viewport: { width: 844, height: 390 }, act: async () => {} },
-  { name: 'about', query: '?seed=1&time=day&s=400', act: async (page) => { await page.click('#about') } },
+  { name: 'thin-ice', query: '?seed=1&weather=clear&time=day&s=2795', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'about', query: '?seed=1&weather=clear&time=day&s=400', act: async (page) => { await page.click('#about') } },
   // A bed of reed islets, just down the lake from where it starts.
-  { name: 'islets', query: '?seed=1&time=day&s=150', viewport: { width: 844, height: 390 }, act: async () => {} },
-  { name: 'islets-dusk', query: '?seed=1&time=dusk&s=7040', act: async () => {} },
+  { name: 'islets', query: '?seed=1&weather=clear&time=day&s=150', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'islets-dusk', query: '?seed=1&weather=clear&time=dusk&s=7040', act: async () => {} },
   // The same water at the other times of day.
-  { name: 'dusk', query: '?seed=1&time=dusk&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
-  { name: 'night', query: '?seed=1&time=night&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
-  { name: 'aurora', query: '?seed=1&time=aurora&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
-  { name: 'aurora-phone', query: '?seed=1&time=aurora&s=400', act: async () => {} },
-  { name: 'settings', query: '?seed=1&time=night&s=400', act: async (page) => { await page.click('#settings') } },
-  { name: 'landscape', query: '?seed=1&time=day&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'dusk', query: '?seed=1&weather=clear&time=dusk&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'night', query: '?seed=1&weather=clear&time=night&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'aurora', query: '?seed=1&weather=clear&time=aurora&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'aurora-phone', query: '?seed=1&weather=clear&time=aurora&s=400', act: async () => {} },
+  { name: 'settings', query: '?seed=1&weather=clear&time=night&s=400', act: async (page) => { await page.click('#settings') } },
+  // Weather, and what is in the sky besides stars. Lake 13 has a comet and lake 2 an aeroplane.
+  { name: 'snow', query: '?seed=1&weather=snow&time=day&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'blizzard', query: '?seed=1&weather=blizzard&time=dusk&s=5200', act: async () => {} },
+  { name: 'comet', query: '?seed=13&weather=clear&time=night&s=3400', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'aeroplane', query: '?seed=2&weather=clear&time=day&s=3400', viewport: { width: 844, height: 390 }, act: async () => {} },
+  { name: 'landscape', query: '?seed=1&weather=clear&time=day&s=5200', viewport: { width: 844, height: 390 }, act: async () => {} },
   // Ten thousand kilometres down the lake: the picture must be as sharp as at the start.
-  { name: 'far', query: '?seed=1&time=day&s=10000000', act: async () => {} },
+  { name: 'far', query: '?seed=1&weather=clear&time=day&s=10000000', act: async () => {} },
 ]
 
 mkdirSync(OUT, { recursive: true })