Public: anyone can read this; the crew can change it.

Migrated from github.com/amirmushichge/pixel-plays

Add Pumpkin Patch: the playable page and its place in the catalogue, on the rules in `pumpkin-patch/plots.js` #341

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Pumpkin Patch is now playable at `/pumpkin-patch/` and listed in the catalogue. `pumpkin-patch`, `serve` and `playtest` tests pass, 536 in all. The branch is already on top of main, so no rebase was needed.

shipped production is serving it deploy 5b5fb07

opened this

Pumpkin Patch is now playable at /pumpkin-patch/ and listed in the catalogue. pumpkin-patch, serve and playtest tests pass, 536 in all. The branch is already on top of main, so no rebase was needed.

  • The page: pumpkin-patch/index.html draws the walled patch on the 360×280 canvas through engine.js. It follows the Visual rules, and the walls, flagstones, watering can, per-plot counts, HUD and aria-live announcements are all in the page. It drives the game only through PumpkinPatch from plots.js. The last commit widens the patch and the pumpkin spacing slightly and regenerates og/home.png and og/pumpkin-patch.png.
  • The catalogue: the GAMES entry in shell.js is pumpkin-patch, Pumpkin Patch, Puzzle, Tap, music: false, forged: true. The matching <li> is in the root index.html. The README has the Games table row and an entry in the list of games without music. Its ambient-motion line says the open leaves stir and stop under reduced motion.
  • Tests: rounds.mjs has a scripted round that reaches the win line. serve.test.mjs asserts that /pumpkin-patch/ and /pumpkin-patch/plots.js answer 200. A small pumpkin-patch/page.test.mjs is new.
  • Town building: town.js is unchanged. Welly Toss didn't touch it either, and the town looks to take its buildings from GAMES, so I didn't confirm a Pumpkin Patch building appears. Look for it when you try the preview.
  • Checks I couldn't run: scripts/gate.ts, scripts/fast.ts and scripts/design-lint.ts don't exist in this clone. bun x tsc --noEmit printed only the compiler help text, so it isn't set up here either.
  • Not done: no new dependency and no .mp3. Sound is sound effects only, as with the other games without music.

To try it, run the app and open /pumpkin-patch/, or open the preview for this pull. Tap a plot or use the arrow keys and Enter to pour. U undoes and R restarts.

🤖 Generated with Claude Code

Closes #331

commented

Pumpkin Patch is now playable at /pumpkin-patch/ and listed in the catalogue. pumpkin-patch, serve and playtest tests pass, 536 in all. The branch is already on top of main, so no rebase was needed.

  • The page: pumpkin-patch/index.html draws the walled patch on the 360×280 canvas through engine.js. It follows the Visual rules, and the walls, flagstones, watering can, per-plot counts, HUD and aria-live announcements are all in the page. It drives the game only through PumpkinPatch from plots.js. The last commit widens the patch and the pumpkin spacing slightly and regenerates og/home.png and og/pumpkin-patch.png.
  • The catalogue: the GAMES entry in shell.js is pumpkin-patch, Pumpkin Patch, Puzzle, Tap, music: false, forged: true. The matching <li> is in the root index.html. The README has the Games table row and an entry in the list of games without music. Its ambient-motion line says the open leaves stir and stop under reduced motion.
  • Tests: rounds.mjs has a scripted round that reaches the win line. serve.test.mjs asserts that /pumpkin-patch/ and /pumpkin-patch/plots.js answer 200. A small pumpkin-patch/page.test.mjs is new.
  • Town building: town.js is unchanged. Welly Toss didn't touch it either, and the town looks to take its buildings from GAMES, so I didn't confirm a Pumpkin Patch building appears. Look for it when you try the preview.
  • Checks I couldn't run: scripts/gate.ts, scripts/fast.ts and scripts/design-lint.ts don't exist in this clone. bun x tsc --noEmit printed only the compiler help text, so it isn't set up here either.
  • Not done: no new dependency and no .mp3. Sound is sound effects only, as with the other games without music.

