From 15771d0c86bedaa49ef869e90b1ee13e8a0e6375 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:36:30 -0400 Subject: [PATCH 01/16] update ci versions --- .github/workflows/build.yml | 3 +-- .github/workflows/test-game.yml | 6 +++--- .github/workflows/typescript_check.yml | 4 ++-- .github/workflows/unit_tests.yml | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e85bea404..aa266f1479 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,6 @@ on: # This workflow should run on... push: # a push... branches: # to one of these branches: - 'main' - - 'add-ci' # TEMP for testing workflow_dispatch: # or when manually triggered pull_request: # or when a pull request is opened against main branches: @@ -29,7 +28,7 @@ jobs: run: cd ~/sprig/firmware/spade && python3 gardenshed.py build - name: 'Upload artifact' - uses: 'actions/upload-artifact@v4' + uses: 'actions/upload-artifact@v7' with: name: 'firmware.uf2' path: '~/sprig/firmware/spade/firmware.uf2' diff --git a/.github/workflows/test-game.yml b/.github/workflows/test-game.yml index b3d2081a69..a93bd8fa38 100644 --- a/.github/workflows/test-game.yml +++ b/.github/workflows/test-game.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 @@ -35,7 +35,7 @@ jobs: - name: Get changed files id: changed-files - uses: tj-actions/changed-files@v41.0.1 + uses: tj-actions/changed-files@v47 with: files: | games/**.js @@ -46,7 +46,7 @@ jobs: echo "${{ steps.changed-files.outputs.all_changed_files }}" - name: Setup Deno - uses: denoland/setup-deno@v1.1.3 + uses: denoland/setup-deno@v2 - name: Check Games run: deno run --allow-read tests/sprigfuzzy_workflow.js ${{ steps.changed-files.outputs.all_changed_files }} \ No newline at end of file diff --git a/.github/workflows/typescript_check.yml b/.github/workflows/typescript_check.yml index a6f73cbdf3..59784a1f21 100644 --- a/.github/workflows/typescript_check.yml +++ b/.github/workflows/typescript_check.yml @@ -10,10 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 20.x diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index a48f0c55e8..bd2bf20380 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -17,9 +17,9 @@ jobs: node-version: [20.x] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} cache: "yarn" From 9fe81a90764feadd1bf35c7a7dd7a333ab97eaa3 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:40:07 -0400 Subject: [PATCH 02/16] ts dev dep --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index 16c4d4ebad..0cda7c1c97 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@types/three": "^0.149.0", "@types/throttle-debounce": "^5.0.0", "@types/w3c-web-serial": "^1.0.3", + "typescript": "^6.0.2", "vitest-canvas-mock": "^0.3.3" } } diff --git a/yarn.lock b/yarn.lock index 823a900232..767a479a83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6338,6 +6338,11 @@ typescript@*: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== +typescript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.2.tgz#0b1bfb15f68c64b97032f3d78abbf98bdbba501f" + integrity sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ== + uc.micro@^2.0.0, uc.micro@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" From 8c0e2d127f0f1bf9f5ddd95ead6932c286ae9e5b Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:43:43 -0400 Subject: [PATCH 03/16] use defaults --- .github/workflows/build.yml | 7 ++++--- .github/workflows/test-game.yml | 2 -- .github/workflows/typescript_check.yml | 4 +++- .github/workflows/unit_tests.yml | 4 +++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa266f1479..42dd9c98cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,9 +4,10 @@ on: # This workflow should run on... branches: # to one of these branches: - 'main' workflow_dispatch: # or when manually triggered - pull_request: # or when a pull request is opened against main - branches: - - 'main' + pull_request: + +permissions: + contents: read defaults: run: diff --git a/.github/workflows/test-game.yml b/.github/workflows/test-game.yml index a93bd8fa38..8e1a93a3bb 100644 --- a/.github/workflows/test-game.yml +++ b/.github/workflows/test-game.yml @@ -3,8 +3,6 @@ name: test-game on: workflow_dispatch: pull_request: - branches: - - main paths: - 'games/**.js' diff --git a/.github/workflows/typescript_check.yml b/.github/workflows/typescript_check.yml index 59784a1f21..ed37a97a12 100644 --- a/.github/workflows/typescript_check.yml +++ b/.github/workflows/typescript_check.yml @@ -2,7 +2,9 @@ name: TypeScript Check on: pull_request: - types: [opened, reopened, edited] + +permissions: + contents: read jobs: # Test job diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index bd2bf20380..5dee839a4e 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -2,7 +2,9 @@ name: Unit Tests on: pull_request: - types: [opened, reopened, edited, synchronize] + +permissions: + contents: read env: PUBLIC_MAX_LOOP_TIME_MS: 1500 From 1c9e151d5f6bcdb4d1c8d2436645a55899191685 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:45:22 -0400 Subject: [PATCH 04/16] tsc fixes --- games/8-Sprig.js | 2 +- games/Mario_Kart.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/games/8-Sprig.js b/games/8-Sprig.js index 3a37df938b..8114439552 100644 --- a/games/8-Sprig.js +++ b/games/8-Sprig.js @@ -520,7 +520,7 @@ function startGame() { } // special level switcher logic -function next level() { +function nextLevel() { setSolids([]) // allow block collisions temporarily to allow setting random puzzle config if (speedrun === true) { // actually switch levels since we are in speedrun mode diff --git a/games/Mario_Kart.js b/games/Mario_Kart.js index f5e1803389..3514d5e1ca 100644 --- a/games/Mario_Kart.js +++ b/games/Mario_Kart.js @@ -1,9 +1,10 @@ /* @title: Mario_Kart @description: Mario_Kart is an arcade-style game with a Mario theme where the player must jump over incoming blocks to earn points. As more blocks are successfully jumped over, the score increases. The game features a simple jumping mechanic to test the player's timing and reflexes in an endless format. -@author: nucleiav */ +@author: nucleiav @tags: ['endless'] @addedOn: 2023-01-13 +*/ let n = 0; From a42a1779014a4b33a6b990d2b387845b0e9ca740 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:48:27 -0400 Subject: [PATCH 05/16] fix test game workflow --- .github/workflows/test-game.yml | 11 +++++++++++ tests/sprigfuzzy_workflow.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-game.yml b/.github/workflows/test-game.yml index 8e1a93a3bb..d144205469 100644 --- a/.github/workflows/test-game.yml +++ b/.github/workflows/test-game.yml @@ -43,6 +43,17 @@ jobs: echo "Changed Files:" echo "${{ steps.changed-files.outputs.all_changed_files }}" + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 20 + + - name: Build Engine + run: | + yarn install --frozen-lockfile + yarn build + working-directory: engine + - name: Setup Deno uses: denoland/setup-deno@v2 diff --git a/tests/sprigfuzzy_workflow.js b/tests/sprigfuzzy_workflow.js index 72cf474b08..53f7b8e38a 100644 --- a/tests/sprigfuzzy_workflow.js +++ b/tests/sprigfuzzy_workflow.js @@ -1,4 +1,4 @@ -import { baseEngine } from "npm:sprig@latest/base" +import { baseEngine } from "../engine/dist/base/index.js" // import { iterateReader } from "https://deno.land/std@0.162.0/streams/conversion.ts"; // import * as pathUtils from "https://deno.land/std/path/mod.ts"; From 0db881168a1265740ff9e72634b070b7f9b14079 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:50:06 -0400 Subject: [PATCH 06/16] update to node 24 --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 5dee839a4e..11a6051035 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [20.x] + node-version: [24.x] steps: - uses: actions/checkout@v6 From d043f74330c747975e6826f0819d196dc3e605bf Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:52:06 -0400 Subject: [PATCH 07/16] all up to node 24 --- .github/workflows/test-game.yml | 2 +- .github/workflows/typescript_check.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-game.yml b/.github/workflows/test-game.yml index d144205469..95047b89be 100644 --- a/.github/workflows/test-game.yml +++ b/.github/workflows/test-game.yml @@ -46,7 +46,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 24 - name: Build Engine run: | diff --git a/.github/workflows/typescript_check.yml b/.github/workflows/typescript_check.yml index ed37a97a12..20da4af849 100644 --- a/.github/workflows/typescript_check.yml +++ b/.github/workflows/typescript_check.yml @@ -17,7 +17,7 @@ jobs: - name: Install Node uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24 - name: Install Dependencies run: | From 787ac2038a2c486a209ccb6ac3888bfceb9ad838 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:53:55 -0400 Subject: [PATCH 08/16] fix lol --- games/gravity-flipper-with-twist.js | 788 ++++++++++++++++++++++++++++ 1 file changed, 788 insertions(+) create mode 100644 games/gravity-flipper-with-twist.js diff --git a/games/gravity-flipper-with-twist.js b/games/gravity-flipper-with-twist.js new file mode 100644 index 0000000000..c3c4258245 --- /dev/null +++ b/games/gravity-flipper-with-twist.js @@ -0,0 +1,788 @@ +/* +@title: gravity flipper with a twist +@author: manikanta vasamsetti +@tags: [gravity,platformer,block] +@addedOn: 2026-03-19 +*/ + +const player = "p"; +const wall = "w"; +const normalPlatform = "n"; // Blue, active in normal gravity +const invertPlatform = "i"; // Red, active in flipped gravity +const goal = "g"; +const spike = "s"; +const background = "b"; + +let gameState = "intro"; +let currentLevel = 0; +let gravityFlipped = false; +let introBob = false; + +setLegend( + [player, bitmap` +................ +................ +................ +.00000000000000. +.05577277277550. +.05577277277550. +.05577722777550. +.05575757575550. +.05557575757550. +.05555555555550. +.02222L22L22220. +.01111L11L11110. +.01121111112110. +.00002222220000. +.00000000000000. +.00.000..000.00.`], + [wall, bitmap` +0000000000000000 +0LLLLLLLLLLLLLL0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0L111111111111L0 +0LLLLLLLLLLLLLL0 +0000000000000000`], + [normalPlatform, bitmap` +0000000000000000 +0555555555555550 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0577777777777750 +0555555555555550 +0000000000000000`], + [invertPlatform, bitmap` +0000000000000000 +0999999999999990 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0933333333333390 +0999999999999990 +0000000000000000`], + [goal, bitmap` +................ +................ +.....000000..... +....02666660.... +...0266666660... +..026666666660.. +..06666FF66660.. +..0666FFFF6660.. +..0666FFFF6660.. +..06666FF66660.. +..066666666690.. +...0666666690... +....06666690.... +.....000000..... +................ +................`], + [spike, bitmap` +................ +................ +.......00....... +......0210...... +......0210...... +.....022110..... +.....022110..... +....02221110.... +....02221110.... +...0222211110... +...0222211110... +..022222111110.. +..022222111110.. +.02222221111110. +.01111111111110. +0000000000000000`], + [background, bitmap` +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777`] +); + +setBackground(background); +setSolids([wall]); + +const introMap = map` +wwwwwwwwww +w.....g..w +w........w +w...s....w +w........w +w...p....w +w..n...i.w +w........w +w........w +wwwwwwwwww`; + +const instructionsMap = map` +wwwwwwwwww +w........w +w........w +w........w +w........w +w...p....w +w........w +w........w +w........w +wwwwwwwwww`; + +const instructionsMap2 = map` +wwwwwwwwww +w........w +w........w +w........w +w........w +w........w +w........w +w........w +w........w +wwwwwwwwww`; + +const instructionsMap3 = map` +wwwwwwwwww +w........w +w........w +w........w +w........w +w........w +w........w +w........w +w........w +wwwwwwwwww`; + +const instructionsMap4 = map` +wwwwwwwwww +w........w +w........w +w..s.s.s.w +w........w +w..p...g.w +w........w +w........w +w........w +wwwwwwwwww`; + +const levels = [ + map` +wwwwwwwwww +w........w +w........w +w........w +w.n......w +w........w +w........w +w........w +wp.....g.w +wwwwwwwwww`, + + map` +wwwwwwwwww +w..w.....w +w........w +w.nw.....w +w..w.....w +w..w.....w +w..w.....w +w..w.....w +wp.w...g.w +wwwwwwwwww`, + + map` +wwwwwwwwww +w..w..w..w +w.....w..w +w..w..w..w +w..wn.w..w +w..w..w..w +w..w..w..w +w..wiww..w +wp.wiii.gw +wwwwwwwwww`, + + map` +wwwwwwwwww +w....w.w.w +w.w..w...w +w.w..w...w +w.w.nw.w.w +w.w..w.w.w +w.w....w.w +w.w....w.w +wpw..w.wgw +wwwwwwwwww`, + + map` +wwwwwwwwww +w.w.i.w..w +w.w.i.w..w +w...w.w..w +wnn.w.w..w +w.w.w.w..w +w.w.w..i.w +w.w.w.ni.w +wpw.w.w.gw +wwwwwwwwww`, + + map` +wwwwwwwwww +w.w.w....w +w...i....w +w.w.wnn..w +w.w.w.w..w +w.w.wsws.w +w.w.w.w..w +w.w...w..w +wpw.w.w.gw +wwwwwwwwww`, + + map` +wwwwwwwwww +w....w.w.w +w..w.w...w +w..w.w.w.w +w.nw.w.i.w +w..w.w.w.w +w..w.w.w.w +w..w.w.w.w +wp.w...wgw +wwwwwwwwww`, + + map` +wwwwwwwwww +w.w.w.ww.w +w...w.ii.w +w.w.w.ww.w +w.w.wnww.w +w.w.w.ww.w +w.w.w.ww.w +w.w...ww.w +wpw.w.wwgw +wwww.wwwww`, + + map` +wwwwwwwwww +w...wwww.w +w.w.wwww.w +w.w.wwww.w +w.w.wwww.w +w.w.wwww.w +w.w.wwww.w +w.w.inin.w +wpw.wwwwgw +wwww....ww`, + + map` +wwwwwwwwww +w.w...ww.w +w...w.iw.w +w.w.w.ii.w +w.w.w.ww.w +w.w.wsww.w +w.w.w.ww.w +w.w.w..w.w +wpw.w.wwgw +www.wwwwww`, + + map` +wwwwwwwwww +w..n.w...w +w.ww...w.w +w.ww.w.w.w +w.wwiw.w.w +w.ww.w.w.w +w.ww.w.w.w +w.ww.n.w.w +wpwwsw.wgw +wwwwww.www`, + + map` +wwwwwwwwww +w.ww...w.w +w.ww.w...w +w.ww.i.w.w +w.wwnn.w.w +w.ww.w.w.w +w.ww.w.w.w +w.w..w.w.w +wpii.w.wgw +wwww.wwwww`, + + map` +wwwwwwwwww +w...ww...w +w.w.w..w.w +w.w.ww.w.w +w.wnwwnw.w +wsw.nn.w.w +w.w..w.w.w +w.w..w.w.w +wpi.ww.wgw +www.w.wwww`, + + map` +wwwwwwwwww +w.ww.w.w.w +w.ww.w...w +w.ww.w.w.w +w.ww.w.w.w +w.in.s.w.w +w.ww.w.w.w +w.ww...w.w +wpww.w.wgw +wwwwnwwwww`, + + map` +wwwwwwwwww +w.ww.www.w +w.ww.ini.w +w.ww.www.w +w.wwnwww.w +w.ww.sww.w +w.ww.www.w +w.n..www.w +wpww.wwwgw +www..w.www` +]; + +// Check if movement is blocked at position (x, y) +// Walls are always solid +// Blue platforms are solid when gravity is DOWN (normal) +// Red platforms are solid when gravity is UP (flipped) +function isBlocked(x, y) { + if (x < 0 || x >= width() || y < 0 || y >= height()) return true; + + const tile = getTile(x, y); + for (const sprite of tile) { + if (sprite.type === wall) return true; + if (sprite.type === normalPlatform && !gravityFlipped) return true; + if (sprite.type === invertPlatform && gravityFlipped) return true; + } + return false; +} + +function getPlayer() { + return getFirst(player); +} + +function renderHUD() { + if (gameState !== "playing") return; + clearText(); + addText(gravityFlipped ? "GRAVITY: UP" : "GRAVITY: DOWN", { + x: 1, + y: 1, + color: gravityFlipped ? color`3` : color`5` + }); + addText(`LEVEL ${currentLevel + 1}/${levels.length}`, { + x: 1, + y: 2, + color: color`2` + }); +} + +function showIntro() { + gameState = "intro"; + gravityFlipped = false; + introBob = false; + setMap(introMap); + clearText(); + addText("GRAVITY PLATFORMER", { x: 1, y: 1, color: color`5` }); + addText("WITH TWISTS", { x: 4, y: 2, color: color`3` }); + addText("A shifting world", { x: 2, y: 4, color: color`2` }); + addText("Press L to continue", { x: 1, y: 13, color: color`2` }); +} + +function showInstructions() { + gameState = "instructions"; + gravityFlipped = false; + setMap(instructionsMap); + clearText(); + addText("HOW TO PLAY", { x: 4, y: 1, color: color`6` }); + addText("- PAGE 1/4 -", { x: 4, y: 2, color: color`2` }); + addText("", { x: 0, y: 3, color: color`2` }); + addText("CONTROLS:", { x: 5, y: 4, color: color`L` }); + addText("A/D: Move", { x: 5, y: 5, color: color`2` }); + addText("W: Flip Gravity", { x: 2, y: 6, color: color`2` }); + addText("J: Reset Level", { x: 3, y: 7, color: color`2` }); + addText("", { x: 0, y: 8, color: color`2` }); + addText("THE TWIST:", { x: 5, y: 9, color: color`L` }); + addText("Platforms change!", { x: 1, y: 10, color: color`5` }); + addText("Blue & Red switch", { x: 1, y: 11, color: color`3` }); + addText("based on gravity", { x: 2, y: 12, color: color`2` }); + addText("", { x: 0, y: 13, color: color`2` }); + addText("L: Next Page", { x: 4, y: 14, color: color`6` }); +} + +function showInstructions2() { + gameState = "instructions2"; + gravityFlipped = false; + setMap(instructionsMap2); + clearText(); + addText("BLUE PLATFORMS", { x: 3, y: 1, color: color`5` }); + addText("- PAGE 2/4 -", { x: 4, y: 2, color: color`2` }); + addText("", { x: 0, y: 3, color: color`2` }); + addText("When gravity is", { x: 2, y: 4, color: color`2` }); + addText("DOWN (normal):", { x: 3, y: 5, color: color`5` }); + addText("", { x: 0, y: 6, color: color`2` }); + addText("Blue platforms =", { x: 2, y: 7, color: color`2` }); + addText("SOLID EVERYWHERE", { x: 2, y: 8, color: color`4` }); + addText("", { x: 0, y: 9, color: color`2` }); + addText("Can't pass through", { x: 1, y: 10, color: color`2` }); + addText("from any direction!", { x: 0, y: 11, color: color`3` }); + addText("", { x: 0, y: 12, color: color`2` }); + addText("", { x: 0, y: 13, color: color`2` }); + addText("L: Next Page", { x: 4, y: 14, color: color`6` }); +} + +function showInstructions3() { + gameState = "instructions3"; + gravityFlipped = false; + setMap(instructionsMap3); + clearText(); + addText("RED PLATFORMS", { x: 3, y: 1, color: color`3` }); + addText("- PAGE 3/4 -", { x: 4, y: 2, color: color`2` }); + addText("", { x: 0, y: 3, color: color`2` }); + addText("When gravity is", { x: 2, y: 4, color: color`2` }); + addText("UP (flipped):", { x: 3, y: 5, color: color`3` }); + addText("", { x: 0, y: 6, color: color`2` }); + addText("Red platforms =", { x: 2, y: 7, color: color`2` }); + addText("SOLID EVERYWHERE", { x: 2, y: 8, color: color`4` }); + addText("", { x: 0, y: 9, color: color`2` }); + addText("Blue platforms =", { x: 2, y: 10, color: color`2` }); + addText("PASSABLE now!", { x: 3, y: 11, color: color`5` }); + addText("", { x: 0, y: 12, color: color`2` }); + addText("", { x: 0, y: 13, color: color`2` }); + addText("L: Next Page", { x: 4, y: 14, color: color`6` }); +} + +function showInstructions4() { + gameState = "instructions4"; + gravityFlipped = false; + setMap(instructionsMap4); + clearText(); + addText("DANGERS & GOAL", { x: 3, y: 1, color: color`4` }); + addText("- PAGE 4/4 -", { x: 4, y: 2, color: color`2` }); + addText("", { x: 0, y: 3, color: color`2` }); + addText("SPIKES (gray):", { x: 3, y: 7, color: color`3` }); + addText("Touch = DEATH!", { x: 3, y: 8, color: color`3` }); + addText("Avoid them!", { x: 4, y: 9, color: color`2` }); + addText("", { x: 0, y: 10, color: color`2` }); + addText("GOAL (yellow):", { x: 3, y: 11, color: color`4` }); + addText("Reach to win!", { x: 3, y: 12, color: color`4` }); + addText("", { x: 0, y: 13, color: color`2` }); + addText("L: START GAME", { x: 3, y: 14, color: color`6` }); +} + +function showLevelComplete() { + gameState = "levelcomplete"; + clearText(); + playTune(goalTune); + addText("LEVEL COMPLETE!", { x: 2, y: 6, color: color`4` }); + addText(`Level ${currentLevel + 1}/${levels.length}`, { x: 4, y: 8, color: color`2` }); + addText("L - Next Level", { x: 3, y: 12, color: color`6` }); + addText("K - Retry Level", { x: 2, y: 14, color: color`3` }); +} + +function showGameOver(reason) { + gameState = "gameover"; + clearText(); + playTune(deathTune); + addText("GAME OVER", { x: 5, y: 6, color: color`3` }); + addText(reason || "You died", { x: 4, y: 8, color: color`2` }); + addText("Press K to retry", { x: 2, y: 14, color: color`2` }); +} + +function showWin() { + gameState = "win"; + clearText(); + playTune(winTune); + addText("YOU WIN!", { x: 6, y: 6, color: color`4` }); + addText("Press K", { x: 6, y: 8, color: color`2` }); + addText("to restart", { x: 5, y: 9, color: color`2` }); +} + +function loadLevel(index) { + currentLevel = index; + gravityFlipped = false; + setMap(levels[currentLevel]); + renderHUD(); +} + +function startGame() { + currentLevel = 0; + gravityFlipped = false; + gameState = "playing"; + playTune(startTune); + loadLevel(0); +} + +function resetLevel() { + if (gameState !== "playing") return; + gravityFlipped = false; + playTune(resetTune); + loadLevel(currentLevel); +} + +function retryCurrentLevel() { + if (gameState !== "gameover" && gameState !== "levelcomplete") return; + gravityFlipped = false; + gameState = "playing"; + playTune(resetTune); + loadLevel(currentLevel); +} + +function advanceToNextLevel() { + if (gameState !== "levelcomplete") return; + currentLevel += 1; + if (currentLevel >= levels.length) { + showWin(); + } else { + gameState = "playing"; + playTune(levelTune); + loadLevel(currentLevel); + } +} + +function moveHorizontal(dx) { + if (gameState !== "playing") return; + + const p = getPlayer(); + if (!p) return; + + const nx = p.x + dx; + if (isBlocked(nx, p.y)) { + playTune(bumpTune); + return; + } + + p.x = nx; + playTune(moveTune); + checkTileEffects(); +} + +function flipGravity() { + if (gameState !== "playing") return; + + gravityFlipped = !gravityFlipped; + playTune(flipTune); + renderHUD(); +} + +// FIX #1: Clean checkTileEffects - one loop, immediate exit, no duplication +function checkTileEffects() { + if (gameState !== "playing") return; + + const p = getPlayer(); + if (!p) return; + + const tile = getTile(p.x, p.y); + + for (const sprite of tile) { + if (sprite.type === spike) { + showGameOver("Spikes got you"); + return; + } + + if (sprite.type === goal) { + if (currentLevel + 1 >= levels.length) { + showWin(); + } else { + showLevelComplete(); + } + return; + } + } +} + +// Intro bobbing animation +setInterval(() => { + if (gameState !== "intro") return; + const p = getPlayer(); + if (!p) return; + introBob = !introBob; + p.y = introBob ? 4 : 5; +}, 500); + +// FIX #2: Gravity loop with proper state checking - prevents post-win chaos +setInterval(() => { + if (gameState !== "playing") return; + + const p = getPlayer(); + if (!p) return; + + const direction = gravityFlipped ? -1 : 1; + const nextY = p.y + direction; + + if (nextY < 0 || nextY >= height()) { + showGameOver("You fell into the void"); + return; + } + + if (!isBlocked(p.x, nextY)) { + p.y = nextY; + } + + checkTileEffects(); +}, 120); + +// FIX #3: Input priority - levelcomplete first to prevent stuck states +onInput("l", () => { + // PRIORITY: level completion takes precedence + if (gameState === "levelcomplete") { + advanceToNextLevel(); + return; + } + + if (gameState === "intro") { + playTune(pageTune); + showInstructions(); + return; + } + + if (gameState === "instructions") { + playTune(pageTune); + showInstructions2(); + return; + } + + if (gameState === "instructions2") { + playTune(pageTune); + showInstructions3(); + return; + } + + if (gameState === "instructions3") { + playTune(pageTune); + showInstructions4(); + return; + } + + if (gameState === "instructions4") { + startGame(); + return; + } +}); + +onInput("a", () => moveHorizontal(-1)); +onInput("d", () => moveHorizontal(1)); +onInput("w", () => flipGravity()); +onInput("j", () => resetLevel()); + +onInput("k", () => { + if (gameState === "gameover") { + retryCurrentLevel(); + return; + } + + if (gameState === "levelcomplete") { + retryCurrentLevel(); + return; + } + + if (gameState === "win") { + startGame(); + } +}); + +const moveTune = tune` +70: C5~70, +70: D5~70, +70: E5~70, +1100`; + +const bumpTune = tune` +50: C3~50, +50: C3~50, +1000`; + +const flipTune = tune` +60: C4^60, +60: E4^60, +60: G4^60, +60: C5^60, +1600`; + +const resetTune = tune` +80: E4~80, +80: C4~80, +80: E4~80, +1300`; + +const pageTune = tune` +70: G4^70, +70: C5^70, +70: E5^70, +1400`; + +const goalTune = tune` +120: C5^120, +120: E5^120, +120: G5^120, +2200`; + +const levelTune = tune` +100: D5^100, +100: F5^100, +100: A5^100, +2000`; + +const startTune = tune` +120: E4^120, +120: G4^120, +120: B4^120, +2200`; + +const deathTune = tune` +90: C4~90, +90: A3~90, +90: F3~90, +1400`; + +const winTune = tune` +150: C5^150, +150: E5^150, +150: G5^150, +150: C6^150, +2600`; + +showIntro(); From 0b2ab60a314426705547221f53cc4162c1a4ab82 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:56:03 -0400 Subject: [PATCH 09/16] fix meta data --- games/gravity-flipper-with-twist.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/games/gravity-flipper-with-twist.js b/games/gravity-flipper-with-twist.js index c3c4258245..994bcdcbb3 100644 --- a/games/gravity-flipper-with-twist.js +++ b/games/gravity-flipper-with-twist.js @@ -1,8 +1,9 @@ /* @title: gravity flipper with a twist @author: manikanta vasamsetti -@tags: [gravity,platformer,block] +@tags: ['gravity','platformer','block'] @addedOn: 2026-03-19 +@description: A gravity-flipping platformer where you navigate through levels by toggling gravity to activate different platforms and avoid spikes. */ const player = "p"; From d5c84188b2c28666097b9ed047c96baa55b9bd50 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 19:57:55 -0400 Subject: [PATCH 10/16] downgrade to node 22 --- .github/workflows/test-game.yml | 2 +- .github/workflows/typescript_check.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-game.yml b/.github/workflows/test-game.yml index 95047b89be..9ec952583b 100644 --- a/.github/workflows/test-game.yml +++ b/.github/workflows/test-game.yml @@ -46,7 +46,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 24 + node-version: 22 - name: Build Engine run: | diff --git a/.github/workflows/typescript_check.yml b/.github/workflows/typescript_check.yml index 20da4af849..3d3cfc1abb 100644 --- a/.github/workflows/typescript_check.yml +++ b/.github/workflows/typescript_check.yml @@ -17,7 +17,7 @@ jobs: - name: Install Node uses: actions/setup-node@v6 with: - node-version: 24 + node-version: 22 - name: Install Dependencies run: | From 0534a1a410cbfc33caf1a90d6c3375b2b7d82a19 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 20:09:04 -0400 Subject: [PATCH 11/16] fix checks --- .github/workflows/docker.yml | 45 ++++++++++++++++++++++++++ .github/workflows/test-game.yml | 2 +- .github/workflows/typescript_check.yml | 29 ----------------- 3 files changed, 46 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/docker.yml delete mode 100644 .github/workflows/typescript_check.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000000..3fc1a6d54a --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,45 @@ +name: Docker Build + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + docker-build: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout Code + uses: actions/checkout@v6 + + - name: Build Docker Image + run: docker build -t sprig-ci . + + - name: Start Container + run: | + docker run -d \ + --name sprig-ci \ + -p 3000:3000 \ + -e NODE_OPTIONS="--max-old-space-size=4096" \ + sprig-ci + + - name: Wait for Server to Start + run: | + echo "Waiting for Astro dev server to start..." + for i in $(seq 1 60); do + if curl -sf -o /dev/null http://localhost:3000; then + echo "Server is up after ${i}s!" + exit 0 + fi + sleep 1 + done + echo "Server failed to respond within 60s" + docker logs sprig-ci + exit 1 + + - name: Show Container Logs on Failure + if: failure() + run: docker logs sprig-ci diff --git a/.github/workflows/test-game.yml b/.github/workflows/test-game.yml index 9ec952583b..95047b89be 100644 --- a/.github/workflows/test-game.yml +++ b/.github/workflows/test-game.yml @@ -46,7 +46,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 - name: Build Engine run: | diff --git a/.github/workflows/typescript_check.yml b/.github/workflows/typescript_check.yml deleted file mode 100644 index 3d3cfc1abb..0000000000 --- a/.github/workflows/typescript_check.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: TypeScript Check - -on: - pull_request: - -permissions: - contents: read - -jobs: - # Test job - build: - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v6 - - - name: Install Node - uses: actions/setup-node@v6 - with: - node-version: 22 - - - name: Install Dependencies - run: | - yarn install - - - name: Build Project - run: | - node .github/scripts/generate-metadata.js - yarn tsc --noEmit From 694d28f16eb24c2436aa035e0165ea992294fbfb Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 20:10:07 -0400 Subject: [PATCH 12/16] more triggers --- .github/workflows/docker.yml | 7 +++++-- .github/workflows/test-game.yml | 5 ++++- .github/workflows/unit_tests.yml | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 3fc1a6d54a..e1925e8e61 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,7 +1,10 @@ name: Docker Build -on: - push: +on: # This workflow should run on... + push: # a push... + branches: # to one of these branches: + - 'main' + workflow_dispatch: # or when manually triggered pull_request: permissions: diff --git a/.github/workflows/test-game.yml b/.github/workflows/test-game.yml index 95047b89be..0f2a358667 100644 --- a/.github/workflows/test-game.yml +++ b/.github/workflows/test-game.yml @@ -1,6 +1,9 @@ name: test-game -on: +on: + push: + branches: + - 'main' workflow_dispatch: pull_request: paths: diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 11a6051035..82e4f41c21 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -1,6 +1,10 @@ name: Unit Tests -on: +on: # This workflow should run on... + push: # a push... + branches: # to one of these branches: + - 'main' + workflow_dispatch: # or when manually triggered pull_request: permissions: From 4f63445d4ba02223bbd7ad76dd6792a803a810a2 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 20:10:42 -0400 Subject: [PATCH 13/16] cut off after 15 seconds --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index e1925e8e61..9c2880100a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -32,14 +32,14 @@ jobs: - name: Wait for Server to Start run: | echo "Waiting for Astro dev server to start..." - for i in $(seq 1 60); do + for i in $(seq 1 15); do if curl -sf -o /dev/null http://localhost:3000; then echo "Server is up after ${i}s!" exit 0 fi sleep 1 done - echo "Server failed to respond within 60s" + echo "Server failed to respond within 15s" docker logs sprig-ci exit 1 From ed122caf6258fae2db36393603326e2ca8e4eb5c Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 20:21:14 -0400 Subject: [PATCH 14/16] hmmm --- .dockerignore | 4 ++ .github/workflows/docker.yml | 4 +- Dockerfile | 6 +- docker-compose.yml | 2 +- package.json | 2 +- yarn.lock | 103 ++++++++++++++++++++++++++++------- 6 files changed, 95 insertions(+), 26 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..d17e62a0a2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +node_modules +.git +dist +.astro diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9c2880100a..7cfd43ba99 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,7 +25,7 @@ jobs: run: | docker run -d \ --name sprig-ci \ - -p 3000:3000 \ + -p 4321:4321 \ -e NODE_OPTIONS="--max-old-space-size=4096" \ sprig-ci @@ -33,7 +33,7 @@ jobs: run: | echo "Waiting for Astro dev server to start..." for i in $(seq 1 15); do - if curl -sf -o /dev/null http://localhost:3000; then + if curl -sf -o /dev/null http://localhost:4321; then echo "Server is up after ${i}s!" exit 0 fi diff --git a/Dockerfile b/Dockerfile index 78dea6360e..062d98645a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -# Use Node.js 20 with Alpine as the base image -FROM node:20-alpine +# Use Node.js 24 with Alpine as the base image +FROM node:24-alpine # Set working directory in the container WORKDIR /app @@ -14,7 +14,7 @@ RUN yarn install --frozen-lockfile COPY . . # Expose the default Astro port -EXPOSE 3000 +EXPOSE 4321 # Default command to start the Astro app CMD ["yarn", "dev", "--host"] diff --git a/docker-compose.yml b/docker-compose.yml index 5caacb5e73..fd59498bd9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: context: . dockerfile: Dockerfile ports: - - "9996:3000" + - "9996:4321" environment: - NODE_ENV=production - NODE_OPTIONS=--max-old-space-size=4096 # Increase to 4GB diff --git a/package.json b/package.json index 67044d1007..b98f30785f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "react-icons": "^4.7.1", "rehype-external-links": "^2.0.1", "sass": "^1.58.0", - "svelte": "^3.54.0", + "svelte": "^4.0.0", "three": "^0.149.0", "throttle-debounce": "^5.0.0", "tinykeys": "^1.4.0", diff --git a/yarn.lock b/yarn.lock index fd53a9c3cd..1c14cff966 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.2.0": +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.2.1": version "2.3.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== @@ -930,18 +930,18 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== +"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@jridgewell/trace-mapping@^0.3.28": - version "0.3.31" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" - integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -1563,6 +1563,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8" integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== +"@types/estree@^1.0.1", "@types/estree@^1.0.6": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + "@types/express-serve-static-core@^4.17.33": version "4.19.6" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" @@ -1878,7 +1883,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.14.0: +acorn@^8.10.0, acorn@^8.14.0: version "8.16.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a" integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== @@ -1941,7 +1946,7 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.3.2: +aria-query@^5.3.0, aria-query@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== @@ -2045,7 +2050,7 @@ axios@^0.26.0: dependencies: follow-redirects "^1.14.8" -axobject-query@^4.1.0: +axobject-query@^4.0.0, axobject-query@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee" integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== @@ -2286,6 +2291,17 @@ clsx@^2.1.1: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== +code-red@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/code-red/-/code-red-1.0.4.tgz#59ba5c9d1d320a4ef795bc10a28bd42bfebe3e35" + integrity sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + "@types/estree" "^1.0.1" + acorn "^8.10.0" + estree-walker "^3.0.3" + periscopic "^3.1.0" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -2396,6 +2412,14 @@ css-selector-parser@^3.0.0: resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-3.1.2.tgz#181106cc2acc9fa74f0dbd6860c3305202284c81" integrity sha512-WfUcL99xWDs7b3eZPoRszWVfbNo8ErCF15PTvVROjkShGlAfjIkG6hlfj/sl6/rfo5Q9x9ryJ3VqVnAZDA+gcw== +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + css-what@^6.1.0: version "6.2.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.2.2.tgz#cdcc8f9b6977719fdfbd1de7aec24abf756b9dea" @@ -2771,7 +2795,7 @@ estree-walker@^2.0.1, estree-walker@^2.0.2: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== -estree-walker@^3.0.3: +estree-walker@^3.0.0, estree-walker@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== @@ -3525,6 +3549,13 @@ is-plain-obj@^4.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== +is-reference@^3.0.0, is-reference@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.3.tgz#9ef7bf9029c70a67b2152da4adf57c23d718910f" + integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw== + dependencies: + "@types/estree" "^1.0.6" + is-regex@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" @@ -3813,6 +3844,11 @@ load-yaml-file@^0.2.0: pify "^4.0.1" strip-bom "^3.0.0" +locate-character@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-3.0.0.tgz#0305c5b8744f61028ef5d01f444009e00779f974" + integrity sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA== + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -3932,7 +3968,7 @@ magic-string@0.30.5: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -magic-string@^0.30.10, magic-string@^0.30.14: +magic-string@^0.30.10, magic-string@^0.30.14, magic-string@^0.30.4: version "0.30.21" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91" integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ== @@ -4134,6 +4170,11 @@ mdast-util-to-string@^4.0.0: dependencies: "@types/mdast" "^4.0.0" +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + mdurl@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0" @@ -4769,6 +4810,15 @@ pathval@^2.0.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== +periscopic@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/periscopic/-/periscopic-3.1.0.tgz#7e9037bf51c5855bd33b48928828db4afa79d97a" + integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^3.0.0" + is-reference "^3.0.0" + picocolors@^1.0.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -5450,7 +5500,7 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.0, source-map-js@^1.2.1: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.2.0, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -5639,10 +5689,25 @@ svelte2tsx@^0.7.22: dedent-js "^1.0.1" scule "^1.3.0" -svelte@^3.54.0: - version "3.59.2" - resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.59.2.tgz#a137b28e025a181292b2ae2e3dca90bf8ec73aec" - integrity sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA== +svelte@^4.0.0: + version "4.2.20" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-4.2.20.tgz#31cae3e8f10ccdc6441fae8157c1e8da5965d228" + integrity sha512-eeEgGc2DtiUil5ANdtd8vPwt9AgaMdnuUFnPft9F5oMvU/FHu5IHFic+p1dR/UOB7XU2mX2yHW+NcTch4DCh5Q== + dependencies: + "@ampproject/remapping" "^2.2.1" + "@jridgewell/sourcemap-codec" "^1.4.15" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/estree" "^1.0.1" + acorn "^8.9.0" + aria-query "^5.3.0" + axobject-query "^4.0.0" + code-red "^1.0.3" + css-tree "^2.3.1" + estree-walker "^3.0.3" + is-reference "^3.0.1" + locate-character "^3.0.0" + magic-string "^0.30.4" + periscopic "^3.1.0" teeny-request@^8.0.0: version "8.0.3" From 3ffe8c581b772531a751cd730177f2e7e9db0b8f Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 20:24:12 -0400 Subject: [PATCH 15/16] fix exports --- src/lib/game-saving/account.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/game-saving/account.ts b/src/lib/game-saving/account.ts index 26f8a0250a..fbcfc271a9 100644 --- a/src/lib/game-saving/account.ts +++ b/src/lib/game-saving/account.ts @@ -1,7 +1,8 @@ import type { AstroCookies } from 'astro' import admin from 'firebase-admin' import { initializeApp } from 'firebase-admin/app' -import { FieldPath, getFirestore, Timestamp, WhereFilterOp } from 'firebase-admin/firestore' +import { FieldPath, getFirestore, Timestamp } from 'firebase-admin/firestore' +import type { WhereFilterOp } from 'firebase-admin/firestore' import { customAlphabet } from 'nanoid/async' import { lazy } from '../utils/lazy' import { generateGameName } from '../words' From 13ee81574b0296649a74861e61902495db6128ad Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 3 Apr 2026 20:29:04 -0400 Subject: [PATCH 16/16] fix jank --- src/lib/codemirror/util.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/codemirror/util.ts b/src/lib/codemirror/util.ts index 7b8c8ad1e1..19801e476a 100644 --- a/src/lib/codemirror/util.ts +++ b/src/lib/codemirror/util.ts @@ -2,7 +2,8 @@ import { foldable, foldEffect } from '@codemirror/language' import type { Text } from '@codemirror/state' import { EditorView, WidgetType } from '@codemirror/view' import type { SyntaxNodeRef, Tree } from '@lezer/common' -import { ComponentType, h, render } from 'preact' +import { h, render } from 'preact' +import type { ComponentType } from 'preact' export function getTag(name: string, node: SyntaxNodeRef, syntax: Tree, doc: Text) { if (node.name !== 'TaggedTemplateExpression') return