Reflects completed migration from DigitalOcean to local Hyper-V server. Adds game deployment strategy (engine-first, Docker for complex games) and server connection info. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.6 KiB
GamerComp.com - AI Game Arcade
Mobile-first game arcade where kids (8-16) play AI-generated HTML5 canvas games, create games via wizard, and earn XP.
Quick Reference
./deploy.sh # Build + restart + reload nginx
./deploy.sh --clear-cloudflare # Also purge CDN cache
pm2 logs gamercomp-api --lines 50
sudo -u postgres psql -d game_arcade
Tech Stack
| Layer | Tech |
|---|---|
| Frontend | React 18, Vite, React Router, PWA |
| Backend | Node.js, Express, PostgreSQL, Redis |
| Auth | JWT + FingerprintJS (guests) |
| AI (generation) | Claude Sonnet (claude-sonnet-4-20250514) — streaming |
| AI (lightweight) | Claude Haiku (claude-haiku-4-5-20251001) — tweaks, refinement, summaries |
| Push | Web Push (VAPID) via web-push |
| Infra | KITVM3 (local Hyper-V), Nginx, PM2, Cloudflare Tunnel, Docker |
Project Structure
frontend/src/
├── pages/
│ ├── Play.jsx # Game player + DevToolbar (P key)
│ ├── CreateWizard.jsx # 3-step wizard + SSE progress
│ ├── Dashboard.jsx # "My Games" - collections + created games only
│ ├── Profile.jsx # Stats, streaks, XP activity, achievements, history
│ ├── Arcade.jsx # Game browser with live previews
│ └── ...
├── components/
│ ├── Header.jsx # Sticky nav (static on /play/*), mobile menu
│ ├── DevToolbar.jsx # Tweak, refine, code editor (P key)
│ ├── TweakPanel.jsx # 3-step: preview → confirm → success
│ ├── GameCard.jsx # Live preview with audio mock
│ ├── OnboardingTutorial.jsx # First-time wizard (DB-persisted)
│ └── ...
├── context/AuthContext.jsx
└── api.js # 180s timeout, SSE streaming, push
backend/src/
├── routes/
│ ├── creation.js # Background generation + SSE streaming
│ ├── localai.js # Haiku tweaks: preview, classify, apply, review
│ ├── push.js # VAPID key, subscribe/unsubscribe
│ └── ...
└── utils/
├── claude.js # Sonnet: generateGameStream, regenerateGameStream
├── haiku.js # preprocessTweak, explainError, summarize*
├── localAI.js # refinePrompt, classifyTweak, applyTweak
└── pushNotify.js # Web push send/subscribe
AI Architecture
Haiku-first: All lightweight AI uses Claude Haiku directly.
| Task | Model | Location |
|---|---|---|
| Game generation/refinement | Sonnet (streaming) | claude.js |
| Tweak preview/apply | Haiku | localAI.js |
| Prompt refinement | Haiku | localAI.js |
| Code review | Haiku | localai.js route |
| Error explanation | Haiku | haiku.js |
| Summaries | Haiku | haiku.js |
Background Generation + SSE
POST /api/creation/:id/generatereturns immediately- Backend runs async, streams progress to
activeGenerationsMap (5min TTL) - Client connects
GET /api/creation/:id/stream?token=JWT - SSE replays buffered events, streams new ones
- On complete: DB save, in-app notification, email, push
SSE auth: JWT via ?token= query param.
Nginx: Requires proxy_buffering off for /api.
Key Pages
Dashboard → "My Games"
- Collections grid (4 max shown)
- Created games list with status badges
- Create button — no stats/XP (moved to Profile)
Profile (own)
- Avatar, XP bar, level icon
- Quick stats: Games Created, Played, Time, Total XP
- Streaks: Login (🔥), Creation (⚡) with milestones
- XP activity: Recent transactions
- Achievements grid (earned/locked toggle)
- Tabs: Created Games, Favorites, Play History
Play + DevToolbar
- Press P to open (creators only, draft/testing)
- Tweak tab: 3-step flow with Haiku preview → confirm → success
- Edit tab: Code editor with Haiku review before save
- Refine tab: Full Sonnet regeneration with SSE progress
- Prompt tab: View generation prompt
- Test 30s minimum before publishing
Header
- Sticky on all pages except
/play/*(static there) - Mobile hamburger menu
- Token display, notification bell, avatar+level badge
Onboarding
- 4-step welcome wizard for new users
- Persisted in DB (
onboarding_completecolumn) - Survives cache clear/reload
API Endpoints
# Public
GET /api/arcade/games|:id
GET /api/leaderboard/players|creators|games
GET /api/push/vapid-key
# Auth
POST /api/auth/register|login|guest-login
POST /api/auth/forgot-password|reset-password
# Authenticated
POST /api/play/start|finish|rate|favorite
POST /api/creation/start|:id/generate|refine|publish
GET /api/creation/:id/stream # SSE (?token=JWT)
POST /api/localai/refine-prompt|classify|tweak/:gameId
POST /api/localai/tweak/:gameId/preview # Haiku preview
POST /api/localai/review-code/:gameId # Haiku code review
POST /api/localai/save-code/:gameId # Save manual edits
POST /api/push/subscribe|unsubscribe
GET /api/users/me
Database Tables
Core: users, games, plays, ratings, high_scores Social: favorites, follows, notifications, collections Progress: achievements, user_achievements, xp_transactions Education: classrooms, classroom_students, assignments Push: push_subscriptions Reports: game_reports, bug_reports
Common Tasks
# Add page
1. frontend/src/pages/NewPage.jsx
2. Add route in App.jsx
3. Add to Header.jsx if needed
4. ./deploy.sh
# Add API endpoint
1. backend/src/routes/file.js
2. frontend/src/api.js method
3. Mount in app.js if new file
4. pm2 restart gamercomp-api
# Database change
sudo -u postgres psql -d game_arcade
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO gamearc;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO gamearc;
Troubleshooting
| Issue | Fix |
|---|---|
| UI not updating | /clear-cache.html or Ctrl+Shift+R |
| PM2 errors | pm2 flush && pm2 restart gamercomp-api |
| SSE not working | Check nginx proxy_buffering off |
| Generation timeout | Check 180s timeouts (nginx, api.js) |
| Iframe blank | Needs sandbox="allow-scripts" |
| Push not delivered | Check VAPID keys, subscriptions pruned on 410 |
| Mobile keyboard hiding | Use font-size: 16px on inputs |
Game Deployment Strategy
New games should be built using the GamerComp engine (AI-generated HTML5 canvas games via the Create Wizard) whenever possible. For complex games that exceed what the engine can produce (e.g. Allegiance, MorseQuest), deploy them as Docker containers on the same KITVM3 server and proxy them through Nginx.
# Docker game deployment pattern
docker build -t gamename ./games/gamename/
docker run -d --name gamename -p 300X:80 --restart unless-stopped gamename
# Then add nginx location block to proxy /games/gamename/ to localhost:300X
Server Info
- Host: KITVM3 Hyper-V VM on R810 (16 CPUs, 8GB RAM)
- SSH:
ssh -i ~/.ssh/claude_gamercomp -p 2135 ubuntu@keylinkit.vpnplus.to - App dir:
/home/ubuntu/game-arcade/ - Routing: Cloudflare Tunnel (gamercomp-local) → Nginx → PM2/Docker
- DO server is decommissioned — all traffic routes through the tunnel
Architecture Notes
Iframe Communication: Games export pauseGame(), resumeGame(), pauseMusic(), resumeMusic(), gameScore, setMusicEnabled(), setSfxEnabled() on window.
Content Safety: Multi-layer filtering (profanity, PII, violence). Gaming allowlist. Kid-friendly errors.
Audio Mocking: GameCard.jsx mocks AudioContext and Audio completely to prevent sounds in previews.
Mobile Touch: Play.jsx uses onTouchEnd with e.preventDefault() for buttons. Textareas need font-size: 16px to prevent iOS zoom and keyboard issues.