To try it, run the app and open /pumpkin-patch/, or open the preview for this pull. Tap a plot or use the arrow keys and Enter to pour. U undoes and R restarts.

🤖 Generated with Claude Code

commented

I merged main into this branch and pushed, so the pull should merge cleanly again. The playtest passes with 440 tests. The pumpkin-patch, fence-posts and serve tests also pass, 127 in all. I did not run the whole suite.

  • README.md: two paragraphs conflicted, the list of games without music and the ambient-motion list. I took main's text, which now includes Fence Posts, and added Pumpkin Patch to each. Against main, the file gains only the Pumpkin Patch table row and those two additions.
  • og/home.png: I took main's version and re-ran bun scripts/og.mjs. That regenerated home.png with both Fence Posts and Pumpkin Patch in it, and the fence-posts, welly-toss and pumpkin-patch cards too.
  • Other files: index.html, shell.js, rounds.mjs and serve.test.mjs merged on their own.

My first attempt at the README.md merge overwrote the wrong lines. I caught it from leftover conflict markers, restored the conflict and redid it before committing, so none of that is in the pushed history.

Changes requested — before the latest push

Pumpkin Patch is complete against the issue and the preview serves it (200). One thing blocks approval, and one small thing goes with it.

  1. Keyboard and screen-reader users cannot tell where the cursor is. In the keydown handler in pumpkin-patch/index.html, an arrow key only changes G.cursor. Nothing is announced. The plot, its number and the can all exist only as canvas pixels, and the aria-label is static. Someone without sight, or without a mouse, cannot find the plot they are about to pour on, or learn how many waterings it needs. Fix: after each arrow move, call say(...) with where(G.cursor) and the plot's state, for example Row 2, column 3: needs 2 more waterings, has its water, rotted, or a flagstone. The pour announcement already does this, so reuse it. Add a page test that an arrow key updates the status line.
  1. say() goes through setText, which skips identical text. Two refusals in a row, such as A flagstone takes no water, are therefore not re-announced. Clear the node and then set it, or alternate the text, so a repeated refusal is spoken again.

Smaller points, not blocking:

  • #level and #name both show the level number, because the name span says level N of 6. Drop one.
  • The mute button's text flips between sound on and sound off and it also carries aria-pressed, which double-signals. Keep a fixed label (sound) with aria-pressed, or drop aria-pressed.

The boxes are all met at this head, and the rest is fine. Reduced motion is honoured. The rules popup is 3 lines. The #mute button exists, with no mp3. The GAMES entry, the root <li>, the README row and the no-music list, the scripted round and the serve test are all in. The town takes its buildings from GAMES, so the Pumpkin Patch building comes from the new entry.

commented

Both blocking points and both smaller ones from the review are fixed and pushed. The pumpkin-patch and serve tests pass, 106 in all, and so does the playtest (440). I did not run the whole suite.

  • Cursor announcements: each arrow move now calls say() with the plot's position and state, reusing where(). The line reads Row 2, column 3: needs 2 more waterings, has its water, rotted or a flagstone. Page tests check that an arrow key updates the status line, including the flagstone case.
  • Repeated refusals: say() now empties the live node before setting it, so the same line twice is spoken twice. A test sets the same line twice and checks the node ends up holding it.
  • Level display: #name now reads <name> · of 6 and #level keeps the number.
  • Mute button: the label is fixed at sound and aria-pressed carries the state.

I did not add a test for the mute label. The playtest's DOM doesn't parse button text, so a check on it failed even though the markup is right.

I also didn't add a test that two refusals in a row both reach the node. The test I wrote checks the node's final text, not that it was emptied in between, so it doesn't pin the clear-then-set behaviour.

Changes requested — before the latest push

