multiplayer-prompting
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data โ all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v34View latest version
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Val Town โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Frontend (React) โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโ โ โ
โ โ โ CardDeckโ โPromptStackโ โVibeOutput โ โ โ
โ โ โโโโโโฌโโโโโ โโโโโโโฌโโโโโ โโโโโโโโฌโโโโโโ โ โ
โ โ โ โ โ โ โ
โ โ โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ โ
โ โ โโโโโโโโผโโโโโโโ โ โ
โ โ โ App.tsx โ โ โ
โ โ โโโโโโโโฌโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ SSE โ HTTP โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Backend (Hono) โ โ
โ โ โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ โ โ
โ โ โSSE Hub โ โ API Routesโ โ Vibe Engine โ โ โ
โ โ โbroadcastโ โ /api/* โ โ (OpenAI) โ โ โ
โ โ โโโโโโฌโโโโโ โโโโโโโฌโโโโโโ โโโโโโโโโฌโโโโโโโโ โ โ
โ โ โ โ โ โ โ
โ โ โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ โ
โ โ โโโโโโโโผโโโโโโโโโ โ โ
โ โ โ Database โ โ โ
โ โ โ (SQLite) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Browser โ POST /api/session/:id/join
โ
Create/Find Session in SQLite
โ
Add Player with Turn Order
โ
Broadcast "player-joined" via SSE
โ
Return Session + Player Data
Browser โ POST /api/session/:id/play
โ
Insert Card into prompt_stack Table
โ
Update current_turn in Session
โ
Broadcast "card-played" via SSE
โ
All Clients Update UI
Browser โ POST /api/session/:id/generate
โ
Fetch All Cards from prompt_stack
โ
Vibe Engine Synthesizes Prompt
โ
Call OpenAI API
โ
Save Result to vibe_results Table
โ
Broadcast "vibe-update" via SSE
โ
All Clients Show Response
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ Client 1 โ โ Client 2 โ โ Client 3 โ
โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ
โ โ โ
โ EventSource โ EventSource โ EventSource
โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโค
โ โ โ
โโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโผโโโโโโโโโ
โ SSE Hub โ
โ (Maintains โ
โ connections) โ
โโโโโโโโโฌโโโโโโโโโ
โ
broadcast(message)
โ
โโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ card-playedโ โ turn-changedโ
โ vibe-update โ โplayer-joinedโ
โ player-left โ โ etc. โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
sessions_v1
โโโ id (PK)
โโโ created_at
โโโ current_turn
โโโ max_players
โโโ status
players_v1
โโโ id (PK)
โโโ session_id (FK)
โโโ name
โโโ avatar
โโโ is_active
โโโ turn_order
โโโ last_seen
prompt_stack_v1
โโโ id (PK)
โโโ session_id (FK)
โโโ player_name
โโโ card_type
โโโ content
โโโ image_url
โโโ timestamp
vibe_results_v1
โโโ id (PK)
โโโ session_id (FK)
โโโ prompt
โโโ response
โโโ token_count
โโโ timestamp
Session: current_turn = 0
Players: [Alice, Bob, Charlie] (turn_order: 0, 1, 2)
Turn 0: Alice plays โ current_turn = 1
Turn 1: Bob plays โ current_turn = 2
Turn 2: Charlie plays โ current_turn = 0 (wraps around)
Turn 0: Alice again โ ...
Stack: [
{type: "role", content: "Act as Rust expert"},
{type: "tone", content: "ELI5"},
{type: "token-limit", content: "50 tokens"}
]
Vibe Engine:
1. Extract role โ "Act as Rust expert"
2. Extract tone โ "ELI5"
3. Extract token limit โ 50
4. Build prompt:
"""
Act as Rust expert
ELI5
IMPORTANT: Keep your response under 50 tokens.
"""
5. Call OpenAI with prompt + user query
6. Return response
App
โโโ PlayerList
โ โโโ Player Cards (active + spectators)
โโโ PromptStack
โ โโโ Played Card History
โโโ VibeOutput
โ โโโ Query Input
โ โโโ Generate Button
โ โโโ AI Response Display
โโโ CardDeck
โโโ Card Grid (5 cards)
โโโ Custom Card Modal
App Component State:
โโโ sessionId: string
โโโ playerName: string
โโโ session: Session
โโโ players: Player[]
โโโ stack: PlayedCard[]
โโโ hand: Card[]
โโโ currentPlayer: Player
โโโ isMyTurn: boolean
โโโ latestResult: PromptResult
โโโ generating: boolean
Effects:
โโโ SSE Connection (updates on message)
โโโ fetchSessionState (on join/updates)
- No Authentication: Sessions are public by ID
- Input Validation: Sanitize all user inputs
- Rate Limiting: Consider adding to /generate endpoint
- XSS Protection: React handles by default
- CSRF: Not applicable (no cookies/sessions)
- Cold Start: ~2-3 seconds for database init
- SSE Overhead: ~1KB per client per 30s (heartbeat)
- Database: SQLite in-memory for active sessions
- OpenAI: 2-5 seconds per generation (gpt-4o-mini)
- Concurrent Players: Tested with 10 simultaneous users
- Session Cleanup: Cron job to archive old sessions
- Connection Pooling: Val Town handles automatically
- CDN for Static Assets: Val Town edge caching
- Database Sharding: Separate tables per date range
- Rate Limiting: Add Redis-like counter for /generate
Legend:
- โ : Data flow
- โ : Sequential step
- โโโ : Component/structure hierarchy
- (FK) : Foreign key
- (PK) : Primary key