71 Commits

Author SHA1 Message Date
Damon Pidhajecky f25b246b61 Add add-multiplayer skill + maze-tanks example (#20)
* 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>
2026-04-30 18:11:09 -04:00
dpid cc72ffc647 fix(worldlabs): pin three to ^0.180.0 to match Spark 2.0 peer dep
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>
2026-04-21 16:51:22 -07:00
dpid 561bfd094e feat(worldlabs): update skill for Spark 2.0 renderer
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>
2026-04-21 16:35:17 -07:00
rshtirmer eaa818074e refactor: unify site build + consolidate folder structure
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>
2026-03-13 17:14:22 -04:00
rshtirmer aced7bdf90 feat(gigachad-sim): add v2 character models and promo scripts
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>
2026-03-10 14:09:27 -04:00
Ryan Shtirmer fcc4922dcb Merge pull request #7 from OpusGameLabs/feat/skill-best-practices
feat(skills): apply Anthropic skill best practices to all skills
2026-03-10 14:06:59 -04:00
rshtirmer 1bd5b21d83 fix: address CodeRabbit PR #7 feedback
- 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>
2026-03-10 13:59:13 -04:00
rshtirmer 90269327a5 feat(worldlabs-arcade): 3D Gaussian Splat arcade walkthrough demo
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>
2026-03-09 17:31:10 -04:00
rshtirmer 7f2ea28eab feat(audio): add procedural BGM and SFX using Web Audio API
Add complete audio system with zero npm dependencies:
- Gameplay BGM (140 BPM workout beat, 6 layers, anti-repetition)
- Game Over BGM (70 BPM somber theme)
- 7 SFX: catch clank, miss thud, flex grunt, powerup chime,
  combo arpeggio, streak fanfare, entrance slam
- AudioBridge wires EventBus events to audio playback
- Mute button UI (bottom-right, M key shortcut, localStorage persist)
- AudioContext created on first user interaction (autoplay policy)
- All audio non-blocking with try/catch fallbacks

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-02 14:25:53 -05:00
rshtirmer f49458bcd2 feat(effects): add 3D spectacle effects — particles, floating text, screen juice
Add three new visual effects systems for the GigaChad Gym Simulator:

- ParticleManager: GPU particle pool (200 pre-allocated via THREE.Points),
  burst emissions on catch/miss/powerup/combo/streak/entrance events,
  ambient floating dust motes (30 always-active), expanding shockwave rings
- FloatingText: CSS-positioned score popups that project 3D catch positions
  to screen coords, scale with combo level, color-coded by weight type
- ScreenEffects: flash overlays (white/red/green/gold), camera FOV pulse
  on catch, directional light pulse, 60ms hit freeze, combo-scaled shake

All effects are non-blocking, degrade gracefully, and use Constants.js
for all magic numbers (35+ new EFFECTS config values).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-02 14:14:51 -05:00
rshtirmer 28fd68d18d feat(3d-assets): replace primitives with Meshy AI GLB models
- Add MODELS config to Constants.js with paths/scales for all 7 GLBs
- Player.js: load rigged GigaChad with AnimationMixer, walk/idle fadeToAction
  transitions via SkeletonUtils.clone(), primitive box fallback on failure
- WeightManager.js: load dumbbell/barbell/kettlebell GLBs, clone per spawn
  with independent materials for opacity fading, primitive fallback
- PowerupManager.js: load protein-shake GLB with green glow sphere,
  primitive cylinder fallback
- Game.js: preloadAll() 7 GLB paths before startGame(), render loop
  starts immediately for visible gym during loading
- All model loads have .catch() fallback to original primitives

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-02 13:53:58 -05:00
rshtirmer f6ef59c5be feat(gigachad-sim): scaffold GigaChad Gym Simulator (3D Three.js)
Endless gym workout simulator where GigaChad catches falling weights.
Core mechanics: left/right movement, auto-catch weights, combo system,
protein shake powerups (2x multiplier), flex bonus, 3-life system with
difficulty ramp. Full event-driven architecture with 18 events, mobile
touch controls, AI-readable state snapshot, and gym environment with
dramatic lighting.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-02 13:35:41 -05:00
rshtirmer 94a4af6cbb feat: add template gallery, new skills, clean up templates
- Add gallery system (manifest, build script, screenshot capture, telemetry)
- Add use-template and quick-game skills
- Add giga-simulator example game
- Rewrite game-audio skill, update add-audio skill
- Remove bundled scripts from templates (iterate-client, validate-architecture, verify-runtime)
- Update CLAUDE.md with gallery docs and telemetry section
- Update package.json with gallery build/capture scripts
- Clean up skill frontmatter across all skills
- Fix GLB model typechanges via .gitattributes update

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 11:06:18 -05:00
rshtirmer c37361872a chore: optimize all Meshy-generated GLBs, add MeshoptDecoder to game AssetLoaders
Ran optimize-glb.mjs on all Meshy-generated GLB assets:
- lowball-blitz: boomer 17MB→1.6MB, agent-boomer 15MB→1.3MB (91% reduction)
- rock-em-sock-em: 187MB total → ~19MB total (89-92% reduction)

Added MeshoptDecoder import to both games' AssetLoader.js so the
compressed GLBs decompress correctly at runtime.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-27 15:19:00 -05:00
rshtirmer 32f3bf96a3 feat(lowball-blitz): auto-targeting envelopes, Meshy boomers, mobile joystick, Play.fun SDK
- Auto-targeting envelopes: find nearest unhit house, aim with parabolic arc
- Meshy AI generated boomer GLBs for homeowners and real estate agents
- Virtual joystick for mobile with HAS_TOUCH capability detection
- SpectacleSystem: GPU particles, screen shake, combos, floating score text
- Strudel BGM + Web Audio SFX with mute toggle
- Play.fun SDK integration (addPoints/savePoints)
- Loading screen with progress bar for model preloading
- Promo video capture script (screenshot-based for WebGL)
- Deploy to GitHub Pages (rshtirmer.github.io/lowball)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-26 17:37:24 -05:00
rshtirmer 43e0cfe4dd feat(lowball-blitz): add Strudel BGM + Web Audio SFX with mute toggle
Integrate procedural audio system using @strudel/web for looping BGM
and Web Audio API for one-shot SFX. Gameplay BGM is an energetic
mischievous chiptune at 130 cpm with anti-repetition techniques
(cycle alternation, layer phasing, probabilistic notes). Game over
theme is somber at 60 cpm. Six SFX mapped to game events: throw,
hit, combo, damage, collect, near-miss. Mute button (bottom-left)
with M keyboard shortcut, preference persisted to localStorage.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-26 16:26:53 -05:00
rshtirmer 354107749d feat(lowball-blitz): add SpectacleSystem for visual polish (particles, shake, flash, trails)
Create GPU particle system with 500-particle pool, screen shake, flash overlays,
floating score text, speed lines, camera entrance tween, combo/streak effects,
near-miss slow-motion, and player/envelope trail particles. Wire into Game.js
animate loop with camera effect compositing. Add mega combo CSS with pulse
animation. All effects driven by EventBus spectacle events.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-26 16:03:58 -05:00
rshtirmer c851d3a924 feat(rock-em-sock-em): integrate rigged 3D models with AnimationMixer
Switch from static GLB models to Meshy AI rigged models with skeleton
support. Load walk/run animation clips from separate GLBs using
SkeletonUtils.clone() to preserve bone bindings. AnimationMixer drives
idle animations while programmatic wrapper transforms handle punch
lunge, block tilt, and head-pop knockout effects. Head bone is detected
and animated directly when available.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-26 15:45:13 -05:00
rshtirmer 10a080312b fix: move robots closer together inside the ring
Reduced robot Z positions from ±2.0 to ±0.8 so they're face-to-face
in proper boxing range. Pulled camera in closer and aimed at ring center.
Tightened hit range to match new distance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-26 15:24:01 -05:00
rshtirmer 4b2ee58ef0 feat(lowball-blitz): scaffold 3D endless runner with envelope-throwing mechanics
Implement Lowball Blitz -- a Three.js endless runner where an AI robot agent
sprints through a suburban neighborhood throwing lowball offer envelopes at houses.
Hit houses spawn panicking homeowners who drop collectible panic points. Dodge
enemy real estate agents carrying FOR SALE signs.

Core systems:
- Auto-run forward with left/right lane shifting (WASD/arrows + mobile touch)
- Envelope throwing (space/tap) with cooldown and Punch animation
- Procedural street generation (road, sidewalks, grass, lane markings, houses)
- House entities with colored boxes + triangular roofs, shake/flash on hit
- Homeowner NPCs with arm-waving panic animation, drop panic points
- Agent enemies walking toward player with FOR SALE signs
- Combo system (consecutive hits build multiplier up to 10x, 3s timeout)
- 3-life system with invincibility frames and flashing effect
- Speed increases over time (8 to 25 units/sec)
- Full render_game_to_text() for AI agent state reading
- Spectacle event hooks for future visual polish
- Mobile touch zones (left half dodge, right half throw)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-26 15:21:59 -05:00
rshtirmer 60f804770e fix: add post-generation verification and mandatory rigging to 3D skills
Addresses three issues found during Rock Em Sock Em Robots build:

1. **Model orientation**: Meshy models face unpredictable directions.
   Skills now mandate post-load verification with bounding box logging,
   rotationY in Constants.js (default Math.PI for Meshy), and Playwright
   screenshot confirmation.

2. **Model scale/fit**: Models can overflow their containers. Skills now
   include auto-scale fitting code patterns (target height calculation,
   container bounds check, floor alignment).

3. **Rigging is mandatory for humanoids**: Static models require hacky
   programmatic animation. Skills now mandate rigging through Meshy API
   for all bipedal characters, with full generate→rig→animate→integrate
   pipeline documentation including basic_animations and action_id usage.

Also fixes robot facing directions and ring scale in the example game.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-26 15:20:43 -05:00
rshtirmer 009c3f8d34 feat(rock-em-sock-em): integrate Meshy AI 3D models for robots and boxing ring
Replace primitive BoxGeometry/CylinderGeometry/SphereGeometry with Meshy AI-generated
GLB models for Blue Bomber, Red Rocker, and the boxing ring. Models are static (not
rigged), so the existing programmatic AnimationSystem is adapted to animate whole-model
transforms (lunge, tilt, head pop, idle bob) via a wrapper group pattern. All GLB loads
have try/catch with full primitive fallback. Models are preloaded on startup before
game logic begins.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-26 15:14:56 -05:00
rshtirmer f4b0812aa8 feat(rock-em-sock-em): scaffold 3D boxing game with punch/block/knockout mechanics
Two robots (Blue Bomber and Red Rocker) face off in a boxing ring.
Player controls the Blue Bomber with A/D/W keys or touch tap zones.
Red Rocker is AI-controlled with timing-based punch/block patterns.
Each hit reduces opponent head health; at zero, head pops up = knockout.
Score tracks rounds won. Game over when player gets knocked out.

Core systems: CombatSystem (damage, cooldowns, hit detection),
AISystem (timing patterns, reactive blocking), AnimationSystem
(punch/block/head-pop animations on primitive-built robots),
InputSystem (keyboard + mobile touch zones).

Includes spectacle events, combo tracking, and design-brief.md.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-26 14:59:58 -05:00
rshtirmer 1d42f19908 feat: add Biden/Trump character models, promo capture scripts, and 3D asset skill updates
Adds Biden and Trump GLB models to the character library and example projects.
Includes promo video capture and high-FPS conversion scripts for trump-vs-biden.
Updates game-3d-assets skill with new pipeline patterns.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-26 14:28:20 -05:00
rshtirmer 8854de2930 feat(trump-vs-biden): add visual effects system — particles, screen flash, camera shake, trails
Add EffectsSystem.js with 10 spectacle effects wired through EventBus:
- Opening: white camera flash + characters rise with easeOutBounce + ambient particles from frame 1
- Hit effects: particle bursts at impact, screen flash (red/blue), camera shake
- Throw effects: muzzle flash (PointLight) + small particle burst at throw origin
- Projectile trails: fading transparent spheres along projectile path
- Combo text: HTML overlay "Nx COMBO!" with scale animation, growing font size
- Streak milestones: full-screen text slam at combo 5/10/25 with large particle burst
- Damage feedback: red flash overlay, strong camera shake, HUD heart shake
- Arena glow pulse: edge glow strips oscillate opacity sinusoidally
- Game over: slow-motion (delta * 0.2), explosion particles, camera zoom
- Clean reset: all effects properly disposed on restart

All magic numbers in Constants.js EFFECTS object. Zero gameplay changes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-25 19:04:36 -05:00
rshtirmer ac482c0f78 feat(trump-vs-biden): scaffold 3D arena battle game
Implement the complete scaffold for Trump vs Biden 3D arena battle:

- Arena: 20x12 dark platform with glowing edges, atmospheric lighting/fog
- Player (Trump): Left/right movement, projectile throw with cooldown,
  gesture animations (point/clap/dance/twist), placeholder orange box
- Opponent (Biden): AI-controlled sinusoidal movement with random offset,
  periodic projectile throws aimed at player, placeholder blue box
- Projectiles: Glowing spheres with point lights, sphere-vs-sphere collision
- ProjectileManager: Spawn/update/collision pool with PLAYER_HIT/OPPONENT_HIT events
- Health system: 5 lives, hearts HUD, game over on depletion
- Scoring: Points per hit, combo tracking with timeout, combo bonus at 3+
- Input: Keyboard (A/D + Space) + mobile touch (left/right half + tap)
- HUD: Health hearts, score, combo counter below Play.fun safe zone
- Game over overlay with score/best, restart via button/Space/Enter
- Full EventBus events including spectacle hooks for visual polish step
- render_game_to_text() and advanceTime() for AI agent testing
- Design brief with expression maps for both characters

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-25 18:43:16 -05:00
rshtirmer bc0ca6e08b feat: 3D asset pipeline — animated characters, model search, OrbitControls template
Add the 3D parallel to the 2D pixel art pipeline:

- scripts/find-3d-asset.mjs: search & download GLBs from Sketchfab, Poly Haven, Poly.pizza
- skills/game-3d-assets: full skill with AssetLoader (SkeletonUtils.clone), OrbitControls
  camera, fadeToAction animation crossfade, camera-relative WASD, per-model facingOffset
- skills/add-3d-assets: user-invocable /add-3d-assets command
- 3d-character-library/: 4 animated GLBs (Soldier, Xbot, Robot, Fox) with manifest.json
- templates/threejs-3d: updated with animated character controller, OrbitControls,
  AssetLoader, third-person camera follow pattern
- examples/3d-asset-test: working demo with character cycling (C key), preloading,
  world props (barrels, crates), animated enemies
- make-game pipeline: Step 1.5 now works for 3D — character selection from library,
  world object search via find-3d-asset.mjs, full subagent instructions

Key learnings baked into skill:
- SkeletonUtils.clone() is mandatory for skeletal models (regular .clone breaks → T-pose)
- Model facing varies: facingOffset per character (Soldier -Z needs +PI, Robot +Z needs 0)
- OrbitControls + target-follow is the proven third-person pattern (from official three.js example)
- Preload all GLBs with Promise.all on startup for instant character cycling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-25 15:12:47 -05:00
rshtirmer 3de46e7371 fix(mog-showdown): force portrait mode, visible touch controls, larger projectiles
Desktop was stretching to landscape, ruining the vertical dodger layout.
Mobile had invisible tap zones and items too small to recognize.

- Force portrait with FORCE_PORTRAIT=true, pillarbox on desktop
- Replace OS-based isMobile with capability detection (ontouchstart)
- Add visible semi-transparent arrow buttons on touch devices
- Enable pointer events on all devices (not gated behind isMobile)
- Increase projectile sizes 50% for mobile readability
- Add FORCE_PORTRAIT option + TOUCH constants to phaser-2d template
- Add portrait-first, touch controls, and mobile sizing guidance to skills

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:02:27 -05:00
rshtirmer ba50764694 Set vite base path for mog-showdown GitHub Pages deployment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:45:08 -05:00
rshtirmer a0d84b9f41 Add intermediate character assets and promo conversion script for mog-showdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:44:12 -05:00
rshtirmer daf4b1f682 feat(mog-showdown): add procedural audio system (BGM + SFX via Strudel.cc + Web Audio API)
Add complete audio pipeline with Strudel for looping BGM and Web Audio API
for one-shot SFX. Three BGM themes (gameplay 135cpm, win 100cpm, lose 60cpm)
using synth oscillators only with anti-repetition techniques (cycle alternation,
layer phasing, probabilistic notes). Six SFX mapped to game events via EventBus.
Mute button in parallel UIScene visible across all scenes with M key shortcut
and localStorage persistence.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-24 17:36:17 -05:00
rshtirmer f37706f03b feat(mog-showdown): add autonomous promo video capture script
Create scripts/capture-promo.mjs that uses Playwright to record a 13s
promo video of uninterrupted gameplay. The script:

- Patches all death/game-over paths (loseLife, triggerGameOver,
  PLAYER_DIED listeners, hitByAttack, gameOver property) so the
  player never dies during recording
- Generates natural-looking ArrowLeft/ArrowRight dodging inputs with
  variable timing, quick taps, double-taps, and pauses
- Includes a 2s entrance pause so the bounce-in animation plays
- Records at 1080x1920 (9:16 portrait) via Playwright video
- Accepts --port, --duration, and --output-dir CLI args

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-24 17:29:00 -05:00
rshtirmer 296f9a62a4 feat(mog-showdown): add spectacle-first visual effects system
Add particle effects, screen shake, floating text, combo counter,
streak announcements, player trail, background pulse, and hit freeze
frames. Enhance opening moment with bounce-in + landing shake +
particle burst + flavor text. Polish game over screen with glow text,
scale-in panel, and ambient particles. All effects wired through
EventBus via new src/effects/ modules (ParticleManager, ScreenEffects,
TextEffects). 45+ configurable EFFECTS constants added.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-24 17:21:47 -05:00
rshtirmer 6da52b9289 feat(mog-showdown): add photo-composite bobblehead characters with expression system
Replace Graphics-only character rendering with photo-composite bobbleheads:
cartoon South Park-style bodies + photo head spritesheets. Add expression
system (NORMAL/HAPPY/ANGRY/SURPRISED) wired to gameplay events, idle
breathing animations, and hat-flying-off mechanic for Androgenic. Scale
up characters to 14-16% canvas width and projectiles by 20% with glow
outlines for better visibility.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-24 17:05:51 -05:00
rshtirmer 09460de9b0 feat(mog-showdown): scaffold looksmaxxing arena dodge game
Implement core gameplay loop for Mog Showdown: Clavicular vs Androgenic
in a side-scrolling arena. Dodge attacks (wigs, hats), collect power-ups
(protein shakes, dumbbells), fill the Mog Meter to trigger Frame Mog bursts.

- Clavicular entity with Graphics API character (prominent clavicles, sharp jaw, gold tones)
- Androgenic NPC with cap/wig mechanic (hat flies off during Frame Mog)
- Projectile system with 4 types (wig, hat, protein shake, dumbbell)
- SpawnSystem with difficulty ramp (intervals decrease over time)
- ScoreSystem with combo tracking and mog meter progression
- 3 lives system with invulnerability frames after hit
- Near-miss detection for spectacle events
- Dark arena theme with neon grid floor
- Entrance sequence (bounce-in + camera flash)
- Game over with mog result text ("YOU MOGGED HIM!" / "YOU GOT MOGGED!")
- Full render_game_to_text() with player, opponent, projectiles, combo

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-24 16:34:48 -05:00
rshtirmer 4c5c0f3309 Add promo video pipeline step and move nick-land-dodger to examples
- Add Step 2.5 (Promo Video) to make-game pipeline between visual
  polish and audio. Records autonomous 50 FPS gameplay footage using
  Playwright slow-mo capture + FFmpeg speed-up.
- Add skills/promo-video/ with full technique docs, capture script
  template, and FFmpeg conversion script
- Add skills/record-promo/ as standalone slash command
- Move nick-land-dodger into examples/ directory
- Add rule: games created from within game-creator go into examples/
- Add 8 new celebrity character spritesheets to character library
- Update game-assets skill with broad photo search and bobblehead body
- Renumber pipeline tasks (now 7 total)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:19:01 -05:00
rshtirmer 150fda32e7 Add face detection character pipeline and trump-mog example
Introduces the Node.js character build pipeline using face-api.js for
face detection and @imgly/background-removal-node for ML background
removal. Includes the trump-mog example game demonstrating South Park
photo-composite characters with Trump and Biden.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:52:09 -05:00
rshtirmer 573e5f96f7 Merge remote-tracking branch 'glitchtrend/main' into merge-glitchtrend-fork 2026-02-24 13:28:02 -05:00
rshtirmer ffe9113694 fix(audio): reduce BGM repetitiveness with cycle alternation and layer phasing
- Gameplay BGM: 4 alternating melody phrases, 3 bass progressions, 3 drum
  patterns, counter melody on offset .slow(1.5), pad chords on .slow(4),
  atmospheric texture on .slow(3) with probabilistic notes
- Game over BGM: 3 alternating melody phrases, alternating chords, ghostly
  texture layer
- Effective loop length now ~45 seconds before exact repeat (was ~8 seconds)

Also updates game-audio skill with anti-repetition guidance:
- New section in SKILL.md covering cycle alternation, layer phasing,
  probabilistic notes, filter cycling, and counter melodies
- All bgm-patterns.md examples updated to demonstrate these techniques

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:53:15 -05:00
glitchtrend c75ab0520b Replace text mute buttons with Phaser Graphics API speaker icon
Subagents consistently use this.add.text() for mute buttons because the
skill doc said "speaker icon" without providing code. Now SKILL.md has
complete drawMuteIcon() + _createMuteButton() code using fillRect,
fillTriangle, arc, and lineBetween that subagents can copy verbatim.

- SKILL.md: full Mute Button section with Graphics API drawing code
- game-creator.md, make-game.md: ban text buttons, reference skill code
- flappy-bird example: working reference implementation (UIScene, AudioBridge, GameState, EventBus)
- phaser-2d template: add AUDIO_TOGGLE_MUTE event

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:04:48 -08:00
rshtirmer de2edf1e5b chore(castle-siege): set vite base path for GitHub Pages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:00:21 -05:00
rshtirmer 49303e912b feat(castle-siege): add procedural audio — medieval siege BGM + SFX
Strudel.cc for looping BGM (gameplay battle theme at 120cpm, somber
game over at 60cpm, wave-complete victory fanfare). Web Audio API for
instant one-shot SFX (catapult launch, explosion, enemy death, castle
hit, war horn, castle destroyed, score chime). Mute toggle via M key
and circular button in bottom-right corner with localStorage persistence.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 17:56:47 -05:00
rshtirmer f7d180f49b feat(castle-siege): add enemy castle fortress at far end of battlefield
Enemies now emerge from a dark, menacing castle positioned at the
negative Z end of the battlefield. The enemy castle features darker
stone colors, blood-red tower roofs, glowing red windows, skull
decorations above the gate, flickering torches, and pulsing gate glow.
Spawn positions updated so enemies stream out of the enemy castle gate
with Z jitter for a natural streaming effect. LevelBuilder filters
trees/rocks that would overlap the enemy castle footprint.

Also fixes ParticleSystem event listener cleanup on destroy and adds
bounds checking for scorch mark pool access.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 17:49:12 -05:00
rshtirmer 7905d9d9bd feat(castle-siege): add visual polish — particles, screen shake, atmosphere, UI juice
Add comprehensive visual design layer (Step 2) to the 3D tower defense game:

- ParticleSystem: object-pooled (300 particles) with explosion bursts, enemy death
  fragments, marching dust clouds, castle damage debris, projectile fire trails,
  impact flashes, and ground scorch marks
- CameraShake: damped oscillation on projectile impact and castle hits
- ScreenEffects: red vignette flash on damage, progressive health tint, victory glow
  on wave clear, floating damage numbers, kill combo text (double/triple/quad/mega)
- Sunset atmosphere: vertex-colored sky gradient, purple fog that thickens per wave,
  low-angle warm directional light, rim backlight, ACES filmic tone mapping
- Castle: flickering torch lights on towers, banner wave animation, gate glow pulse,
  progressive damage darkening on materials
- Enemies: 25% larger for visibility, 6 wave-based color tiers, sword + handle geometry,
  death flash-white-then-fade animation with sinking rotation, marching dust emission
- HUD: wave banner slide in/out animation, health bar red pulse below 25%

All visual values in Constants.js, all communication through EventBus.
No gameplay mechanics altered.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 17:30:42 -05:00
rshtirmer da5c7add68 feat(castle-siege): scaffold 3D tower defense game
Castle Siege Defense -- a 3D tower defense where the player defends a
medieval castle against waves of marching enemies by tapping/clicking
to launch arcing projectiles with splash damage.

Architecture:
- EventBus singleton with 18 events across game, castle, enemy,
  projectile, wave, score, and audio domains
- GameState with wave, castleHealth, enemiesKilled, isMuted
- Constants.js for all config (castle, enemy, projectile, wave, camera,
  level, colors)
- Game.js orchestrator: init all systems, manage loop, auto-start

Gameplay systems:
- Castle: impressive medieval geometry (keep, 4 towers with cone roofs,
  walls, battlements, gate with arch, banners), damage flash feedback
- EnemyManager: wave spawning with lane distribution, increasing
  difficulty (+3 enemies/wave, +10% speed/wave), wave pause/complete
- ProjectileManager: parabolic arc trajectories, splash damage radius,
  cooldown, glowing impact effects
- InputSystem: raycaster tap-to-fire + Space key for testing
- LevelBuilder: terrain, dirt path, shadow-casting lighting, hemisphere
  light, sky dome, decorative trees
- HUD: wave banner, castle health bar with color shifts
- Menu: game over overlay with wave/score/best display

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 17:16:53 -05:00
rshtirmer 1e4571d18c chore: update .gitignore, add singularity-run base path, remove stray files
- Add .vite/, .claude/, .plan.md, .playwright-mcp/, test-*.png to .gitignore
- Add gh-pages base path to singularity-run vite config
- Remove stray test screenshots, debug script, vite cache

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:00:15 -05:00
rshtirmer 695a6ebe84 feat(barn-defense): upgrade to retina/DPR template patterns
Upgrade the barn-defense example to use the new high-DPI rendering
architecture from the Phaser 2D template, ensuring crisp rendering on
retina displays and proper responsive scaling across all screen sizes.

Key changes:
- Constants.js: Add DPR/PX canvas sizing, scale all spatial values
  (sizes, speeds, ranges, radii) by PX factor while preserving game
  logic values (HP, damage, costs, durations)
- GameConfig.js: Add Scale.FIT, CENTER_BOTH, zoom: 1/DPR, roundPixels,
  antialias, preserveDrawingBuffer
- index.html: Responsive viewport (max-scale=1, no user-scale),
  fullscreen game container
- main.js: Add render_game_to_text() and advanceTime(ms) test hooks
- PixelRenderer.js: Round canvas dimensions for fractional PX scales,
  use floor/ceil pixel rendering to avoid sub-pixel gaps
- All sprites (tiles, enemies, towers, projectiles): Scale by PX
- All scenes: PX-scale hardcoded offsets for text, buttons, particles
- All UI components: PX-scale button sizes, spacing, fonts, info panels
- All systems: PX-scale particle effects, path markers, barn drawing
- Grid math preserved: TILE_SIZE = 40*PX, GRID_COLS/ROWS unchanged

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 16:53:01 -05:00
rshtirmer 3142f9ddcd feat(vampire-survivors): upgrade to retina/DPR template patterns
Migrate all rendering from fixed 800x600 to dynamic DPR-aware canvas
sizing with PX scaling factor. The game now renders at native device
resolution on retina displays without CSS upscaling blur.

Changes:
- Constants.js: full rewrite with DPR detection, canvas sizing, PX
  scale factor; all spatial values (sizes, speeds, ranges, radii)
  multiplied by PX; time/logic values unchanged
- GameConfig.js: add Scale.FIT, CENTER_BOTH, zoom 1/DPR, roundPixels,
  antialias, preserveDrawingBuffer
- index.html: responsive viewport, full-screen container
- main.js: add render_game_to_text() and advanceTime() test hooks
- Scenes: SAFE_ZONE-aware UI positioning, proportional font sizing
  via UI ratios, PX-scaled layout in GameOverScene/UIScene/GameScene
- Entities: PX-aware pixel art sprite scale for Player, Enemy, XpGem
- Systems: PX-scaled particle sizes, spawn margins, weapon visuals,
  projectile knockback, garlic radius growth

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 16:52:58 -05:00
rshtirmer f6a7917763 feat(flappy-bird): upgrade to retina/DPR-aware rendering architecture
Adopt the new high-DPI template patterns so the game renders sharp on
all displays while preserving identical gameplay proportions.

Key changes:
- Constants.js: DPR detection, dynamic canvas sizing, PX scale factor;
  all pixel values converted to PX-scaled or ratio-based equivalents
- GameConfig.js: Scale.FIT + CENTER_BOTH + zoom:1/DPR, roundPixels,
  antialias, preserveDrawingBuffer
- index.html: responsive viewport (100% width/height instead of fixed
  400x600), user-scalable=no
- main.js: add render_game_to_text() and advanceTime() test hooks
- Scenes: proportional font sizes, UI ratios, PX-scaled positioning
- Entities/Systems: all drawing coordinates use PX factor
- Tests: canvas dimension check replaced with aspect-ratio assertion;
  old visual snapshots removed (will regenerate on next run)

Audio system (Strudel) is untouched. All EventBus events, GameState
structure, and Playwright test globals preserved.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 16:52:55 -05:00
rshtirmer 91981b44d4 feat: add crowd-dash example, rename example-game to asteroid-dodger
- Add crowd-dash: 3D neon city endless runner (Three.js) with particles,
  camera juice, synthwave audio, and death slow-motion
- Rename examples/example-game → examples/asteroid-dodger
- Enable agent teams in settings.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:35:01 -05:00