--- name: demo-builder description: Automatically generate playable game demos from concept documents. Parses game designs, creates Three.js prototypes with scoring, characters, textures, and music. Transforms ideas into interactive experiences. --- # Demo Builder Skill ## Purpose This skill automatically generates playable game prototypes from game concept documents. It: - **Parses concept documents** to extract game mechanics, theme, genre - **Generates Three.js game code** using the threejs-game skill - **Creates first playable level** with scoring, objectives, characters - **Generates assets** (textures, colors, basic models) - **Integrates music** (Suno AI generation or 8-bit MIDI) - **Produces web-ready demo** that runs in browser **Output**: Fully functional game demo with HTML/JS/CSS that can be played immediately. ## When to Use This Skill Use this skill when you have: - ✅ Game concept document (from brainstorming/design phases) - ✅ Need to validate gameplay quickly with playable prototype - ✅ Want to pitch game with interactive demo vs. static mockups - ✅ Require rapid prototyping for playtesting - ✅ Need proof-of-concept before full development investment ## Prerequisites ### Required Input **Game Concept Document** (from brainstorming or design) - Location: `/docs/*-game-concepts-*.md` or `/docs/plans/*-design.md` - Must include: Title, description, genre, core mechanics, theme - Example: `fps-game-concepts-market-driven-2025-10-26.md` ### Dependencies - **threejs-game skill** (for 3D game implementation) - Three.js library (loaded via CDN in generated HTML) - Optional: Suno API key for music generation (can use MIDI fallback) ## Core Workflow ### Phase 1: Concept Parsing **1. Load Game Concept** ```javascript GameConcept = { title: string, description: string, genre: string[], // ["FPS", "Extraction", "Co-op"] theme: string, // "cyberpunk", "military", "horror", etc. core_mechanics: string[], target_persona: string, price_point: number | "F2P" } ``` **2. Extract Demo Requirements** ```javascript DemoRequirements = { game_type: "FPS" | "third-person" | "top-down" | "side-scroller", camera_type: "first-person" | "third-person" | "fixed" | "isometric", movement_type: "WASD" | "mouse" | "touch" | "hybrid", primary_mechanic: "shooting" | "extraction" | "survival" | "puzzle", color_palette: extractColorPalette(theme), character_archetypes: extractCharacters(description), objectives: extractObjectives(description), music_style: extractMusicStyle(genre, theme) } ``` ### Phase 2: Demo Architecture Design **3. Generate Demo Specifications** Based on genre/mechanics, create demo spec: **FPS Demo Template:** ```javascript { level: { type: "arena" | "corridor" | "open-world-section", size: {x: 100, y: 50, z: 100}, geometry: "modular" // Can be expanded }, player: { type: "fps-controller", spawn: {x: 0, y: 2, z: 0}, health: 100, weapons: ["basic_rifle"], movement_speed: 5, look_sensitivity: 0.002 }, enemies: [ {type: "basic_enemy", count: 5, spawn_pattern: "random"}, {type: "patrol_enemy", count: 3, patrol_routes: [[...]]} ], objectives: [ {type: "eliminate_targets", target_count: 5, points: 100}, {type: "survive_time", duration: 60, points: 50}, {type: "collect_items", item_count: 3, points: 150} ], scoring: { enemy_kill: 20, item_collect: 50, time_bonus: 1 // per second survived }, ui: { hud: ["health", "ammo", "score", "timer"], crosshair: true, minimap: false } } ``` **Extraction Shooter Demo Template:** ```javascript { level: { type: "extraction-zone", zones: ["hot_zone", "neutral", "extract_point"], size: {x: 80, y: 30, z: 80} }, player: { type: "tactical-controller", inventory_slots: 8, health: 100, stamina: 100 }, loot: [ {type: "resource", count: 10, value: 10}, {type: "rare_item", count: 3, value: 50} ], enemies: { type: "AI_guards", difficulty: "medium", count: 4 }, objectives: [ {type: "extract_with_loot", min_value: 100, points: 200}, {type: "extract_alive", points: 100} ], extraction_point: {x: 70, y: 1, z: 70}, time_limit: 180 // 3 minutes } ``` ### Phase 3: Asset Generation **4. Generate Color Palettes** ```javascript function generateColorPalette(theme) { const palettes = { "cyberpunk": { primary: 0x00ffff, // Cyan secondary: 0xff00ff, // Magenta accent: 0xffff00, // Yellow environment: 0x1a1a2e, // Dark blue-gray enemy: 0xff0080 // Pink }, "military": { primary: 0x4a6741, // Olive green secondary: 0x8b7355, // Tan accent: 0xff6b35, // Orange environment: 0x5a6650, // Gray-green enemy: 0xb71c1c // Red }, "horror": { primary: 0x1b1b1b, // Almost black secondary: 0x8b0000, // Dark red accent: 0xffffff, // White environment: 0x2d2d2d, // Dark gray enemy: 0x4a0e0e // Blood red }, "space/sci-fi": { primary: 0x0a2e4a, // Deep blue secondary: 0x2a9d8f, // Teal accent: 0xe76f51, // Orange-red environment: 0x000814, // Space black enemy: 0xf72585 // Bright pink } }; return palettes[theme] || palettes["military"]; } ``` **5. Generate Textures (Procedural)** ```javascript function generateTexture(type, color, size = 512) { const canvas = document.createElement('canvas'); canvas.width = size; canvas.height = size; const ctx = canvas.getContext('2d'); if (type === "floor") { // Grid pattern ctx.fillStyle = `#${color.toString(16).padStart(6, '0')}`; ctx.fillRect(0, 0, size, size); ctx.strokeStyle = '#000000'; ctx.lineWidth = 2; for (let i = 0; i < size; i += size / 8) { ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, size); ctx.stroke(); ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(size, i); ctx.stroke(); } } else if (type === "wall") { // Brick/panel pattern ctx.fillStyle = `#${color.toString(16).padStart(6, '0')}`; ctx.fillRect(0, 0, size, size); // Add panel lines const lighterColor = Math.min(color + 0x202020, 0xffffff); ctx.strokeStyle = `#${lighterColor.toString(16).padStart(6, '0')}`; ctx.lineWidth = 3; for (let i = 0; i < size; i += size / 4) { ctx.strokeRect(i, 0, size / 4, size); } } return new THREE.CanvasTexture(canvas); } ``` **6. Generate Characters (Geometric)** ```javascript function generateCharacter(type, color) { const group = new THREE.Group(); if (type === "player") { // Simple capsule body const body = new THREE.Mesh( new THREE.CapsuleGeometry(0.5, 1.5, 4, 8), new THREE.MeshPhongMaterial({ color: color }) ); body.position.y = 1; group.add(body); // Weapon (for FPS) const weapon = new THREE.Mesh( new THREE.BoxGeometry(0.1, 0.1, 0.8), new THREE.MeshPhongMaterial({ color: 0x333333 }) ); weapon.position.set(0.3, 0.8, -0.5); group.add(weapon); } else if (type === "enemy") { // Hostile NPC const body = new THREE.Mesh( new THREE.BoxGeometry(0.8, 1.6, 0.6), new THREE.MeshPhongMaterial({ color: color }) ); body.position.y = 0.8; group.add(body); // Enemy marker (head) const head = new THREE.Mesh( new THREE.SphereGeometry(0.3, 8, 8), new THREE.MeshPhongMaterial({ color: 0xff0000, emissive: 0x330000 }) ); head.position.y = 2; group.add(head); } return group; } ``` ### Phase 4: Music Generation **7. Generate Music (Suno AI or MIDI)** ```javascript async function generateMusic(style, concept_name) { // Option 1: Suno API (if API key available) if (SUNO_API_KEY) { const prompt = generateMusicPrompt(style, concept_name); const musicUrl = await callSunoAPI(prompt); return musicUrl; } // Option 2: 8-bit MIDI fallback return generate8BitMIDI(style); } function generateMusicPrompt(style, concept_name) { const prompts = { "fps": `Epic action game music, intense electronic beats, military drums, adrenaline pumping, 140 BPM, game soundtrack, ${concept_name} theme`, "horror": `Dark atmospheric horror game music, eerie synths, unsettling ambience, tension building, 80 BPM, survival horror soundtrack`, "cyberpunk": `Synthwave cyberpunk game music, neon aesthetic, retro futuristic, energetic, 130 BPM, electronic game soundtrack`, "tactical": `Tactical stealth game music, suspenseful, orchestral strings, slow build tension, 90 BPM, espionage theme`, "roguelike": `Retro roguelike dungeon music, chiptune style, 8-bit adventure, upbeat tempo, 120 BPM, classic game feel` }; return prompts[style] || prompts["fps"]; } function generate8BitMIDI(style) { // Generate simple 8-bit style music pattern // Using Web Audio API for procedural chiptune const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); const patterns = { fps: { tempo: 140, notes: ["C4", "E4", "G4", "C5", "G4", "E4"], // Energetic pattern rhythm: [0.25, 0.25, 0.5, 0.25, 0.25, 0.5] }, ambient: { tempo: 80, notes: ["C3", "E3", "G3", "B3", "G3", "E3"], // Slower, eerie rhythm: [1, 1, 0.5, 0.5, 1, 1] } }; return createChiptuneLoop(audioCtx, patterns[style] || patterns.fps); } ``` ### Phase 5: Game Code Generation **8. Generate Complete Game Files** Using threejs-game skill, generate: **index.html:** ```html
[Objective description]
Controls:
WASD - Move | Mouse - Look | Left Click - Shoot
ESC - Pause