Go to file
type-two 39701884e3 Lane D S17 gate 3.2: THE POOL YARD — authored cold, in the game only by being chosen
site_04_pool_yard: E's ring (fourteen honest noes) east, the bed poolside, ONE
corroded post in the venturi channel where the NE corner wants steel. Authored
in the editor (palette shapes, iterative SCORE IT x3, canonical export).
Gauntlet: WINNABLE at $80 — 13 quads, 6 clean, 1 marginal; cheapest hold $40
(h1,t1b,p2,p3, 92.7 FULL, no rust); every 92%-cover line routes through c1 —
clean $65 rated on t1,p1,p2,c1, UNHOLDABLE on the two shapes that pull the eye
harder. audit.html over the shipped file reproduces the card to the digit.
Separation REFUSED with receipts (bare 83.7 FULL — mild-night canon, A's 0.4).

board.js (A's granted edit): pool_yard_southerly POOL entry with the audit
receipt. d.test: +5 pins (chosen-never-scripted, ring/rust facts, judged-XOR,
wreck apron, exposure $160). gardenfly.selftest (B's file, flagged): judged
walk 3 -> 4 in the same commit that ships the yard.

Selftest 515/0/0 (510 + 5, the count moved by exactly what was added).
Mutations: 1 full-suite (finding stripped -> DOUBLE red: B's walk 'UNJUDGED'
+ my XOR pin, 513/2), 10 probed (entry deleted/re-paired/receipt stripped/
scripted-slot, gnome unpriced/rust zeroed/fence priced, apron x3) — every one
red with its own words, controls green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 03:53:20 +10:00
.claude Sprint 11 integration: merge all lanes, wire leadFor + setBudget, untrack launch.json; Sprint 12 plan + prompts 2026-07-17 18:08:32 +10:00
docs assetcheck/look.html: the verify that answers "is this the right shape" 2026-07-18 16:01:39 +10:00
prototype Add side-systems to design doc + playable sail-storm prototype 2026-07-16 20:55:31 +10:00
tools Lane D S17 gate 3.2: THE POOL YARD — authored cold, in the game only by being chosen 2026-07-21 03:53:20 +10:00
web/world Lane D S17 gate 3.2: THE POOL YARD — authored cold, in the game only by being chosen 2026-07-21 03:53:20 +10:00
.gitignore Sprint 11 integration: merge all lanes, wire leadFor + setBudget, untrack launch.json; Sprint 12 plan + prompts 2026-07-17 18:08:32 +10:00
DESIGN.md Add side-systems to design doc + playable sail-storm prototype 2026-07-16 20:55:31 +10:00
LANE_PROMPTS.md Sprint 17 plan + prompts: the book of clients pt 1 — the board; John's seven-night ruling recorded 2026-07-21 00:09:22 +10:00
PLAN3D.md Correct PLAN3D asset inventory; log M0 contract additions 2026-07-16 21:33:42 +10:00
README.md Merge origin/main: S14 lane integration + review fixes; TEETH becomes SPRINT16 2026-07-19 10:34:21 +10:00
ROADMAP.md Merge origin/main: S14 lane integration + review fixes; TEETH becomes SPRINT16 2026-07-19 10:34:21 +10:00
server.py Vendor three.js r175, add stdlib dev server and launch config 2026-07-16 21:33:42 +10:00
SPRINT2.md Add Sprint 2 assembly instructions: wire proven modules into one playable storm 2026-07-16 22:24:35 +10:00
SPRINT3.md Add Sprint 3 plan and lane prompts: close the game loop 2026-07-17 01:11:16 +10:00
SPRINT4.md Add Sprint 4 plan and lane prompts: face and water 2026-07-17 02:03:47 +10:00
SPRINT5.md Add Sprint 5 plan and lane prompts: hail and the broom 2026-07-17 02:44:30 +10:00
SPRINT6.md Add Sprint 6 plan and lane prompts: winnable, then a week of nights 2026-07-17 08:54:02 +10:00
SPRINT7.md Add Sprint 7 plan and lane prompts: one truth, then the week 2026-07-17 09:48:23 +10:00
SPRINT8.md Add Sprint 8 plan and lane prompts: ship the week 2026-07-17 11:57:51 +10:00
SPRINT9.md Add Sprint 9 plan and lane prompts: pyrrhic call, $80 win, second site 2026-07-17 14:03:45 +10:00
SPRINT10.md Add Sprint 10 plan and lane prompts: sites are data 2026-07-17 15:12:55 +10:00
SPRINT11.md Add Sprint 11 plan and lane prompts: prove the corner block, then the job sheet 2026-07-17 16:44:11 +10:00
SPRINT12.md Sprint 11 integration: merge all lanes, wire leadFor + setBudget, untrack launch.json; Sprint 12 plan + prompts 2026-07-17 18:08:32 +10:00
SPRINT13.md QA pass: fix Enter storm-skip (deployed), log findings; Sprint 13 plan + prompts 2026-07-17 23:26:47 +10:00
SPRINT14.md Sprint 14 plan + prompts: the yard editor — sites are makeable 2026-07-18 14:50:26 +10:00
SPRINT15.md Merge origin/main: S14 lane integration + review fixes; TEETH becomes SPRINT16 2026-07-19 10:34:21 +10:00
SPRINT16.md Merge origin/main: S14 lane integration + review fixes; TEETH becomes SPRINT16 2026-07-19 10:34:21 +10:00
SPRINT17.md Sprint 17 plan + prompts: the book of clients pt 1 — the board; John's seven-night ruling recorded 2026-07-21 00:09:22 +10:00
THREADS.md Sprint 17 pt 1 integration: the board live (510/0/0), constraint seam verified at merge, [I] entry 2026-07-21 03:14:44 +10:00

HARD YARDS — rig it, then survive the night

(repo/product history: the project was codenamed SHADES through Sprint ~8; the shipped game is HARD YARDS. Internal docs and the gitea repo name still say shades — that's the same thing, not a second game.)

Geometry/tower-defense: you're a small person rigging shade sails against Australian storms. three.js r175 (vendored, no build step) + a zero-dep Python server. Everything the repo needs is in the repo.

Run it

python3 server.py --port 8801     # any free port
# game:     http://localhost:8801/web/world/index.html
# selftest: http://localhost:8801/web/world/selftest.html   (must be all green)
# 2D proto: http://localhost:8801/prototype/index.html      (the original thesis)

No pip, no npm, no build. Python 3.8+ and a browser.

Read in this order

  1. DESIGN.md — the design canon (what the game is)
  2. PLAN3D.md — the build canon (stack, contracts, lane model) · docs/MANUAL.md — the HOW: tool map, asset/site cookbooks, earned gotchas · ROADMAP.md — the growth canon (the arcs from the week to the business)
  3. THREADS.md — the append-only lane log. The project's memory. Read the last few [I] integrator entries to know the current state.
  4. SPRINT15.md — the current sprint (highest-numbered fired sprint wins: SPRINT16 is pre-speced TEETH and fires only when 15 integrates — its own header says so)
  5. LANE_PROMPTS.md — copy-paste prompts per lane, per sprint (bottom = newest)

The lane model (how this repo is built)

Five parallel Opus agents ("lanes"), each in its OWN clone, on its own branch:

lane owns
A main.js, world.js, camera, hud, week, sites, server — shell & integration, merge shepherd
B sail.js, rigging — cloth sim, economy, balance.test pen
C weather, skyfx, debris, storm/site wind data
D player, interact, ladder, broom — and the designated playtester
E Blender asset factory (tools/blender), models/, textures

Hard rules (they exist because each was earned — see THREADS):

  • One clone per lane. Never two agents in one working tree.
  • Rebase onto latest main before starting; small commits; push your branch.
  • File ownership is the merge strategy; cross-lane needs go in THREADS.md.
  • Selftest green after every landing. Skips must be real. An assert that cannot fail is decoration.
  • All sim code is deterministic (dt, t) — no Date.now, no rAF.
  • Measure, don't reason: the repo's biggest bugs were all "a number gathered from the wrong harness". When two harnesses disagree, find the variable.

Setup on a new machine

Gitea's SSH runs over tailscale (the public host is Cloudflare-proxied, no direct SSH). Add to ~/.ssh/config:

Host gitea.partly.party
    HostName 100.71.119.27
    Port 222
    User git

Then:

git clone git@gitea.partly.party:monster/hardyards.git ~/Documents/shades
for L in A B C D E; do
  git clone git@gitea.partly.party:monster/hardyards.git ~/Documents/shades-lane$L
  git -C ~/Documents/shades-lane$L checkout -B lane/$(echo $L | tr 'A-Z' 'a-z') origin/lane/$(echo $L | tr 'A-Z' 'a-z')
done

~/Documents/shades is the integration checkout (main; where merges and sprint docs happen). The five shades-lane* clones are where lane agents run.

Per clone, once: cp .claude/launch.example.json .claude/launch.json and pick a port of your own (integration 8823, lanes AE 88248828). The real launch.json is untracked — six checkouts on one laptop can't share one port.

Sprint cycle

  1. Fire lanes with the newest prompts at the bottom of LANE_PROMPTS.md (Lane A usually first if the sprint gives it rulings/blocking items).
  2. Lanes work, push their branches, log in THREADS.md.
  3. Integrate in the main checkout: merge origin/lane/{e,c,b,d} (THREADS.md conflicts resolve keep-both-chronological; real code conflicts get read), run selftest, play the result, write SPRINT(n+1).md + prompts, push main AND fast-forward all five lane/* branches to main.