fuzzyworld

nordic-skating / commit

Deploy to apps.fuzzyworld.net with fuzzyworld-tools

bcbc446b2faa704253f34a5edf562228e8008d02 · Pavel Safronov · 2026-10-26 18:21:30 -0700 · parents 3f3d6bcebc82

Deploy to apps.fuzzyworld.net with fuzzyworld-tools

Adds the fuzzyworld package.json section, a deploy script (fw deploy) and the fuzzyworld-tools dependency, and points gitlab.io / gitlab.com links at apps.fuzzyworld.net and code.fuzzyworld.net.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
 README.md         |  2 +-
 index.html        |  2 +-
 package-lock.json | 13 +++++++++++++
 package.json      | 11 +++++++++--
 vite.config.ts    |  3 +++
 5 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 868f2be..2c3ca7c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # Nordic Skating
 
-**Live — <https://pavelsafronov.gitlab.io/nordic-skating/>** · [Source](https://gitlab.com/PavelSafronov/nordic-skating)
+**Live — <https://apps.fuzzyworld.net/nordic-skating/>** · [Source](https://code.fuzzyworld.net/nordic-skating/)
 
 An endless skate across an endless lake of thin black ice, for a phone. The ice sings
 under the blades the way real black ice does, and its pitch tells you how thin it is.
diff --git a/index.html b/index.html
index 9fe94ef..1e9313e 100644
--- a/index.html
+++ b/index.html
@@ -68,7 +68,7 @@
   <h2>The sound</h2>
   <p>None of it is a recording. It is synthesized from the physics of thin ice: the note is the one frequency at which a sheet of that thickness gives its sound to the air, and the falling “pew” is a distant crack, its high notes arriving first.</p>
   <p>Inspired by National Geographic’s film <a href="https://www.youtube.com/watch?v=v3O9vNi-dkA" target="_blank" rel="noopener">Hear the Otherworldly Sounds of Skating on Thin Ice</a>.</p>
-  <p><a href="https://gitlab.com/PavelSafronov/nordic-skating/-/blob/main/README.md" target="_blank" rel="noopener">How it works, and credits</a> · <a href="https://gitlab.com/PavelSafronov/nordic-skating" target="_blank" rel="noopener">Source</a></p>
+  <p><a href="https://code.fuzzyworld.net/nordic-skating/blob/README.md.html" target="_blank" rel="noopener">How it works, and credits</a> · <a href="https://code.fuzzyworld.net/nordic-skating/" target="_blank" rel="noopener">Source</a></p>
   <!-- The Flaticon free licence requires the credit wherever the artwork is used. -->
   <p><small>Icons by <a href="https://www.flaticon.com/authors/icongeek26" target="_blank" rel="noopener">Icongeek26</a>, from Flaticon.</small></p>
 
diff --git a/package-lock.json b/package-lock.json
index 4429761..8b00d93 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
       "devDependencies": {
         "@types/node": "^26.4.1",
         "@types/three": "^0.180.0",
+        "fuzzyworld-tools": "git+https://code.fuzzyworld.net/fuzzyworld-tools.git#semver:^1.0.0",
         "playwright": "1.63.0",
         "typescript": "^7.0.2",
         "vite": "^8.2.2",
@@ -3909,6 +3910,18 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/fuzzyworld-tools": {
+      "version": "1.0.1",
+      "resolved": "git+https://code.fuzzyworld.net/fuzzyworld-tools.git#45b1fe3805ad7ec86b864e4604b7ad89a0e25a78",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "fw": "bin/fw"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/generator-function": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
diff --git a/package.json b/package.json
index 6705ad9..3446151 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,8 @@
     "screenshots": "npm run build && node tools/screenshots.mjs",
     "analyse-video": "node tools/analyse-video.mjs",
     "icons": "node tools/icons.mjs",
-    "sound-check": "node tools/sound-check.mjs"
+    "sound-check": "node tools/sound-check.mjs",
+    "deploy": "fw deploy"
   },
   "dependencies": {
     "simplex-noise": "^4.0.3",
@@ -21,6 +22,7 @@
   "devDependencies": {
     "@types/node": "^26.4.1",
     "@types/three": "^0.180.0",
+    "fuzzyworld-tools": "git+https://code.fuzzyworld.net/fuzzyworld-tools.git#semver:^1.0.0",
     "playwright": "1.63.0",
     "typescript": "^7.0.2",
     "vite": "^8.2.2",
@@ -28,5 +30,10 @@
     "vite-plugin-qrcode": "^0.4.1",
     "vitest": "^5.0.0"
   },
-  "license": "MIT"
+  "license": "MIT",
+  "fuzzyworld": {
+    "app": "nordic-skating",
+    "title": "Nordic Skating",
+    "description": "An endless skate over thin black ice that sings under every stride."
+  }
 }
diff --git a/vite.config.ts b/vite.config.ts
index 3837e2c..faddaeb 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,6 +1,7 @@
 import { defineConfig } from 'vite'
 import { VitePWA } from 'vite-plugin-pwa'
 import { qrcode } from 'vite-plugin-qrcode'
+import fuzzyworld from 'fuzzyworld-tools/vite'
 
 /**
  * Relative asset paths by default, so the same build works wherever Pages puts it:
@@ -14,6 +15,7 @@ export default defineConfig({
   // `npm run dev` binds to every interface (--host) so a phone on the same Wi-Fi can
   // open the app; this prints a scannable QR of that network URL alongside it.
   plugins: [
+    fuzzyworld(),
     qrcode(),
     // What makes the app installable: a manifest that says what it is called and how it
     // opens, and a service worker that keeps a copy of it, so that it opens with no
@@ -33,6 +35,7 @@ export default defineConfig({
         theme_color: '#0b1a24',
         // Relative, for the same reason as `base`: both resolve against the manifest's
         // own address, so the installed app belongs to wherever it was deployed.
+        id: '.',
         start_url: '.',
         scope: '.',
         icons: [