README said "target: partly.party, not wired yet". It's wired. tools/deploy.sh follows the GAMES doctrine (deploy-map skill): QA gate -> rsync web/ to VPS staging -> docker cp into forum-nginx -> verify. No build step, so web/ ships as-is: vanilla ES modules + importmap with three r175 vendored, all paths relative or resolved from import.meta.url, which is why it runs from a subdirectory with no base rewrite. 6.6 MB. nginx.conf needed no edit — its catch-all `root /usr/share/nginx/html` already routes any new directory, which is how blobbo works. /gutsy (no slash) 301s to /gutsy/. Excludes web/dev/ (ruling #5: never shipped). Verified live, not assumed: the lane harnesses 404 through to the arcade index. THE 200 THAT ISN'T. That same catch-all try_files means ANY missing file returns the arcade's index.html with HTTP 200. A deploy that lost every module would still curl 200 on all of them. So every check asserts on CONTENT, never on the status code — this is the failure deploy-map records as ".bin data URLs serving arcade HTML". The guard caught itself, too: it originally grepped for `<title>MonsterRobot`, but the arcade's real title is `~*~W3LC0M3 2 TH3 M0NST3R R0B0T P4RTY 4RC4D3~*~`, so it could never have fired. Matched against the live box now. DURABILITY, and it's John's call. This docker-cp's into the container's own layer, matching blobbo/glytch: zero downtime, nothing else touched, survives restarts and reboots (restart: unless-stopped) — but NOT `docker compose up --force-recreate` or an nginx image bump, which wipe it. Re-running the script is the fix. The durable alternative is a bind mount in forum/docker-compose.yml like cratewars/roguelike have, which costs a forum-nginx recreate and brief downtime across ALL of partly.party, so this script does not take that decision. ship-check (README says run it before deploying — I ran it after; my miss, and it came back clean): 1 auth N/A — static files, no endpoint/API/admin surface 2 secrets PASS — nothing secret-shaped in the payload or the diff 3 input/SSRF PASS — the only user string reaching a fetch is ?lvl=, and C gates it on the CAMPAIGN allowlist BEFORE the load (levels/index.js:151). Traversal tested live with `curl --path-as-is` (plain curl normalises ../ away and proves nothing): /etc/passwd never leaked. DEPOT_BASE in assets.js is unused — the manifest has zero external URLs. 4 money N/A 5 deploy PASS — verified by content + booted in a real browser: assets.misses() == [], 15 draws, 69k tris, zero console errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
60 lines
3.4 KiB
Markdown
60 lines
3.4 KiB
Markdown
# GUTS — a fantastic voyage through the alimentary canal
|
||
|
||
Browser flight-combat game (three.js, zero build step). You pilot **ENDO-1**, a microscopic
|
||
probe, mouth → rectum through five anatomically-grounded biomes: ride peristalsis down the
|
||
esophagus, cross the acid sea of the stomach, thread the villi forest of the small intestine,
|
||
survive the gas swamps of the colon. *Fantastic Voyage* × *Star Fox* × *Descent*.
|
||
|
||
- **Design:** [docs/GDD.md](docs/GDD.md) · **Look:** [docs/ART_BIBLE.md](docs/ART_BIBLE.md)
|
||
- **Architecture + contracts:** [docs/TECH.md](docs/TECH.md)
|
||
- **Asset generation:** [docs/PIPELINE.md](docs/PIPELINE.md)
|
||
- **How we work (lanes/rounds):** [docs/PROCESS.md](docs/PROCESS.md) — **read this first if you are a lane**
|
||
- **Current round:** [docs/LANES/ROUND1_INSTRUCTIONS.md](docs/LANES/ROUND1_INSTRUCTIONS.md)
|
||
|
||
## Run it
|
||
|
||
```bash
|
||
cd web && python3 -m http.server 8140
|
||
# http://localhost:8140 — the game
|
||
# http://localhost:8140/?stub=1&dbg=1 — stub world + debug HUD (works from day 0)
|
||
```
|
||
|
||
No bundler, no npm, no build. ES modules + import map; three.js r175 vendored in `web/vendor/`
|
||
(never CDN — the game must run offline). Before you finish a session: `bash tools/qa.sh`.
|
||
|
||
## The one-paragraph tech pitch
|
||
|
||
The whole canal is a **spline**. World position is `(s, θ, ρ)` — distance along the canal,
|
||
angle and radius in the cross-section. Tube walls are chunked extrusions along
|
||
parallel-transport frames; peristalsis and breathing are **vertex-shader displacement**
|
||
(cheap, squishy, everywhere); collision is an analytic radius test (no physics engine).
|
||
Caverns (mouth, stomach) switch the same controller to free 6DOF. Look is **synthetic
|
||
scanner** — dark endoscope void, SEM-style monochrome walls with FLUX-generated detail
|
||
textures, emissive-coded enemies. Everything is seeded + deterministic, and every asset is
|
||
optional at runtime — the game boots and plays asset-free with procedural fallbacks.
|
||
|
||
## Hard laws (all lanes)
|
||
|
||
1. **Determinism.** No `Math.random` outside `js/core/rng.js`. Seeded RNG only. qa.sh greps.
|
||
2. **Assets are optional.** Missing texture/model/audio ⇒ procedural fallback, never a crash.
|
||
3. **Eyeball everything.** Visual work isn't done until a screenshot is in `docs/shots/laneX/`.
|
||
4. **Perf budget:** ≤300 draw calls, 60 fps on M-series / mid laptop. Measure via `window.DBG`.
|
||
5. **Free-first.** Local MODELBEAST generation before any paid API; fal.ai is a gated fallback
|
||
(John's go). See PIPELINE.md.
|
||
6. **Git:** stage only your exact paths, commit + push each session, never `git add .`.
|
||
|
||
## Deploy
|
||
|
||
**Live: https://partly.party/gutsy/** — `bash tools/deploy.sh` (QA gate → rsync `web/` minus
|
||
`dev/` → `docker cp` into `forum-nginx` → verify). No build step; `web/` ships as-is.
|
||
|
||
Two things to know before you touch it, both documented at length in the script header:
|
||
- **It's ephemeral.** Content lives in the container's own layer (like blobbo/glytch), so a
|
||
`docker compose up --force-recreate` or nginx image bump wipes it — re-run the script. The
|
||
durable fix is a bind mount in `forum/docker-compose.yml` (what cratewars/roguelike use),
|
||
which costs a forum-nginx recreate and brief partly.party downtime.
|
||
- **A 404 there returns HTTP 200.** nginx's catch-all `try_files ... /index.html` serves the
|
||
arcade index for any missing file. Verify on content, never on status codes.
|
||
|
||
Origin: `ssh://git@100.71.119.27:222/monster/guts.git`.
|