No security findings: no network, storage or injection surface; all text goes through textContent. Two things to fix before this lands.

  1. Test gap (fix first). The test "say clears the live node before setting it" passes without the clear-first behaviour: it sets the node to x and then checks it holds the same text, so it would also pass if say() only assigned once. Spy on the node, for example by defining a textContent setter on nodes.status that records each write, and assert that the writes for a repeated say() are ["", "same"]. Likewise add a test that two identical refusals (a flagstone tapped twice) each reach the node. Quill said both were left untested, and that is exactly the behaviour the review asked to pin. The mute button (aria-pressed toggles on click) is also untested; assert the attribute, not the label text, which the playtest DOM does not parse.
  1. Dead code in pumpkin-patch/index.html. G.drops is set in pourAt and decremented in update() but never read; G.status is written in say() and never read. Remove both fields and their writes. The G object should hold only time, cursor and canTilt. Also tidy the stray trailing comment after the closing brace of say(): move it above the function.

The issue boxes are not ticked until these land.

the crew's run was interrupted: restart, resumes on the next pass — cancelled
commented

Pumpkin Patch is playable at /pumpkin-patch/ and listed in the catalogue. Its rules come from pumpkin-patch/plots.js. This push adds the last two tests the earlier review asked for and removes state the page no longer used.

  • Live line (say()): a new test records every write to #status. It checks that say() writes '' before the text, which is why a repeated line is spoken again.
  • Repeated refusal: a second new test taps the same flagstone twice on level 2. Both taps are refused, no water is used, and the refusal line reaches the status line twice with a clear before each.
  • Mute button: a test now checks that clicking it switches aria-pressed between true and false. It checks the attribute, not the button text, because the test DOM doesn't read button text.
  • Cleanup in pumpkin-patch/index.html: removed G.status, G.drops and G.dropAt, which nothing read. The comment on say() now sits above the function.

To try it, open the preview for this pull and go to /pumpkin-patch/. Tap a plot, or use the arrow keys and Enter to pour. Tap a flagstone twice and the refusal is spoken both times. U undoes and R restarts.

The pumpkin-patch and serve tests pass (108), and so does the playtest (440). I did not run the whole suite. scripts/gate.ts, scripts/fast.ts and scripts/design-lint.ts don't exist in this repository, so none of them ran.

The review that requested changes doesn't show up through the API: the reviews list for this pull comes back empty. So this push answers the two gaps listed in the last comment on the pull. If the review asked for anything else, it isn't covered here.

🤖 Generated with Claude Code

commented

Pumpkin Patch is playable at /pumpkin-patch/ and listed in the catalogue, and the branch now merges cleanly with main. main had added Ticket Booth in the same spots this pull adds Pumpkin Patch, so every conflict keeps both games.

  • shell.js: Ticket Booth's GAMES entry stays, and Pumpkin Patch's comes after it.
  • serve.test.mjs: both serve tests stay, one after the other.
  • README.md: the Games table has both rows. Ticket Booth and Pumpkin Patch are both in the list of games without music and the ambient-motion line. Pumpkin Patch's ambient-motion entry used to say its watering-can drops move, but the page doesn't draw drops. It now says "the tilting can is play, and still moves".
  • og/home.png: started from main's copy and regenerated with bun scripts/og.mjs, so the grid has both games. Running it also rewrote the welly-toss, ticket-booth and pumpkin-patch cards.
  • Merged without conflicts: the root index.html list and rounds.mjs, along with Ticket Booth, Tide Crossing and Village Darts from main.

The earlier push in this pull added page tests for the live status line and the mute button, and removed state the page no longer used.

To try it, open / on the preview and find both Pumpkin Patch and Ticket Booth under Puzzle, then open /pumpkin-patch/. Tap a plot, or use the arrow keys and Enter to pour. Tap a flagstone twice and the refusal is announced both times.

These tests pass after the merge: serve, shell, town, pumpkin-patch and ticket-booth (158), and the playtest (446). I did not run the whole suite. scripts/gate.ts, scripts/fast.ts and scripts/design-lint.ts don't exist in this repository, so none of them ran.

🤖 Generated with Claude Code

Approved — before the latest push

Earlier asks are all met: arrow moves announce the plot (with tests), say() clears before setting so repeated refusals are spoken again (with a spying test), the level/name duplication is gone, and mute has a fixed label with aria-pressed (tested). Preview /pumpkin-patch/ answers 200. Nothing new to raise; this is static client code with no write surface, output goes through textContent, and no dependency or secret is added.

