The previous animate-mode extension check looked for "gif" in the style
name, but documented animation styles (walk-cycle, idle, attack) never
contain that substring, so GIF responses were always saved as .png and
wouldn't load. Sniff the base64 prefix instead.
Also drop unused `extname` import and add a `/retrodiffusion` row to the
README slash-commands table to match the new user-invocable skill.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add add-multiplayer skill (PartyKit backend)
New user-invocable skill that adds real-time or turn-based multiplayer to
existing browser games via PartyKit (Cloudflare Durable Objects). Follows
the additive-edit pattern from scaffold-gateables and the integration-flow
pattern from monetize-game.
Single-player gameplay is preserved when the server is unreachable —
NetworkManager catches all connection errors and emits network:disconnected
without throwing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add maze-tanks example to dogfood the add-multiplayer skill
Built via the /make-game pipeline + /add-multiplayer end to end —
4-player Phaser tanks-in-a-maze with PartyKit realtime sync (20Hz),
shooter-authoritative bullets, broadcast deaths, and design-pixel
wire format that's PX-independent across clients with different
window sizes/DPRs. Live-players-only (no NPC bots).
Live deploy verified at maze-tanks-multiplayer.dpid.partykit.dev.
STEP*-DONE.md files capture ~14 actionable findings from running
both pipelines as a real user would. Notable ones: clerk auth flow
is broken in 2026 (use --provider github), wire format must be
PX-independent, local-human deaths must broadcast regardless of
killer, round-end consensus needs human-only counting.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Apply add-multiplayer skill fixes from maze-tanks dogfood findings
Addresses 9 of the 10 findings surfaced while building examples/maze-tanks.
The 10th (RECONNECT_*BACKOFF_MS naming) was a non-issue — the skill files
are internally consistent; the inconsistency was introduced by a per-game
override in the dogfood example.
Changes by file:
- SKILL.md: Step 6 now requires `--provider github` for partykit login
(default `clerk` flow hangs on retired dashboard.partykit.io). New
troubleshooting entries for the clerk hang and the welcome race.
- deploy.md: Step 2 rewritten around GitHub device-code OAuth. New
troubleshooting entries for clerk hang, partykit npm-audit transitive
vulns (don't `audit fix --force`), and parent .env inheritance by
partykit dev.
- partykit-server.md: `compatibilityDate` bumped to 2026-01-15 with a
policy note about keeping it within ~6 months. `src/types.ts` marked
REQUIRED (the realtime/turn-based templates import from it).
- architecture.md: documents that the wire schema is open (games may add
fields like `rotation`); requires positions broadcast in design pixels
for PX-independence; constructor-ordering footgun for `gameState.multiplayer`
reset(); detect Constants umbrella vs per-block export shape before
patching.
- client-integration.md: `NetworkManager._connect` guards `import.meta`
for non-Vite contexts; reset() block uses `if (this.multiplayer)`
guard; new "Welcome-race gotcha" section with idempotent seed-then-
subscribe pattern; comment in NetworkManager imports about adapting
to umbrella vs per-block Constants.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Remove implementation logs; clean up README and package.json
The 6 STEP*-DONE.md files were build-session implementation logs from
the agentic pipeline that produced this example. Their useful findings
have already been folded into the skill docs (architecture.md,
client-integration.md, deploy.md, partykit-server.md, SKILL.md). The
maze layout, code changes, and bug fixes are all visible in the source
and git history.
- Delete STEP{1,1.5,2,3}-DONE.md, STEP-MULTIPLAYER-DONE.md, STEP-MP-GLUE-DONE.md
- Update README.md header tagline + remove the build-journal section
- Update package.json description
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add maze-tanks to the examples list in CLAUDE.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Address coderabbit major findings on add-multiplayer
8 fixes for issues flagged in CodeRabbit's review pass:
1. server.ts: UTF-8 byte-length check via TextEncoder so multibyte
chars don't slip past MAX_MESSAGE_BYTES (was using JS string .length).
Also persist the server-stamped state in `peers` so late joiners
see the same `ts` as everyone else.
2. NetworkManager.js: clear room-switch race by deferring the new
connect to _onSocketClosed via `pendingRoomId`. Old behavior raced
the previous socket's async close, misclassifying it as an error
and triggering a duplicate reconnect on top of the new room.
3. NetworkManager.js: emit network:disconnected when client.connect()
throws synchronously — the single-player fallback was relying on
socket callbacks that never fire in that path.
4. MazeSystem.js: handle zero-distance overlap in resolveCircle().
When dx == dy == 0, the previous code yielded NaN normals and
left the entity embedded in the wall.
5. GameScene.js: extract the TANK_DIED / ROUND_ENDED HUD listeners to
stable refs and unregister them on Phaser SHUTDOWN. Previous inline
lambdas leaked across scene restarts.
6. Bullet.js: cross-client unique IDs (shooterId:timestamp:seq)
instead of `b${seq++}` which collided across tabs.
7. RemotePlayerRegistry.js: validate playerId is a non-empty string
before mutating the remotePlayers map (defends against malformed
network messages, including __proto__-style attacks).
8. EventBus.js: add SPAWN_ASSIGNMENTS_CHANGED to the catalog (it was
being emitted as a string literal, breaking the no-magic-events
convention).
Skill docs updated to match (architecture.md PX scaling for remote
positions, client-integration.md room-switch handoff, partykit-server.md
TextEncoder pattern).
partykit.json compatibility date pinned to 2024-09-25 (a stable
PartyKit-published date; previous 2025-01-01 wasn't a real release).
tsconfig adds WebWorker lib so TextEncoder + console types resolve.
All changes verified via tsc + node --check.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: rshtirmer <rshtirmer@gmail.com>
Bronze tier is the default experience everyone plays — no feature is
gated behind it. Previous proposal logic was creating bronze-tier
features (e.g. a "QoL screen-shake toggle") which is a no-op gate.
Updates principle 4, the tier vocabulary section, the example proposal
table, the Step 1.25 subagent prompt, and related copy across make-game
and the skill frontmatter to exclude bronze from feature scaffolding.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops option 5 from the Step 0 question. Ambiguous answers are re-asked
rather than silently defaulting to Play.fun — simpler branching, one
fewer code path to maintain.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces /scaffold-gateables, a monetization-agnostic skill that adds
gateable features (skin picker, continue-after-death, bonus mode, QoL
toggles) to an existing game with a single isEntitled() capability seam.
Games stay fully playable with every gateable locked by default; any
paywall, subscription, or entitlement layer can flip them on later.
Wires it into /make-game as conditional Step 1.25, driven by a new
"monetization intent" question in Step 0 (none / Play.fun / sub.games /
both / unsure). This closes the gap where /subgames (subdotgames/skills,
separate repo) had nothing meaningful to gate on fresh pipeline output.
Also branches Step 4 "next up" messaging, Step 5, and Pipeline Complete
on the intent; converts task-number references to semantic names so
numbering shifts cleanly when Step 1.25 is included or skipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two parallel subagents re-benchmarked the instancing patterns from scratch
(temp dirs, fresh Three.js r183 install, headless Chromium via Playwright,
30 warmup + 180 sample frames, median of 3 runs).
Core claim reproduced: InstancedMesh wins by 1–2 orders of magnitude on
CPU-side metrics (draw calls, render CPU, update loop, build time).
Changes:
- Replace all cited numbers with measured values
- Drop Traversal p95 from headline metrics (hits noise floor in both
variants with modern Three.js — not a meaningful before/after signal)
- Add Render CPU p95 as the headline timing metric (was not in PR #10)
- Add methodology note: SwiftShader in headless Chromium makes GPU-bound
metrics (FPS, frame time) unreliable; CPU-side metrics are trustworthy
- Clarify static-world optimized case is "2 draw calls" (InstancedMesh +
floor plane), not 1
- Note baseline ~19,365 (not 19,600) because individual meshes frustum-cull
at the edges; InstancedMesh does not cull per-instance
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New reference skill covering InstancedMesh patterns for draw-call reduction,
with measured before/after numbers (19,600 → 1 draw calls for static scenes,
8,000 → 1 for moving entity fields).
- skills/threejs-perf/SKILL.md: core patterns + decision tree + measured results
- instancing-static.md: InstancedMesh for static repeated objects
- instancing-moving.md: flat state buffer + batched setMatrixAt writes
- templates/: 4 baseline vs optimized reference snippets
Also wires the new skill into threejs-game (companion pointer + draw-call
tip), make-game step 1 (loaded alongside threejs-game for 3D projects),
and CLAUDE.md (skill tree + reference-skill count + companion-files list).
Focused cherry-pick from #10 — drops the benchmark harness, custom
agent-skills standard, and validator (Anthropic's Skills format is now
canonical), plus the mini-world/bot-arena demos.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spark 2.0 declares `three@^0.180.0` as its peer. Three treats every 0.x
minor as potentially breaking, so the previous `three@^0.183.0` pin
caused ERESOLVE on `npm install` for both the worldlabs-arcade example
and any new game scaffolded from the threejs-3d template + /worldlabs.
- examples/worldlabs-arcade: three ^0.183.0 → ^0.180.0
- templates/threejs-3d: three ^0.183.0 → ^0.180.0
- skills/worldlabs/SKILL.md: document the three@^0.180.0 requirement
alongside the @sparkjsdev/spark@^2.0.0 pin
Verified with a clean `npm install` in examples/worldlabs-arcade — no
peer warnings, no --legacy-peer-deps needed. Template uses only stable
pre-0.150 three APIs (Scene, WebGLRenderer, GLTFLoader, OrbitControls,
MeshoptDecoder, SkeletonUtils), so stepping back 3 minors has no
functional impact.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Document SparkRenderer as the Three.js integration point for World Labs
Gaussian Splat scenes (was SplatMesh-only). Surface the 2.0 quality knobs
(sortRadial, enableLod, lodSplatScale, maxPixelRadius), switch the render
loop snippet to setAnimationLoop, use `await splat.initialized` as the load
completion idiom, and add troubleshooting for the 2.0-specific failure
modes (missing SparkRenderer = black scene, LOD pop, unlit GLB characters
via renderEnvMap). Re-aligns the skill docs with the reference
implementation in examples/worldlabs-arcade, which already uses the 2.0
API.
Also pins the example's @sparkjsdev/spark dependency from "latest" to
"^2.0.0" to prevent silent breakage on future majors.
Bumps skill metadata version 1.3.0 → 1.4.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Templates now read --ogp-safe-top-inset and --ogp-safe-bottom-inset CSS
variables set by the Play.fun SDK, so game UI stays visible on fullscreen
mobile Safari across all tab modes. Skills updated to document the pattern
for AI-generated games.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reduce top-level directories from 19 to 14 and unify the two
disconnected site pages into a single build script.
Site unification:
- gallery/ → site/ (manifest.json, build.js, thumbnails/, telemetry/)
- New unified site/build.js generates both _site/index.html (landing)
and _site/gallery/index.html (gallery) with shared CSS, nav, footer
- Landing page game cards are now data-driven from manifest (no drift)
- Optional benchmarks section renders when site/benchmarks.json exists
- npm run build:site produces the whole _site/
Directory consolidation:
- character-library/ + 3d-character-library/ → assets/characters/ + assets/3d-characters/
- evals/ → tests/ (trigger files, flows, README)
- docs/troubleshooting.md → TROUBLESHOOTING.md
- benchmarks/ deleted (empty)
All references updated across ~15 files (CLAUDE.md, skills, templates,
package.json, examples).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code's plugin validator uses strict schema validation and rejects
unknown top-level keys. The "openclaw" field causes installation to fail
with: Unrecognized key: "openclaw"
- Strip trailing .,;:!) from captured key values so mid-sentence
pastes like "MESHY_API_KEY=abc123." save correctly
- Anchor all .env grep checks with ^KEY=. to avoid matching comments
or empty assignments
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Skip placeholder values (your-key-here, <key>, etc.) so example
text from skill prompts is never saved as a real secret
- Auto-append .env to the target project's .gitignore when saving keys
- Make additionalContext provider-agnostic (remove hardcoded meshy ref)
- Use `set -a; . .env; set +a` instead of `source .env` so vars are
exported to child processes (node, npx)
- Fix grep/cut command in game-deploy to anchor match and preserve
keys containing = characters
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
API keys pasted in chat previously ended up in Claude's context window.
This adds a UserPromptSubmit hook that detects key patterns, saves them
to .env, and blocks the message so keys never reach the model.
- Add scripts/intercept-api-key.mjs (zero deps, explicit + bare key detection)
- Add hooks.UserPromptSubmit config to settings.json
- Add .env to .gitignore
- Update 6 skill prompts to use KEY=value paste format with .env check-first
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add argument-hint to 11 skills missing it (26/27 now covered, playdotfun submodule excluded)
- Standardize compatibility field placement to root level (game-qa, meshyai)
- Improve README positioning with outcome-focused opening
- Create trigger test suite (tests/trigger-tests.md) with 5-7 prompts per skill
- Add troubleshooting guide (docs/troubleshooting.md) covering all common issues
- Document reference/wrapper skill convention in CLAUDE.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split large SKILL.md into focused companion files to improve
readability and maintainability:
- character-pipeline.md: South Park system, expressions, bobblehead, 4-tier fallback
- pixel-renderer.md: renderPixelArt(), renderSpriteSheet(), palette definitions
- integration-patterns.md: entity replacement, animation, external assets, logos, memes
Added Performance Notes section and updated Reference Files listing.
Extracted sections replaced with one-line See references in SKILL.md.
YAML frontmatter, role intro, asset tiers, sprite design rules, process
steps, and checklist all retained in SKILL.md.
Co-Authored-By: Claude <noreply@anthropic.com>
Move the button pattern code block (~60 lines) from SKILL.md to
game-objects.md and the responsive canvas config code (~100 lines,
including entity sizing, HTML boilerplate, portrait-first patterns)
to project-setup.md. Replace with cross-references. Rename References
section to Reference Files and update companion descriptions.
Co-Authored-By: Claude <noreply@anthropic.com>
Covers T-pose from wrong clone method, Meshy AI prompt tips, rigging
failures, meshopt decoder errors, and model facing direction fixes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 5 common troubleshooting entries covering auth callback issues,
game registration errors, SDK loading with ad blockers, savePoints
modal timing, and API key configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds rigged GigaChad v2 GLB models (idle, walk, run) and helper scripts
for promo video capture and high-FPS conversion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds skill for generating 3D Gaussian Splat environments via World Labs API,
plus worldlabs-generate.mjs helper script. Updates .gitignore to exclude
.herenow/ deployment artifacts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Menu.js: fix redundant ternary — properly convert hex constant to CSS color
- EventBus.js: spread-copy listener array before iterating to prevent
mutation issues when listeners call off() during emit
- gigachad.meta.json: remove expired Meshy AI signed URLs, keep task IDs
for re-generation
- qa-game SKILL.md: remove "accessibility" from description since no
axe tests are generated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
World Labs SPZ environment with animated Soldier character (Three.js + SparkJS).
Fixes Y-flip, panorama doubling, character scaling, third-person camera, and
ground raycasting for navigable photorealistic arcade scene.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>