• Blog
  • Docs
  • Pricing
  • Weโ€™re hiring!
Log inSign up
jjg

jjg

multiplayer-prompting

Public
Like
multiplayer-prompting
Home
Code
14
.vscode
.vt
backend
4
docs
frontend
5
shared
.vtignore
AGENTS.md
ARCHITECTURE.md
DEPLOYMENT.md
QUICKSTART.md
README.md
deno.json
vibe_engine.ts
Environment variables
Branches
1
Pull requests
Remixes
History
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.
Sign up now
Code
/
ARCHITECTURE.md
Code
/
ARCHITECTURE.md
Search
โ€ฆ
Viewing readonly version of main branch: v54
View latest version
ARCHITECTURE.md

๐ŸŽด Vibe-Draft Architecture

System Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        Val Town                              โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚               Frontend (React)                      โ”‚    โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚    โ”‚
โ”‚  โ”‚  โ”‚ CardDeckโ”‚  โ”‚PromptStackโ”‚ โ”‚VibeOutput  โ”‚       โ”‚    โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚    โ”‚
โ”‚  โ”‚       โ”‚             โ”‚               โ”‚              โ”‚    โ”‚
โ”‚  โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚    โ”‚
โ”‚  โ”‚                     โ”‚                               โ”‚    โ”‚
โ”‚  โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”                       โ”‚    โ”‚
โ”‚  โ”‚              โ”‚   App.tsx   โ”‚                       โ”‚    โ”‚
โ”‚  โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                       โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                        โ”‚                                    โ”‚
โ”‚                   SSE  โ”‚  HTTP                             โ”‚
โ”‚                        โ”‚                                    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚            Backend (Hono)                          โ”‚    โ”‚
โ”‚  โ”‚                                                     โ”‚    โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚    โ”‚
โ”‚  โ”‚  โ”‚SSE Hub  โ”‚  โ”‚ API Routesโ”‚  โ”‚ Vibe Engine   โ”‚   โ”‚    โ”‚
โ”‚  โ”‚  โ”‚broadcastโ”‚  โ”‚  /api/*   โ”‚  โ”‚ (OpenAI)      โ”‚   โ”‚    โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚    โ”‚
โ”‚  โ”‚       โ”‚             โ”‚                 โ”‚            โ”‚    โ”‚
โ”‚  โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚    โ”‚
โ”‚  โ”‚                     โ”‚                               โ”‚    โ”‚
โ”‚  โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                     โ”‚    โ”‚
โ”‚  โ”‚              โ”‚  Database      โ”‚                     โ”‚    โ”‚
โ”‚  โ”‚              โ”‚  (SQLite)      โ”‚                     โ”‚    โ”‚
โ”‚  โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                     โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Data Flow

1. Join Session

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

2. Play Card

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

3. Generate Vibe

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

SSE Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 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.     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Database Schema

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

Turn Flow

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 โ†’ ...

Card Stack Processing

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

Component Hierarchy

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

State Management

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)

Security Notes

  • 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)

Performance Considerations

  • 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

Scaling Strategies

  1. Session Cleanup: Cron job to archive old sessions
  2. Connection Pooling: Val Town handles automatically
  3. CDN for Static Assets: Val Town edge caching
  4. Database Sharding: Separate tables per date range
  5. Rate Limiting: Add Redis-like counter for /generate

Legend:

  • โ†’ : Data flow
  • โ†“ : Sequential step
  • โ”œโ”€โ”€ : Component/structure hierarchy
  • (FK) : Foreign key
  • (PK) : Primary key
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
Weโ€™re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
ยฉ 2026 Val Town, Inc.