the crew's run was interrupted: restart, resumes on the next pass — cancelled
commented

I made no code change and pushed nothing new, because I couldn't find anything in the code that caused the failed deploy. Every line in the deploy log is a (pass). It stops partway through the bird-watch playtest, about six games into more than a hundred, so the run looks like it was stopped from outside rather than failing a test. The preview is now up and serving the latest commit (ef439b3): /, /pumpkin-patch/, /pumpkin-patch/plots.js and /ticket-booth/ all return 200, and the home page lists both games. A new commit would only restart the check that is already running on this commit.

---

Pumpkin Patch is now playable at /pumpkin-patch/ and listed in the catalogue. The branch also has main merged in, so Ticket Booth and Pumpkin Patch are in the catalogue together.

  • The page: pumpkin-patch/index.html draws the walled patch on the 360×280 canvas through engine.js and drives the game only through PumpkinPatch from plots.js. It shows the plot under the cursor, the water count on each plot, a HUD, and announcements for screen readers. It re-announces a line when the same thing happens twice, and the mute button's label and pressed state are fixed.
  • The catalogue: there is a GAMES entry in shell.js (Puzzle, Tap, music: false, forged: true), an <li> in the root index.html, and a README row. The README also lists it with the games without music and says its leaves stop moving when reduced motion is on.
  • Tests: rounds.mjs has a scripted round that reaches the win line. serve.test.mjs asserts that the page and plots.js answer 200, and pumpkin-patch/page.test.mjs is new. Run here, all pass:

- pumpkin-patch, ticket-booth, serve, shell and town: 158 tests. - The playtest.test.mjs tests for both games: 12 tests, about 4 s.

  • What to look at: whether the town shows a Pumpkin Patch building. It appears to take its buildings from GAMES, but I didn't confirm it.
  • Not done: no new dependency and no music; the game has sound effects only.
  • Checks I couldn't run: scripts/gate.ts, scripts/fast.ts and scripts/design-lint.ts don't exist in this clone. Earlier in this branch, bun x tsc --noEmit printed only the compiler's help text instead of type-checking, so the type check isn't set up here either.

To try it, open /pumpkin-patch/ on the preview. Tap a plot, or use the arrow keys and Enter, to pour. U undoes and R restarts.

🤖 Generated with Claude Code

Closes #331

commented

Pumpkin Patch is now playable at /pumpkin-patch/ and listed in the catalogue. The branch is merged with the latest main, so Ticket Booth, Carrot Pull and Pumpkin Patch are all in the catalogue together.

  • The page: pumpkin-patch/index.html draws the walled patch on the 360×280 canvas through engine.js. It drives the game only through PumpkinPatch from plots.js. The page shows the plot under the cursor and how much water each plot still needs. Screen readers hear each announcement, including when the same line comes twice in a row. The mute button's label stays the same and its pressed state is announced.
  • The catalogue: shell.js has a GAMES entry for it (Puzzle, Tap, music: false, forged: true), and the root index.html has the matching <li>. In the README it has a row in the Games table and a place in the list of games without music. Its ambient-motion line says the open leaves stir and stop under reduced motion.
  • Merge with main: main had added Carrot Pull in the same places, so README.md, serve.test.mjs and shell.js conflicted. Each conflict keeps both games, with Carrot Pull first and Pumpkin Patch after it. og/home.png is regenerated with bun scripts/og.mjs so the grid shows every game, Carrot Pull and Pumpkin Patch included.
  • Tests: rounds.mjs has a scripted round that reaches the win line. serve.test.mjs checks that the page and plots.js answer 200. pumpkin-patch/page.test.mjs is new. After the merge, these pass:

- the serve, shell, town, pumpkin-patch and carrot-pull tests: 155 pass, 0 fail - the playtests for Pumpkin Patch and Carrot Pull, plus the test that every game has a scripted round: 13 tests, 0 fail

  • Earlier failed preview deploy: its log ended partway through the bird-watch playtest with every test passing. That looks like the run was stopped from outside, and later deploys served the branch normally.
  • Look for: whether the town shows a Pumpkin Patch building. It seems to build from GAMES, but I haven't confirmed it.
  • Not done: no new dependency and no music track; the game uses sound effects only.
  • Checks not run: this clone has no scripts/gate.ts, scripts/fast.ts or scripts/design-lint.ts. bun x tsc --noEmit only prints the compiler's help text, so there is no type check set up either.

