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: v16View latest version
A Multiplayer Prompting Sandbox for Val Town
Vibe-Draft is a collaborative, real-time "Cards Against Humanity" style experience for vibe-coding. Up to 10 developers join a session and take turns playing cards that influence an AI prompt. Each card modifies the tone, role, token limits, or adds custom instructions. The result is a living, evolving prompt that generates creative AI responses based on the collective vibe.
- Create/Join a Session: Players enter a session ID and their name
- Take Turns: Each player gets 5 cards in their hand
- Play Cards: On your turn, play a card to influence the vibe:
- Role Cards: Change the AI persona (Rust Wizard, UX Visionary, Code Pirate, etc.)
- Tone Cards: Adjust the communication style (ELI5, Academic, Meme Lord, etc.)
- Token Limit Cards: Control response length (Brief, Epic, Tweet-sized)
- Custom Cards: Add your own freeform instructions
- Image Cards: Upload visual context
- Remove Cards: Undo moves or clear certain card types
- Generate: Hit "Generate Vibe" to see what the AI creates with the current stack
- Repeat: The next player takes their turn!
index.ts: Main Hono app with API routes and SSE hubsse-hub.ts: Server-Sent Events for real-time multiplayer updatesvibe-engine.ts: Synthesizes prompt stack into OpenAI callsdatabase/:schema.ts: SQLite table definitionsqueries.ts: Database operations for sessions, players, and cards
index.html: Main HTML templateindex.tsx: React app entry pointstyle.css: Custom styles and animationscomponents/:App.tsx: Main application componentCardDeck.tsx: Player's hand of cardsPromptStack.tsx: Visual stack of played cardsVibeOutput.tsx: AI-generated responsesPlayerList.tsx: Active players and spectators
types.ts: TypeScript interfaces shared between frontend/backendcards.ts: Predefined card deck with 20+ cards
- SSE-Powered: No WebSockets needed! Uses Server-Sent Events for instant updates
- Up to 10 Active Players: More can spectate
- Turn-Based: Clear turn indicators and game flow
- Live Updates: See cards played in real-time
- 20+ Predefined Cards: Roles, tones, token limits, and style modifiers
- Wild Cards: Create custom instructions on the fly
- Image Context: Upload images for visual prompting (coming soon)
- Remove/Undo: Fix mistakes or clear card types
- OpenAI GPT-4o-mini: Fast, cost-effective generation
- Dynamic Prompts: Each card stack creates a unique system prompt
- Token Control: Cards can set response length limits
- Visual Context: Support for image-based prompting
- Glassmorphism Design: Modern, translucent interface
- Smooth Animations: Card plays, stack updates, turn changes
- Gradient Background: Purple-pink aesthetic
- Responsive: Works on desktop and tablet
id: Unique session identifiercreated_at: Timestampcurrent_turn: Index of current playermax_players: Max active players (default 10)status: waiting | active | completed
session_id: Foreign key to sessionsname: Player display nameavatar: Emoji avataris_active: Active player vs spectatorturn_order: Turn sequencelast_seen: Heartbeat timestamp
session_id: Foreign key to sessionsplayer_name: Who played the cardcard_type: role | tone | token-limit | custom | image | removecontent: Card content/instructionimage_url: Optional image URL (blob storage)timestamp: When card was played
session_id: Foreign key to sessionsprompt: Generated system promptresponse: AI responsetoken_count: Tokens usedtimestamp: When generated
1. Player joins session → Assigned turn order → Draws 5 cards
2. Wait for turn → Turn indicator appears
3. Play a card → Card added to stack → Turn advances
4. Any player can hit "Generate" → OpenAI synthesizes vibe
5. AI response displayed → Continue playing cards
6. Repeat until satisfied or chaos ensues! 🎉
- SQLite: Session state, players, card history
- Blob Storage: Image uploads (future feature)
- No Deno KV: Not used per Val Town best practices
- React 18.2.0: Pinned consistently across all files
- Hono: Web framework for API routes
- OpenAI: Official SDK from Val Town standard library
- Utilities:
readFile,serveFile,parseProjectfrom std/utils
// Client connects to /api/sse/:sessionId
const eventSource = new EventSource(`/api/sse/${sessionId}`);
// Server broadcasts to all connections
broadcast(sessionId, {
type: "card-played",
data: { playerName, stack, vibePreview },
timestamp: Date.now()
});
Transform the AI's persona:
- Rust Wizard 🦀: Senior Rust engineer
- UX Visionary 🎨: Award-winning designer
- Code Pirate 🏴☠️: Salty sea programmer
- Code Poet 📜: Poetic technical writer
Adjust communication style:
- ELI5 👶: Kid-friendly explanations
- Academic 🎓: Formal scholarly language
- Meme Lord 💀: Internet culture speak
- Brutally Honest 🔨: No-nonsense directness
Control response length:
- Keep It Brief ⚡: Max 50 tokens
- Epic Response 📚: Up to 500 tokens
- Tweet It 🐦: 280 characters max
- Geocities Revival 🌐: 1990s nostalgia
- Cyberpunk Aesthetic 🌃: Dark neon vibes
- Extreme Minimal ⬜: Dieter Rams style
- Wild Card 🃏: Custom freeform instruction
- Show & Tell 📸: Upload image context
- Undo Last ⏪: Remove previous card
- Clear Roles 🧹: Remove all role cards
- Start with a Role: Set the AI's persona first
- Add Tone: Fine-tune the communication style
- Set Token Limits: Control verbosity
- Add Custom Vibes: Get creative with wildcards
- Generate Often: See how each card changes the output
- Layer Roles: Mix technical + creative personas
- Contrast Tones: Academic + Meme Lord = chaos
- Token Control: Brief responses for rapid iteration
- Remove Wisely: Clear roles to reset persona
- Collaborate: Build on others' cards
- Contradict: Play opposing vibes for fun
- Experiment: Try wild combinations
- Spectate: Learn by watching (spectators don't play)
├── backend/
│ ├── index.ts # Main Hono app
│ ├── sse-hub.ts # Real-time updates
│ ├── vibe-engine.ts # OpenAI integration
│ └── database/
│ ├── schema.ts # SQLite tables
│ └── queries.ts # DB operations
├── frontend/
│ ├── index.html # Main HTML
│ ├── index.tsx # React entry
│ ├── style.css # Custom styles
│ └── components/
│ ├── App.tsx
│ ├── CardDeck.tsx
│ ├── PromptStack.tsx
│ ├── VibeOutput.tsx
│ └── PlayerList.tsx
├── shared/
│ ├── types.ts # TypeScript types
│ └── cards.ts # Card definitions
└── README.md
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/session/:id/join | Join/create session |
| GET | /api/session/:id | Get session state |
| POST | /api/session/:id/play | Play a card |
| POST | /api/session/:id/generate | Generate vibe with OpenAI |
| GET | /api/cards/draw/:count | Draw random cards |
| GET | /api/cards | Get all cards |
| GET | /api/sse/:id | SSE connection |
# Automatically provided by Val Town: # - Deno.env.get('OPENAI_API_KEY') - for OpenAI calls
- Image Upload: Full support for visual context cards
- Vote System: Players vote on best vibe
- Card Combos: Special effects for card combinations
- Saved Sessions: Resume previous games
- Custom Decks: Create your own card sets
- Streaming Responses: Real-time token-by-token output
- Leaderboards: Track best vibes and players
- Mobile UI: Touch-optimized card interface
This is a Val Town project! To extend or remix:
- Fork the val on Val Town
- Modify files in your fork
- Test locally or deploy immediately
- Share your version!
MIT License - Feel free to remix and build upon this!
Built with:
- Val Town: Serverless platform with SQLite + OpenAI
- Hono: Lightning-fast web framework
- React 18: UI library
- Tailwind CSS: Utility-first styling (via Twind)
- SSE: Real-time updates without WebSockets
Made with 💜 for the Val Town community
"Where vibes become code, and chaos becomes creativity" 🎴✨