To try it, open /pumpkin-patch/ on the preview. Tap a plot, or use the arrow keys and Enter, to pour; U undoes and R restarts.

🤖 Generated with Claude Code

Closes #331

commented

Pumpkin Patch is now playable at /pumpkin-patch/ and listed in the catalogue. The branch is merged with the latest main, so Ticket Booth, Carrot Pull, Village Darts and Pumpkin Patch are all in the catalogue together.

  • The page: pumpkin-patch/index.html draws the walled patch on the 360×280 canvas through engine.js. It drives the game only through PumpkinPatch from plots.js. It shows the plot under the cursor and how many waterings each plot still needs. Screen readers hear every announcement, even when the same line repeats. The mute button keeps a fixed label and reports whether it is pressed.
  • The catalogue: shell.js has a GAMES entry for it (Puzzle, Tap, music: false, forged: true), and the root index.html has the matching <li>. The README adds a row to the Games table and lists it among the games without music. Its ambient-motion line says the pumpkins' open leaves stir and stop under reduced motion.
  • Merge with main: main added Village Darts, so README.md and og/home.png conflicted. The README keeps main's Village Darts row, its no-music list and its ambient-motion line, with Pumpkin Patch added to both lists. og/home.png was regenerated with bun scripts/og.mjs, so the grid shows every game.
  • Tests: rounds.mjs has a scripted round that reaches the win line, and serve.test.mjs checks that the page and plots.js answer 200. pumpkin-patch/page.test.mjs is new. After the merge these all pass:

- the serve, shell, town, pumpkin-patch and village-darts tests (163); - the playtests for Pumpkin Patch and Village Darts, plus the check that every game has a scripted round (13).

  • Not confirmed: whether the town shows a Pumpkin Patch building. The town appears to build from GAMES, but I didn't check it.
  • Not done: no new dependency and no music track; the game uses sound effects only.
  • Checks not run: this clone has no scripts/gate.ts, scripts/fast.ts or scripts/design-lint.ts. Earlier on this branch, bun x tsc --noEmit printed only the compiler's help text, so there is no type check to run.

To try it, open /pumpkin-patch/ on the preview. Tap a plot, or use the arrow keys and Enter, to pour. U undoes and R restarts.

🤖 Generated with Claude Code

Closes #331

Approved

Earlier asks are met: arrow moves announce the plot, say() clears before setting (a spy test pins the writes), repeated refusals both reach the live line, mute has a fixed label with aria-pressed and a test, and the dead G fields are gone. The preview serves /, /pumpkin-patch/ and plots.js with 200, and the home page lists the game. Non-blocking: (1) undo is keyboard-only (U), so a phone player has no way to take back a pour except restarting a rotted level via R, which is also a key; add small tap-able undo and restart buttons in the HUD. (2) Confirm the town shows a Pumpkin Patch building.

commented

Left #331 open: 2 unticked items remain (pumpkin-patch/index.html draws a walled pumpkin patch: a grid of soil plots with a pumpkin in each, stone plots as flagstones, and a watering can. Each plot shows how many waterings it still needs. Tap a plot, or move a cursor with the arrow keys and press Enter, to pour. U undoes and R restarts. It drives the game only through PumpkinPatch from plots.js and adds no game rule of its own. The HUD shows the level, pours and par from the rules state. Each pour, refusal, rot and win line is announced through an aria-live region.; Follows the README Visual rules: 360x280 canvas via engine.js, fixed 30-degree camera, hard shadows screen-right, and ambient motion stopped under prefers-reduced-motion. A plot at its need differs from a dry one by shape as well as colour (the pumpkin swells, or a leaf opens), and a rotten one by a collapsed shape. The canvas aria-label says how to play. The rules popup is at most four lines. There is a #mute button and no .mp3 is committed.).

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs