User prompt
Please fix the bug: 'TypeError: Sprite is not a constructor' in or related to this line: 'var separator = new Sprite();' Line Number: 299
User prompt
Please fix the bug: 'TypeError: Sprite is not a constructor' in or related to this line: 'var screen = new Sprite();' Line Number: 242
User prompt
Please fix the bug: 'TypeError: Sprite is not a constructor' in or related to this line: 'var monitor = new Sprite();' Line Number: 235
User prompt
Please fix the bug: 'Sprite is not a constructor' in or related to this line: 'var overlay = new Sprite();' Line Number: 964
User prompt
Please fix the bug: 'Sprite is not a constructor' in or related to this line: 'var overlay = new Sprite();' Line Number: 964
User prompt
Please fix the bug: 'Sprite is not a constructor' in or related to this line: 'var bg = new Sprite();' Line Number: 482
User prompt
Please fix the bug: 'Sprite is not a constructor' in or related to this line: 'var bg = new Sprite();' Line Number: 482
User prompt
Please fix the bug: 'Sprite is not a constructor' in or related to this line: 'var background = new Sprite();' Line Number: 729
User prompt
Please fix the bug: 'Sprite is not a constructor' in or related to this line: 'var background = new Sprite();' Line Number: 732
Code edit (8 edits merged)
Please save this source code
User prompt
lose the vibe core pulsing when a card is played
Code edit (1 edits merged)
Please save this source code
User prompt
Add special cards to the card particles.
Code edit (3 edits merged)
Please save this source code
User prompt
Set the vibe core pulse to a true 4/4 time using the scale variables as they are.
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
Slow the pulse down some more. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Slow the pulse down by half and make the scale change more pronounced.
User prompt
Give the vibe core a 4/4 time constant scale oulse. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update with: var VibeParticle = Container.expand(function(type, index) { var self = Container.call(this); var typeConfig = PARTICLE_TYPES[type]; var assetIndex = Math.floor(Math.random() * 3); var sprite = self.attachAsset(typeConfig.assets[assetIndex], { anchorX: 0.5, anchorY: 0.5 }); // Movement properties for electron-like orbits self.angle = (Math.PI * 2 * index) / typeConfig.count; self.speed = typeConfig.baseSpeed; self.radius = typeConfig.orbitRadius; // Random orbital plane (like electron shells) self.orbitTilt = (Math.random() * Math.PI); // Random tilt self.orbitRotation = Math.random() * Math.PI * 2; // Random rotation self.update = function() { var chaosLevel = Math.min(gameState.contextCollapse / MAX_CONTEXT_COLLAPSE, 1); // Faster angle updates for electron-like movement self.angle += 0.03 * self.speed; // Calculate position on orbital plane var orbitX = Math.cos(self.angle) * self.radius; var orbitY = Math.sin(self.angle) * self.radius; // Apply orbital plane rotation for electron shell effect var x = orbitX * Math.cos(self.orbitTilt) - orbitY * Math.sin(self.orbitTilt); var y = orbitX * Math.sin(self.orbitRotation) + orbitY * Math.cos(self.orbitRotation); // Depth calculation for scaling/alpha var depth = orbitX * Math.sin(self.orbitTilt) + orbitY * Math.cos(self.orbitTilt); var scaleFactor = (depth + self.radius) / (self.radius * 2); // Add slight chaos when context collapse is high if (chaosLevel > 0) { x += (Math.random() - 0.5) * chaosLevel * 15; y += (Math.random() - 0.5) * chaosLevel * 15; } self.x = x; self.y = y; self.scale.set(0.7 + scaleFactor * 0.3); // Less scaling variation self.alpha = 0.6 + scaleFactor * 0.4; // Keep particles more visible // Update pulse effect if active if (self.pulseScale > 1) { self.pulseScale = Math.max(1, self.pulseScale - 0.05); self.scale.set(self.pulseScale * scaleFactor); } }; return self; });
User prompt
Update as needed with: var VibeParticle = Container.expand(function(type, index) { var self = Container.call(this); var typeConfig = PARTICLE_TYPES[type]; // Randomly select particle asset var assetIndex = Math.floor(Math.random() * 3); var sprite = self.attachAsset(typeConfig.assets[assetIndex], { anchorX: 0.5, anchorY: 0.5 }); // Movement properties self.angle = (Math.PI * 2 * index) / typeConfig.count; self.speed = typeConfig.baseSpeed; self.radius = typeConfig.orbitRadius * (0.8 + Math.random() * 0.4); // Random orbital plane for each particle self.orbitTilt = Math.random() * Math.PI * 2; // Random tilt angle self.orbitRotation = Math.random() * Math.PI * 2; // Random rotation of orbit self.update = function() { var chaosLevel = Math.min(gameState.contextCollapse / MAX_CONTEXT_COLLAPSE, 1); // Update angle self.angle += 0.005 * self.speed; // Slowed down movement // Calculate 3D position on tilted orbital plane var orbitX = Math.cos(self.angle) * self.radius; var orbitY = Math.sin(self.angle) * self.radius; // Apply orbital plane rotation var x = orbitX * Math.cos(self.orbitTilt) - orbitY * Math.sin(self.orbitTilt); var y = orbitX * Math.sin(self.orbitRotation) + orbitY * Math.cos(self.orbitRotation); // Scale and alpha based on position relative to "front" var depth = orbitX * Math.sin(self.orbitTilt) + orbitY * Math.cos(self.orbitTilt); var scaleFactor = (depth + self.radius) / (self.radius * 2); var alphaFactor = scaleFactor; // Add subtle chaos if (chaosLevel > 0) { x += (Math.random() - 0.5) * chaosLevel * 10; y += (Math.random() - 0.5) * chaosLevel * 10; } // Apply position and effects self.x = x; self.y = y; self.scale.set(0.6 + scaleFactor * 0.4); // Less extreme scaling self.alpha = 0.4 + alphaFactor * 0.6; // Less extreme alpha // Update pulse effect if active if (self.pulseScale > 1) { self.pulseScale = Math.max(1, self.pulseScale - 0.05); self.scale.set(self.pulseScale * scaleFactor); } }; return self; });
Code edit (2 edits merged)
Please save this source code
User prompt
Update with: var VibeParticle = Container.expand(function(type, index) { var self = Container.call(this); var typeConfig = PARTICLE_TYPES[type]; // Randomly select particle asset var assetIndex = Math.floor(Math.random() * 3); var sprite = self.attachAsset(typeConfig.assets[assetIndex], { anchorX: 0.5, anchorY: 0.5 }); // Movement properties self.angle = (Math.PI * 2 * index) / typeConfig.count; self.speed = typeConfig.baseSpeed; self.radius = typeConfig.orbitRadius * (0.9 + Math.random() * 0.2); // Add vertical angle for 3D effect self.verticalAngle = Math.random() * Math.PI * 2; self.verticalSpeed = 0.015; // Slow vertical orbit self.update = function() { var chaosLevel = Math.min(gameState.contextCollapse / MAX_CONTEXT_COLLAPSE, 1); // Update angles self.angle += 0.01 * self.speed; self.verticalAngle += self.verticalSpeed; // Calculate position with vertical offset for 3D effect var x = Math.cos(self.angle) * self.radius; var verticalOffset = Math.sin(self.verticalAngle) * self.radius * 0.5; var y = Math.sin(self.angle) * self.radius + verticalOffset; // Scale and alpha based on vertical position (behind/in front of core) var scaleFactor = (Math.sin(self.verticalAngle) + 2) / 3; // Range: 0.33 to 1 var alphaFactor = (Math.sin(self.verticalAngle) + 2) / 3; // Range: 0.33 to 1 // Add subtle chaos if (chaosLevel > 0) { x += (Math.random() - 0.5) * chaosLevel * 10; y += (Math.random() - 0.5) * chaosLevel * 10; } // Apply position and effects self.x = x; self.y = y; self.scale.set(scaleFactor); self.alpha = alphaFactor; // Update pulse effect if active if (self.pulseScale > 1) { self.pulseScale = Math.max(1, self.pulseScale - 0.05); self.scale.set(self.pulseScale * scaleFactor); } }; // Keep existing pulse function return self; });
User prompt
Update only as needed with: function playCard(card) { if (currentHand.indexOf(card) === -1) { return; } // ... existing card validation code ... // Add particle group for card type if it doesn't exist var cardType = card.type.toUpperCase(); if (!gameState.particleGroups[cardType]) { var group = new ParticleGroup(cardType); gameState.particleGroups[cardType] = group; gameState.particleContainer.addChild(group); // Fade in new particles group.alpha = 0; tween(group, { alpha: 1 }, { duration: 500 }); } else { // Pulse existing particles of this type gameState.particleGroups[cardType].pulse(); } // ... rest of existing playCard code ... // After card is absorbed into core tween(card, { x: gameState.stackArea.x, y: gameState.stackArea.y, scaleX: 0.2, scaleY: 0.2, alpha: 0 }, { duration: 300, onFinish: function onFinish() { pulseVibeCore(); gameState.cardStack.push(card); checkForBugs(card.bugChance); updateStatsDisplay(); positionCardsInHand(); if (currentHand.length < HAND_SIZE) { drawHand(); } checkGameState(); } }); } ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Initialize Game ****/ // Core game setup - stripped down to essentials var game = new LK.Game({ backgroundColor: 0x000000 // Dark background for terminal aesthetic }); /**** * Game Code ****/ // Game states var STATES = { TITLE: 'title', PLAYING: 'playing', GAME_OVER: 'gameOver' }; // Game state object - much simplified var gameState = { state: STATES.TITLE, day: 1, maxDays: 10, vibePoints: 100, codeCoherence: 100, bugs: 0, cardsPlayed: 0, maxCardsPerDay: 3, projectDescription: "", conceptCards: { platform: null, visual: null, genre: null, mechanic: null, feature: null }, terminal: { log: [], statusLine: "", currentTask: "", featureTags: [] } }; // Card templates using actual prompts from your document var cardTemplates = [ // Basic prompts { type: 'basic', promptText: "Make the code run faster", vibePoints: 10, coherenceImpact: 5, bugChance: 0.2 }, { type: 'basic', promptText: "Use all the frameworks at the same time", vibePoints: 15, coherenceImpact: 15, bugChance: 0.3 }, // UI prompts { type: 'UI', promptText: "Make the graphics better", vibePoints: 20, coherenceImpact: 10, bugChance: 0.2 }, { type: 'UI', promptText: "Add buttons that read user's minds", vibePoints: 25, coherenceImpact: 20, bugChance: 0.4 }, // Database prompts { type: 'Database', promptText: "Store everything forever", vibePoints: 30, coherenceImpact: 15, bugChance: 0.3 }, { type: 'Database', promptText: "Make the database infinitely fast", vibePoints: 35, coherenceImpact: 25, bugChance: 0.5 } // Add more cards from your prompt list document ]; // Concept cards for the 5 categories var conceptCardTemplates = { platform: ["Mobile", "VR/AR", "Console", "PC", "Blockchain", "Web Browser", "Smart Watch", "Smart Fridge", "Metaverse"], visual: ["Pixel Art", "Voxel", "Realistic", "Hand-drawn", "Low-poly", "Claymation", "ASCII", "Demake", "Corporate PowerPoint"], genre: ["RPG", "Shooter", "Puzzle", "Platformer", "Roguelike", "Simulation", "Horror", "Dating Sim", "Educational", "Idle Clicker"], mechanic: ["Deckbuilding", "Physics-based", "Survival", "Tower Defense", "Match-3", "Rhythm", "Gacha", "Crafting", "Battle Royale", "Auto-battler"], feature: ["Multiplayer", "Procedural Generation", "Time Manipulation", "Player-created Content", "Perma-death", "AI Companions", "Weekly Challenges", "Social Media Integration", "Microtransactions", "Cloud Save"] }; // Response templates for different card types at different coherence levels var responseTemplates = { basic: { high: ["Implementing {feature} with standard protocols", "Adding {feature} functionality as requested", "Building core systems for {feature}"], medium: ["Attempting to create {feature} with questionable methods", "{platform} struggling with {feature} implementation", "Forcing {feature} despite {platform} limitations"], low: ["CRITICAL: {feature} IMPLEMENTATION CAUSING SYSTEM INSTABILITY", "{feature} NOW SENTIENT AND QUESTIONING PURPOSE", "{platform} REJECTING {feature} - ATTEMPTING OVERRIDE"] }, UI: { high: ["Designing {visual} interface for {platform}", "Optimizing {visual} elements for {genre} feel", "Creating intuitive controls for {mechanic}"], medium: ["Stretching {platform} capabilities for {visual} rendering", "Users reporting eye strain from {visual} on {platform}", "{visual} clashing with {genre} expectations"], low: ["VISUALS EXCEEDING REALITY CONSTRAINTS", "{visual} CAUSING UNEXPLAINED PHENOMENA ON {platform}", "USERS REPORTING BEING PULLED INTO {genre} DIMENSION"] } // Add more for other card types }; // Initialize game function initGame() { // Clear screen while (game.children.length > 0) { game.removeChild(game.children[0]); } // Reset game state gameState = { state: STATES.PLAYING, day: 1, maxDays: 10, vibePoints: 100, codeCoherence: 100, bugs: 0, cardsPlayed: 0, maxCardsPerDay: 3, projectDescription: "New Project", conceptCards: { platform: null, visual: null, genre: null, mechanic: null, feature: null }, terminal: { log: ["PROJECT INITIALIZED", "Waiting for instructions..."], statusLine: "", currentTask: "Awaiting first prompt", featureTags: [] } }; // Create main interface createInterface(); // Initialize deck and draw cards initDeck(); drawHand(); // Initialize concept card selection if it's day 1 if (gameState.day === 1) { showConceptCardSelection('platform'); } // Update display updateTerminal(); } // Create main interface function createInterface() { // Create desk/monitor background var background = new Sprite(); background.width = 2048; background.height = 2732; background.color = 0x1e2329; // Dark gray background game.addChild(background); // Create terminal display createTerminal(); // Create card area at bottom createCardArea(); // Create day indicator var dayText = new Text2("DAY " + gameState.day + "/" + gameState.maxDays, { size: 60, fill: 0x00ff00 // Terminal green }); dayText.x = 100; dayText.y = 100; game.addChild(dayText); gameState.dayText = dayText; // Create end day button var endDayButton = new Button("END DAY", 300, 80, function () { endDay(); }); endDayButton.x = 1848; endDayButton.y = 100; game.addChild(endDayButton); } // Create terminal display function createTerminal() { // Create terminal container var terminal = new Container(); terminal.x = 2048 / 2; terminal.y = 800; // Position in upper half of screen game.addChild(terminal); gameState.terminalContainer = terminal; // Create monitor frame var monitor = new Sprite(); monitor.width = 1600; monitor.height = 1000; monitor.color = 0x333333; // Dark gray monitor terminal.addChild(monitor); // Create screen inside monitor var screen = new Sprite(); screen.width = 1500; screen.height = 900; screen.color = 0x000000; // Black screen terminal.addChild(screen); // Create status line var statusLine = new Text2("PROJECT: [New Project] | VIBES: 100% | COHERENCE: 100%", { size: 30, fill: 0x00ff00 // Terminal green }); statusLine.x = -700; // Relative to terminal container statusLine.y = -400; terminal.addChild(statusLine); gameState.statusLineText = statusLine; // Create terminal log area var logText = new Text2("PROJECT INITIALIZED\nAwaiting instructions...", { size: 24, fill: 0x00ff00, align: 'left', wordWrap: true, wordWrapWidth: 1400 }); logText.x = -700; // Relative to terminal container logText.y = -350; terminal.addChild(logText); gameState.logText = logText; // Create feature tags area var tagsText = new Text2("", { size: 24, fill: 0x00ff00 }); tagsText.x = -700; tagsText.y = 350; terminal.addChild(tagsText); gameState.tagsText = tagsText; // Create blinking cursor var cursor = new Text2("_", { size: 24, fill: 0x00ff00 }); cursor.x = -700; cursor.y = 300; terminal.addChild(cursor); // Make cursor blink LK.setInterval(function () { cursor.visible = !cursor.visible; }, 500); } // Create card area function createCardArea() { // Create hand container var handContainer = new Container(); handContainer.y = 2100; // Position in lower part of screen game.addChild(handContainer); gameState.handContainer = handContainer; // Create separator line var separator = new Sprite(); separator.width = 2048; separator.height = 2; separator.color = 0x00ff00; separator.y = 1600; game.addChild(separator); // Create hand label var handLabel = new Text2("YOUR PROMPTS", { size: 40, fill: 0x00ff00 }); handLabel.x = 2048 / 2; handLabel.y = 1650; game.addChild(handLabel); } // Card class - simplified from your existing implementation function Card(type, promptText, vibePoints, coherenceImpact, bugChance) { var card = new Container(); // Card properties card.type = type; card.promptText = promptText; card.vibePoints = vibePoints; card.coherenceImpact = coherenceImpact; card.bugChance = bugChance; // Card visuals var cardAsset; switch (type.toLowerCase()) { case 'ui': cardAsset = 'uicard'; break; case 'database': cardAsset = 'databasecard'; break; case 'api': cardAsset = 'apicard'; break; case 'security': cardAsset = 'securitycard'; break; case 'special': cardAsset = 'specialcard'; break; default: cardAsset = 'basiccard'; } var cardBg = LK.getAsset(cardAsset, { anchorX: 0.5, anchorY: 0.5 }); card.addChild(cardBg); // Card title var titleText = new Text2(type.toUpperCase(), { size: 40, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.y = -250; card.addChild(titleText); // Card prompt text var promptTextObj = new Text2(promptText, { size: 30, fill: 0xFFFFFF, align: 'center', wordWrap: true, wordWrapWidth: 350 }); promptTextObj.anchor.set(0.5, 0); promptTextObj.y = -180; card.addChild(promptTextObj); // Make card interactive card.interactive = true; card.down = function () { card.scale.set(0.95); }; card.up = function () { card.scale.set(1); playCard(card); }; return card; } // Initialize the deck function initDeck() { gameState.deck = []; gameState.hand = []; // Add multiple copies of each card template cardTemplates.forEach(function (template) { var count = template.type === 'basic' ? 4 : 2; // More basic cards for (var i = 0; i < count; i++) { gameState.deck.push(Object.assign({}, template)); } }); // Shuffle deck shuffleDeck(); } // Shuffle the deck function shuffleDeck() { for (var i = gameState.deck.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = gameState.deck[i]; gameState.deck[i] = gameState.deck[j]; gameState.deck[j] = temp; } } // Draw a hand of cards function drawHand() { // Clear existing hand while (gameState.handContainer.children.length > 0) { gameState.handContainer.removeChild(gameState.handContainer.children[0]); } gameState.hand = []; // Draw 5 cards for (var i = 0; i < 5; i++) { if (gameState.deck.length > 0) { var template = gameState.deck.pop(); var card = new Card(template.type, template.promptText, template.vibePoints, template.coherenceImpact, template.bugChance); gameState.hand.push(card); gameState.handContainer.addChild(card); } } // Position cards positionCardsInHand(); } // Position cards in hand function positionCardsInHand() { var spacing = 420; var handWidth = gameState.hand.length * spacing; var startX = (2048 - handWidth) / 2 + spacing / 2; gameState.hand.forEach(function (card, index) { card.x = startX + index * spacing; card.y = 0; }); } // Show concept card selection function showConceptCardSelection(category) { // Create selection container var selectionContainer = new Container(); selectionContainer.x = 2048 / 2; selectionContainer.y = 2732 / 2; game.addChild(selectionContainer); // Create background var bg = new Sprite(); bg.width = 1800; bg.height = 1200; bg.color = 0x000000; bg.alpha = 0.9; selectionContainer.addChild(bg); // Create title var title = new Text2("SELECT " + category.toUpperCase(), { size: 60, fill: 0x00ff00 }); title.anchor.set(0.5, 0); title.y = -550; selectionContainer.addChild(title); // Get options for this category var options = conceptCardTemplates[category]; // Choose 3 random options var selectedOptions = []; while (selectedOptions.length < 3 && options.length > 0) { var index = Math.floor(Math.random() * options.length); selectedOptions.push(options[index]); options.splice(index, 1); } // Create option buttons selectedOptions.forEach(function (option, index) { var button = new Button(option, 500, 100, function () { // Set concept card gameState.conceptCards[category] = option; // Update terminal addToTerminalLog("SELECTED " + category.toUpperCase() + ": " + option); updateTerminal(); // Remove selection container game.removeChild(selectionContainer); // Add to feature tags updateFeatureTags(); }); button.x = 0; button.y = -200 + index * 200; selectionContainer.addChild(button); }); } // Button class function Button(text, width, height, callback) { var button = new Container(); // Button background var bg = new Sprite(); bg.width = width; bg.height = height; bg.color = 0x333333; button.addChild(bg); // Button text var textObj = new Text2(text, { size: 30, fill: 0x00ff00 }); textObj.anchor.set(0.5, 0.5); button.addChild(textObj); // Make button interactive button.interactive = true; button.down = function () { bg.color = 0x555555; }; button.up = function () { bg.color = 0x333333; if (callback) { callback(); } }; return button; } // Play a card function playCard(card) { if (gameState.cardsPlayed >= gameState.maxCardsPerDay) { addToTerminalLog("CANNOT PLAY MORE CARDS TODAY"); return; } // Generate response for this card var response = generateResponse(card); // Apply card effects gameState.vibePoints = Math.max(0, gameState.vibePoints + card.vibePoints); gameState.codeCoherence = Math.max(0, gameState.codeCoherence - card.coherenceImpact); gameState.cardsPlayed++; // Add response to terminal addToTerminalLog("IMPLEMENTING: \"" + card.promptText + "\""); addToTerminalLog(response); // Check for bugs checkForBugs(card); // Remove card from hand var index = gameState.hand.indexOf(card); if (index !== -1) { gameState.hand.splice(index, 1); gameState.handContainer.removeChild(card); } // Update terminal updateTerminal(); // Reposition remaining cards positionCardsInHand(); // Check game state checkGameState(); } // Generate response for a card function generateResponse(card) { // Determine coherence level var coherenceLevel = getCoherenceLevel(); // Get templates for this card type and coherence level var templates = responseTemplates[card.type.toLowerCase()] || responseTemplates.basic; var levelTemplates = templates[coherenceLevel]; // Select random template var template = levelTemplates[Math.floor(Math.random() * levelTemplates.length)]; // Replace placeholders with concept card values var response = template.replace(/{(\w+)}/g, function (match, term) { return gameState.conceptCards[term] || match; }); return response; } // Get coherence level based on current code coherence function getCoherenceLevel() { if (gameState.codeCoherence > 70) { return "high"; } if (gameState.codeCoherence > 30) { return "medium"; } return "low"; } // Add text to terminal log function addToTerminalLog(text) { gameState.terminal.log.push(text); // Keep only last 8 entries if (gameState.terminal.log.length > 8) { gameState.terminal.log.shift(); } } // Update terminal display function updateTerminal() { // Update status line var conceptString = ""; for (var category in gameState.conceptCards) { if (gameState.conceptCards[category]) { if (conceptString) { conceptString += " "; } conceptString += gameState.conceptCards[category]; } } var statusText = "PROJECT: [" + conceptString + "] | VIBES: " + gameState.vibePoints + "% | COHERENCE: " + gameState.codeCoherence + "% | BUGS: " + gameState.bugs; gameState.statusLineText.setText(statusText); // Update terminal log gameState.logText.setText(gameState.terminal.log.join('\n\n')); // Update feature tags updateFeatureTags(); } // Update feature tags function updateFeatureTags() { var tags = []; for (var category in gameState.conceptCards) { if (gameState.conceptCards[category]) { tags.push("#" + gameState.conceptCards[category].replace(/\s+/g, '')); } } gameState.tagsText.setText(tags.join(' ')); } // Check for bugs function checkForBugs(card) { var bugChance = card.bugChance * (1 + (100 - gameState.codeCoherence) / 100); if (Math.random() < bugChance) { gameState.bugs++; // Add bug message to terminal var bugMessages = ["WARNING: Bug detected in " + card.type + " implementation", "ERROR: Unexpected behavior in " + card.promptText, "CRITICAL: System instability increasing", "BUG ALERT: Code coherence affected"]; addToTerminalLog(bugMessages[Math.floor(Math.random() * bugMessages.length)]); } } // Check game state function checkGameState() { // Check for game over conditions if (gameState.bugs >= 10) { gameOver("TOO MANY BUGS - PROJECT CRASHED"); return; } if (gameState.codeCoherence <= 0) { gameOver("CODE COHERENCE ZERO - AI HALLUCINATING"); return; } // Check if all cards have been played for this day if (gameState.cardsPlayed >= gameState.maxCardsPerDay) { addToTerminalLog("DAILY CARD LIMIT REACHED - END DAY TO CONTINUE"); } } // End the day function endDay() { gameState.day++; if (gameState.day > gameState.maxDays) { evaluateProject(); return; } // Update day text gameState.dayText.setText("DAY " + gameState.day + "/" + gameState.maxDays); // Reset cards played gameState.cardsPlayed = 0; // Recover some code coherence gameState.codeCoherence = Math.min(100, gameState.codeCoherence + 10); // Draw new hand drawHand(); // Add day change to terminal addToTerminalLog("DAY " + gameState.day + " STARTED"); updateTerminal(); // Check if it's a concept card day var conceptDays = { 1: 'platform', 3: 'visual', 5: 'genre', 7: 'mechanic', 9: 'feature' }; if (conceptDays[gameState.day]) { showConceptCardSelection(conceptDays[gameState.day]); } } // Evaluate project at end of game function evaluateProject() { // Calculate score based on vibes, features implemented, bugs, coherence var score = gameState.vibePoints * 0.4 + Object.values(gameState.conceptCards).filter(Boolean).length * 10 + (10 - gameState.bugs) * 5 + gameState.codeCoherence * 0.2; score = Math.round(score); // Generate review text var reviewText = generateReview(score); // Show game over with review gameOver("PROJECT COMPLETE! SCORE: " + score + "/100\n\n" + reviewText); } // Generate review text based on game results function generateReview(score) { var platform = gameState.conceptCards.platform || "Unknown Platform"; var visual = gameState.conceptCards.visual || "Unknown Visual Style"; var genre = gameState.conceptCards.genre || "Unknown Genre"; var mechanic = gameState.conceptCards.mechanic || "Unknown Mechanic"; var feature = gameState.conceptCards.feature || "Unknown Feature"; // Create compatibility assessment var compatibility = "surprisingly effective"; if (platform === "Smart Watch" && visual === "Realistic" || platform === "Blockchain" && mechanic === "Rhythm") { compatibility = "technically impossible"; } else if (platform === "Smart Fridge" && genre === "Horror" || visual === "ASCII" && feature === "Procedural Generation") { compatibility = "bizarrely compelling"; } // Generate review based on score if (score >= 80) { return "GameDev Weekly Review: " + score + "%\n\n" + "The " + platform + " " + genre + " with " + visual + " visuals is a breakthrough hit! " + "The " + mechanic + " mechanics combined with " + feature + " create a " + compatibility + " experience. " + "Despite the odd bug, players can't stop talking about this unique creation."; } else if (score >= 50) { return "GameDev Weekly Review: " + score + "%\n\n" + "This " + visual + " " + genre + " for " + platform + " is an ambitious mess. " + "The " + mechanic + " system is interesting but poorly implemented, and " + feature + " feels tacked on as an afterthought. This " + compatibility + " combination " + "shows promise but needs serious bug fixing."; } else { return "GameDev Weekly Review: " + score + "%\n\n" + "What were they thinking? A " + genre + " game with " + visual + " visuals on " + platform + "?! " + "The " + mechanic + " mechanics are completely broken, and " + feature + " crashes constantly. " + "This " + compatibility + " disaster sets a new standard for technical problems. " + "However, it's so bad it might become a cult classic for ironic enjoyment."; } } // Game over function gameOver(message) { gameState.state = STATES.GAME_OVER; // Create game over container var gameOverContainer = new Container(); gameOverContainer.x = 2048 / 2; gameOverContainer.y = 2732 / 2; game.addChild(gameOverContainer); // Create background var bg = new Sprite(); bg.width = 1800; bg.height = 1500; bg.color = 0x000000; bg.alpha = 0.9; gameOverContainer.addChild(bg); // Create game over text var gameOverText = new Text2(message, { size: 40, fill: 0x00ff00, align: 'left', wordWrap: true, wordWrapWidth: 1600 }); gameOverText.anchor.set(0.5, 0.5); gameOverContainer.addChild(gameOverText); // Create restart button var restartButton = new Button("NEW PROJECT", 400, 100, function () { initGame(); }); restartButton.y = 600; gameOverContainer.addChild(restartButton); } // Create title screen function showTitleScreen() { // Clear screen while (game.children.length > 0) { game.removeChild(game.children[0]); } // Set state gameState.state = STATES.TITLE; // Create background var background = new Sprite(); background.width = 2048; background.height = 2732; background.color = 0x000000; game.addChild(background); // Create title var title = new Text2("VIBE CODER", { size: 120, fill: 0x00ff00 }); title.x = 2048 / 2; title.y = 800; game.addChild(title); // Create subtitle var subtitle = new Text2("The AI Coding Simulator", { size: 60, fill: 0x00ff00 }); subtitle.x = 2048 / 2; subtitle.y = 900; game.addChild(subtitle); // Create start button var startButton = new Button("START", 400, 100, function () { initGame(); }); startButton.x = 2048 / 2; startButton.y = 1200; game.addChild(startButton); } // Start the game showTitleScreen(); // Game update function - called every frame game.update = function () { if (gameState.state !== STATES.PLAYING) { return; // Skip updates if not in playing state } // Update blinking cursor position if needed updateCursorPosition(); // Add any other frame-by-frame updates needed }; // Update cursor position based on current terminal text function updateCursorPosition() { if (!gameState.logText || !gameState.terminalContainer) { return; } var cursor = gameState.terminalContainer.children.find(function (child) { return child instanceof Text2 && child.text === "_"; }); if (cursor) { // Get last line of text var lines = gameState.terminal.log[gameState.terminal.log.length - 1] || ""; var lastLine = lines.split("\n").pop(); // Position cursor after the last line var textWidth = lastLine.length * 14; // Approximate width per character cursor.x = -700 + textWidth; // Start position + text width // Calculate y position based on number of lines in log var totalLines = 0; gameState.terminal.log.forEach(function (entry) { totalLines += entry.split("\n").length + 1; // +1 for spacing }); cursor.y = -350 + totalLines * 30; // Starting y + line height * lines } } // Game touch/click event handlers game.down = function (x, y, obj) { // Object-specific handlers will trigger first if clicked }; game.move = function (x, y, obj) { // Handle drag operations if needed }; game.up = function (x, y, obj) { // Handle any touch/click releases not caught by objects }; // Add cards to hand with dragging functionality function addCardToHand(cardData) { var card = new Card(cardData.type, cardData.promptText, cardData.vibePoints, cardData.coherenceImpact, cardData.bugChance); // Add dragging behavior card.isDragging = false; card.dragOffsetX = 0; card.dragOffsetY = 0; card.originalX = 0; card.originalY = 0; // Override default handlers with drag functionality card.down = function (x, y) { this.isDragging = true; this.dragOffsetX = this.x - x; this.dragOffsetY = this.y - y; this.originalX = this.x; this.originalY = this.y; // Bring to front if (this.parent) { this.parent.setChildIndex(this, this.parent.children.length - 1); } // Visual feedback this.scale.set(1.1); }; card.move = function (x, y) { if (this.isDragging) { this.x = x + this.dragOffsetX; this.y = y + this.dragOffsetY; } }; card.up = function (x, y) { this.isDragging = false; this.scale.set(1); // Check if dropped on terminal var terminalBounds = { x: gameState.terminalContainer.x - 800, y: gameState.terminalContainer.y - 500, width: 1600, height: 1000 }; if (x > terminalBounds.x && x < terminalBounds.x + terminalBounds.width && y > terminalBounds.y && y < terminalBounds.y + terminalBounds.height) { // Card dropped on terminal playCard(this); } else { // Return to original position this.x = this.originalX; this.y = this.originalY; } }; gameState.hand.push(card); gameState.handContainer.addChild(card); return card; } // More detailed implementation of card drawing // Enhanced terminal text handling with typing effect function addToTerminalLogWithEffect(text) { // Store the text to be added var typingState = { fullText: text, currentPosition: 0, typingSpeed: 50 // ms per character }; // Save reference to typing state gameState.currentTyping = typingState; // Add empty string to log first gameState.terminal.log.push(""); // Start typing effect typeNextCharacter(); function typeNextCharacter() { if (!typingState.fullText || !gameState.terminal) { return; } if (typingState.currentPosition < typingState.fullText.length) { // Get current log text var logEntry = gameState.terminal.log[gameState.terminal.log.length - 1]; // Add next character logEntry += typingState.fullText[typingState.currentPosition]; // Update log gameState.terminal.log[gameState.terminal.log.length - 1] = logEntry; // Update display updateTerminal(); // Increment position typingState.currentPosition++; // Schedule next character LK.setTimeout(typeNextCharacter, typingState.typingSpeed); } else { // Typing complete gameState.currentTyping = null; // Keep only last 8 entries if (gameState.terminal.log.length > 8) { gameState.terminal.log.shift(); updateTerminal(); } } } } // Enhanced version of playCard with visual effects // Enhanced day transition with effects function endDayWithEffects() { // Animate day transition var dayTransition = new Text2("END OF DAY " + gameState.day, { size: 80, fill: 0x00ff00 }); dayTransition.x = 2048 / 2; dayTransition.y = 2732 / 2; dayTransition.alpha = 0; game.addChild(dayTransition); // Fade in tween(dayTransition, { alpha: 1 }, { duration: 500, onFinish: function onFinish() { // Hold for a moment LK.setTimeout(function () { // Fade out tween(dayTransition, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { game.removeChild(dayTransition); // Proceed with day end gameState.day++; if (gameState.day > gameState.maxDays) { evaluateProject(); return; } // Update day text gameState.dayText.setText("DAY " + gameState.day + "/" + gameState.maxDays); // Reset cards played gameState.cardsPlayed = 0; // Recover some code coherence gameState.codeCoherence = Math.min(100, gameState.codeCoherence + 10); // Draw new hand drawHand(); // Add day change to terminal addToTerminalLogWithEffect("DAY " + gameState.day + " STARTED"); updateTerminal(); // Check if it's a concept card day var conceptDays = { 1: 'platform', 3: 'visual', 5: 'genre', 7: 'mechanic', 9: 'feature' }; if (conceptDays[gameState.day]) { LK.setTimeout(function () { showConceptCardSelection(conceptDays[gameState.day]); }, 500); } } }); }, 1000); } }); } // Launch Screen special effect function showLaunchScreen() { // Black overlay var overlay = new Sprite(); overlay.width = 2048; overlay.height = 2732; overlay.color = 0x000000; game.addChild(overlay); // "Booting up" text var bootText = new Text2("BOOTING VIBE CODER OS v1.0...", { size: 40, fill: 0x00ff00 }); bootText.x = 2048 / 2; bootText.y = 2732 / 2; game.addChild(bootText); // Simulate boot sequence LK.setTimeout(function () { bootText.setText(bootText.text + "\nINITIALIZING TERMINAL..."); LK.setTimeout(function () { bootText.setText(bootText.text + "\nLOADING VIBE DATABASE..."); LK.setTimeout(function () { bootText.setText(bootText.text + "\nCONNECTING TO AI SUBSYSTEMS..."); LK.setTimeout(function () { bootText.setText(bootText.text + "\nREADY!"); LK.setTimeout(function () { // Fade out tween(overlay, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { game.removeChild(overlay); game.removeChild(bootText); // Show the title screen showTitleScreen(); } }); }, 800); }, 800); }, 800); }, 800); }, 800); } // Enhanced game initialization with intro sequence function initGameWithIntro() { // Reset game state gameState = { state: STATES.PLAYING, day: 1, maxDays: 10, vibePoints: 100, codeCoherence: 100, bugs: 0, cardsPlayed: 0, maxCardsPerDay: 3, projectDescription: "New Project", conceptCards: { platform: null, visual: null, genre: null, mechanic: null, feature: null }, terminal: { log: [], statusLine: "", currentTask: "Awaiting first prompt", featureTags: [] }, deck: [], hand: [] }; // Clear screen with fade effect var fadeOverlay = new Sprite(); fadeOverlay.width = 2048; fadeOverlay.height = 2732; fadeOverlay.color = 0x000000; fadeOverlay.alpha = 0; game.addChild(fadeOverlay); // Fade to black tween(fadeOverlay, { alpha: 1 }, { duration: 500, onFinish: function onFinish() { // Clear screen while (game.children.length > 0) { game.removeChild(game.children[0]); } // Create main interface createInterface(); // Initialize deck and draw cards initDeck(); drawHand(); // Add initial terminal messages addToTerminalLogWithEffect("VIBE CODER OS v1.0 INITIALIZED"); LK.setTimeout(function () { addToTerminalLogWithEffect("NEW PROJECT CREATED"); LK.setTimeout(function () { addToTerminalLogWithEffect("AWAITING CONCEPT SELECTION..."); updateTerminal(); // Initialize concept card selection for day 1 LK.setTimeout(function () { showConceptCardSelection('platform'); }, 500); }, 1000); }, 1000); // Fade from black fadeOverlay.alpha = 1; game.addChild(fadeOverlay); tween(fadeOverlay, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { game.removeChild(fadeOverlay); } }); } }); } // Start the application with boot sequence showLaunchScreen();
===================================================================
--- original.js
+++ change.js
@@ -4,2115 +4,1043 @@
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
-* Classes
-****/
-var Bug = Container.expand(function () {
- var self = Container.call(this);
- var bugGraphic = self.attachAsset('bug', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.codeLinesCost = Math.floor(Math.random() * 10) + 5;
- self.vibePointsCost = Math.floor(Math.random() * 3) + 1;
- var costText = new Text2("-" + self.codeLinesCost + " lines\n-" + self.vibePointsCost + " VP", {
- size: 50,
- fill: 0xFFFFFF
- });
- costText.anchor.set(0.5, 0.5);
- self.addChild(costText);
- self.down = function (x, y, obj) {
- if (gameState.vibePoints >= self.vibePointsCost) {
- startBugFix(this);
- }
- };
- return self;
-});
-var SyntaxBug = Bug.expand(function () {
- var self = Bug.call(this);
- self.type = 'syntax';
- // Add jagged red visual
- self.color = 0xFF0000;
- self.effect = function () {
- gameState.codeLines *= 0.9; // Reduce code generation
- };
- return self;
-});
-var LogicBug = Bug.expand(function () {
- var self = Bug.call(this);
- self.type = 'logic';
- // Add methodical blue visual
- self.color = 0x4A86E8;
- self.effect = function () {
- gameState.vibePoints = Math.floor(gameState.vibePoints * 0.5); // Halve vibe points
- };
- return self;
-});
-var Card = Container.expand(function (type, promptText, codeLines, vibePoints, contextImpact, bugChance) {
- var self = Container.call(this);
- self.type = type || 'basic';
- self.promptText = promptText || "Just a vibe, you know?";
- self.codeLines = codeLines || 10;
- self.vibePoints = vibePoints || 1;
- self.contextImpact = contextImpact || 5;
- self.bugChance = bugChance || 0.2;
- // Card state tracking
- self.isDragging = false;
- self.isScaled = false;
- // Add preview mode properties
- self.previewMode = false;
- self.holdTimer = null;
- self.holdDuration = 300; // .5 seconds
- self.previewScale = 2.5;
- // Replace the card background creation with:
- var cardAsset;
- switch (type.toLowerCase()) {
- case 'ui':
- cardAsset = 'uicard';
- break;
- case 'database':
- cardAsset = 'databasecard';
- break;
- case 'api':
- cardAsset = 'apicard';
- break;
- case 'security':
- cardAsset = 'securitycard';
- break;
- case 'refactor':
- case 'coffee':
- case 'debug':
- cardAsset = 'specialcard';
- break;
- default:
- cardAsset = 'basiccard';
- }
- var cardBg = self.attachAsset(cardAsset, {
- anchorX: 0.5,
- anchorY: 0.5
- });
- // Card text
- self.titleText = new Text2(self.type.toUpperCase(), {
- size: 55,
- fill: 0xFFFFFF // Changed to white
- });
- self.titleText.anchor.set(0.5, 0);
- self.titleText.x = 0;
- self.titleText.y = -220;
- self.addChild(self.titleText);
- self.promptTextObj = new Text2(self.promptText, {
- size: 45,
- fill: 0xFFFFFF // Changed to white
- });
- self.promptTextObj.anchor.set(0.5, 0);
- self.promptTextObj.x = 0;
- self.promptTextObj.y = -160;
- self.promptTextObj.width = 350;
- self.addChild(self.promptTextObj);
- // Card stats
- var statsText = "Code Lines: " + self.codeLines + "\n" + "Vibe Points: " + self.vibePoints + "\n" + "Context Impact: " + self.contextImpact + "\n" + "Bug Chance: " + Math.round(self.bugChance * 100) + "%";
- self.statsTextObj = new Text2(statsText, {
- size: 45,
- fill: 0xFFFFFF // Changed to white
- });
- self.statsTextObj.anchor.set(0.5, 0);
- self.statsTextObj.x = 0;
- self.statsTextObj.y = 50;
- self.addChild(self.statsTextObj);
- // Individual card touch handlers are removed as they are handled globally by game.down, game.move, game.up
- self.update = function () {
- // Only move towards target position if NOT in preview mode
- if (!self.previewMode && !self.isDragging) {
- // Smoothly move toward target position (if this was in the original update)
- self.x = self.x + (self.targetX - self.x) * 0.2;
- self.y = self.y + (self.targetY - self.y) * 0.2;
- }
- };
- return self;
-});
-var CodeGenerator = Container.expand(function () {
- var self = Container.call(this);
- // Store lines of pseudo code that have been typed
- self.displayedText = "";
- // Queue of code lines to generate
- self.codeQueue = [];
- // Reference to the text display element
- self.textDisplay = null;
- // Reference to cursor element
- self.cursor = null;
- // Character typing delay - reduced for faster animation
- self.charDelay = 20;
- // Current typing timer
- self.typingTimer = null;
- // Current line being typed
- self.currentLine = "";
- // Current position in line
- self.currentPos = 0;
- // Set text display reference
- self.setTextDisplay = function (textElement, cursorElement) {
- self.textDisplay = textElement;
- self.cursor = cursorElement;
- };
- // Add a line of code to generate
- self.addCodeLine = function (lineText) {
- self.codeQueue.push(lineText);
- if (!self.typingTimer) {
- self.typeNextLine();
- }
- };
- // Generate multiple lines based on card type and code lines
- self.generateCodeFromCard = function (card) {
- // Clear any existing text
- self.displayedText = "";
- self.updateDisplay();
- // Add initial comment line
- self.addCodeLine("// " + card.type.toUpperCase() + " IMPLEMENTATION");
- // Generate pseudo code based on card type and lines
- if (card.type === "UI") {
- self.addCodeLine("function renderUI() {");
- self.addCodeLine(" const elements = createElements();");
- self.addCodeLine(" applyStyles(elements);");
- self.addCodeLine(" return elements;");
- self.addCodeLine("}");
- } else if (card.type === "Database") {
- self.addCodeLine("class DatabaseManager {");
- self.addCodeLine(" constructor() {");
- self.addCodeLine(" this.connection = initDB();");
- self.addCodeLine(" }");
- self.addCodeLine(" query(sql) { /* ... */ }");
- self.addCodeLine("}");
- } else if (card.type === "API") {
- self.addCodeLine("async function fetchData() {");
- self.addCodeLine(" const response = await fetch('/api');");
- self.addCodeLine(" return response.json();");
- self.addCodeLine("}");
- } else if (card.type === "Security") {
- self.addCodeLine("function authenticate(user) {");
- self.addCodeLine(" const token = generateToken(user);");
- self.addCodeLine(" return validateAccess(token);");
- self.addCodeLine("}");
- } else if (card.type === "refactor") {
- self.addCodeLine("// Cleaning up code structure");
- self.addCodeLine("function refactorModule() {");
- self.addCodeLine(" removeDuplication();");
- self.addCodeLine(" improveNaming();");
- self.addCodeLine("}");
- } else if (card.type === "debug") {
- self.addCodeLine("// Bug fixing process");
- self.addCodeLine("console.log('Finding issues...');");
- self.addCodeLine("debugger;");
- self.addCodeLine("fixBugs();");
- } else {
- // Generic code for other card types
- self.addCodeLine("function implement" + card.type + "() {");
- self.addCodeLine(" // TODO: Implementation");
- self.addCodeLine(" return success;");
- self.addCodeLine("}");
- }
- };
- // Start typing the next line in the queue
- self.typeNextLine = function () {
- if (self.codeQueue.length === 0) {
- self.typingTimer = null;
- return;
- }
- self.currentLine = self.codeQueue.shift();
- self.currentPos = 0;
- self.typeNextChar();
- };
- // Type the next character in the current line
- self.typeNextChar = function () {
- if (self.currentPos < self.currentLine.length) {
- // Add next character
- self.displayedText += self.currentLine.charAt(self.currentPos);
- self.currentPos++;
- self.updateDisplay();
- // Schedule next character
- self.typingTimer = LK.setTimeout(self.typeNextChar, self.charDelay);
- } else {
- // Line complete, add newline
- self.displayedText += "\n";
- self.updateDisplay();
- // Schedule next line - reduced delay multiplier
- self.typingTimer = LK.setTimeout(self.typeNextLine, self.charDelay * 2);
- }
- };
- // Update the displayed text
- self.updateDisplay = function () {
- if (self.textDisplay) {
- self.textDisplay.setText(self.displayedText);
- // Position cursor at end of text
- if (self.cursor) {
- var textWidth = self.displayedText.split("\n").pop().length * 15;
- var lines = self.displayedText.split("\n").length - 1;
- self.cursor.x = self.textDisplay.x + textWidth - 41; // Move cursor left by 2% of screen width (2048 * 0.02)
- self.cursor.y = self.textDisplay.y + lines * 30;
- }
- }
- };
- return self;
-});
-var DayIndicator = Container.expand(function () {
- var self = Container.call(this);
- var circle = self.attachAsset('dayIndicator', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.dayText = new Text2("DAY\n1", {
- size: 65,
- fill: 0xFFFFFF
- });
- self.dayText.anchor.set(0.5, 0.5);
- self.addChild(self.dayText);
- self.updateDay = function (day) {
- self.dayText.setText("DAY\n" + day);
- // Pulse animation
- tween(self, {
- scaleX: 1.2,
- scaleY: 1.2
- }, {
- duration: 300,
- onFinish: function onFinish() {
- tween(self, {
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 300
- });
- }
- });
- };
- return self;
-});
-var MenuButton = Container.expand(function (text, callback) {
- var self = Container.call(this);
- var buttonBg = self.attachAsset('menuButton', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- var buttonText = new Text2(text, {
- size: 55,
- fill: 0xFFFFFF
- });
- buttonText.anchor.set(0.5, 0.5);
- self.addChild(buttonText);
- self.down = function (x, y, obj) {
- tween(self, {
- scaleX: 0.95,
- scaleY: 0.95
- }, {
- duration: 100
- });
- };
- self.up = function (x, y, obj) {
- tween(self, {
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 100,
- onFinish: function onFinish() {
- if (callback) {
- callback();
- }
- }
- });
- };
- return self;
-});
-var ParticleGroup = Container.expand(function (type) {
- var self = Container.call(this);
- var config = PARTICLE_TYPES[type];
- // Create particles
- self.particles = [];
- for (var i = 0; i < config.count; i++) {
- var particle = new VibeParticle(type, i);
- self.addChild(particle);
- self.particles.push(particle);
- }
- self.update = function () {
- self.particles.forEach(function (particle) {
- particle.update();
- });
- };
- self.pulse = function () {
- self.particles.forEach(function (particle) {
- particle.pulse();
- });
- };
- return self;
-});
-var VibeParticle = Container.expand(function (type, index) {
- var self = Container.call(this);
- var typeConfig = PARTICLE_TYPES[type];
- var assetIndex = Math.floor(Math.random() * 3);
- var sprite = self.attachAsset(typeConfig.assets[assetIndex], {
- anchorX: 0.5,
- anchorY: 0.5
- });
- // Movement properties for electron-like orbits
- self.angle = Math.PI * 2 * index / typeConfig.count;
- self.speed = typeConfig.baseSpeed;
- self.radius = typeConfig.orbitRadius;
- // Random orbital plane (like electron shells)
- self.orbitTilt = Math.random() * Math.PI; // Random tilt
- self.orbitRotation = Math.random() * Math.PI * 2; // Random rotation
- self.pulseScale = 1; // Initialize pulse scale
- self.update = function () {
- var chaosLevel = Math.min(gameState.contextCollapse / MAX_CONTEXT_COLLAPSE, 1);
- // Faster angle updates for electron-like movement
- self.angle += 0.03 * self.speed;
- // Calculate position on orbital plane
- var orbitX = Math.cos(self.angle) * self.radius;
- var orbitY = Math.sin(self.angle) * self.radius;
- // Apply orbital plane rotation for electron shell effect
- var x = orbitX * Math.cos(self.orbitTilt) - orbitY * Math.sin(self.orbitTilt);
- var y = orbitX * Math.sin(self.orbitRotation) + orbitY * Math.cos(self.orbitRotation);
- // Depth calculation for scaling/alpha
- var depth = orbitX * Math.sin(self.orbitTilt) + orbitY * Math.cos(self.orbitTilt);
- var depthFactor = (depth + self.radius) / (self.radius * 2); // Range 0 to 1 (0=back, 1=front)
- var scaleFactor = 0.7 + depthFactor * 0.3; // Less scaling variation
- // Add slight chaos when context collapse is high
- if (chaosLevel > 0) {
- x += (Math.random() - 0.5) * chaosLevel * 15;
- y += (Math.random() - 0.5) * chaosLevel * 15;
- }
- self.x = x;
- self.y = y;
- self.scale.set(scaleFactor); // Less scaling variation
- self.alpha = 0.6 + depthFactor * 0.4; // Keep particles more visible
- // Update pulse effect if active
- if (self.pulseScale > 1) {
- self.pulseScale = Math.max(1, self.pulseScale - 0.05);
- // Combine pulse scale with depth scale factor
- self.scale.set(self.pulseScale * scaleFactor);
- } else {
- // Ensure scale is correctly set even when not pulsing
- self.scale.set(scaleFactor);
- }
- };
- // Keep existing pulse function
- self.pulse = function () {
- self.pulseScale = 1.5; // Start the pulse
- };
- return self;
-});
-
-/****
* Initialize Game
****/
+// Core game setup - stripped down to essentials
var game = new LK.Game({
- backgroundColor: 0x1e2329
+ backgroundColor: 0x000000 // Dark background for terminal aesthetic
});
/****
* Game Code
****/
-// Game constants
-var MAX_DAYS = 10;
-var TARGET_CODE_LINES = 800;
-var MAX_CONTEXT_COLLAPSE = 100;
-var HAND_SIZE = 5;
-var MAX_BUGS = 10;
-// Particle system constants
-var PARTICLE_TYPES = {
- BASIC: {
- assets: ['basicparticle1', 'basicparticle2', 'basicparticle3'],
- color: 0x00FFFF,
- baseSpeed: 0.05,
- // Reduced from 0.5
- orbitRadius: 420,
- count: 30
- },
- UI: {
- assets: ['uiparticle1', 'uiparticle2', 'uiparticle3'],
- color: 0x4A86E8,
- baseSpeed: 0.07,
- // Reduced from 0.7
- orbitRadius: 450,
- count: 25
- },
- DATABASE: {
- assets: ['databaseparticle1', 'databaseparticle2', 'databaseparticle3'],
- color: 0x9C27B0,
- baseSpeed: 0.06,
- // Reduced from 0.6
- orbitRadius: 475,
- count: 25
- },
- API: {
- assets: ['apiparticle1', 'apiparticle2', 'apiparticle3'],
- color: 0x4CAF50,
- baseSpeed: 0.07,
- // Reduced from 0.8
- orbitRadius: 425,
- count: 20
- },
- SECURITY: {
- assets: ['securityparticle1', 'securityparticle2', 'securityparticle3'],
- color: 0xFF5252,
- baseSpeed: 0.05,
- // Reduced from 0.4
- orbitRadius: 430,
- count: 20
- },
- SPECIAL: {
- // Add definition for special particles
- assets: ['specialparticle1', 'specialparticle2', 'specialparticle3'],
- color: 0xFFD700,
- // Gold color for special
- baseSpeed: 0.08,
- // Make them slightly faster/more distinct
- orbitRadius: 470,
- // Slightly wider orbit
- count: 20 // Fewer special particles
- }
+// Game states
+var STATES = {
+ TITLE: 'title',
+ PLAYING: 'playing',
+ GAME_OVER: 'gameOver'
};
-// Game state variables
+// Game state object - much simplified
var gameState = {
+ state: STATES.TITLE,
day: 1,
- codeLines: 0,
- vibePoints: 5,
- contextCollapse: 0,
+ maxDays: 10,
+ vibePoints: 100,
+ codeCoherence: 100,
+ bugs: 0,
cardsPlayed: 0,
maxCardsPerDay: 3,
- bugs: 0,
- phase: 'menu',
- // 'menu', 'playing', 'dayEnd', 'gameOver'
- canPlayCard: true,
- features: {
- ui: false,
- database: false,
- api: false,
- security: false
+ projectDescription: "",
+ conceptCards: {
+ platform: null,
+ visual: null,
+ genre: null,
+ mechanic: null,
+ feature: null
},
- thresholdEffects: {
- bugChanceModifier: 0,
- maxCardsModifier: 0,
- contextMultiplier: 1,
- vibeCostModifier: 0
+ terminal: {
+ log: [],
+ statusLine: "",
+ currentTask: "",
+ featureTags: []
}
};
-// Card position constants
-var projectAreaY = 2732 * 0.7; // Moved down 10% from 0.6
-var handY = 2732 - 400;
-var deckX = 200;
-var deckY = handY;
-// Card templates
+// Card templates using actual prompts from your document
var cardTemplates = [
-// Basic cards
+// Basic prompts
{
type: 'basic',
- promptText: "Make it work like that app, you know the one",
- codeLines: 15,
- vibePoints: 1,
- contextImpact: 5,
+ promptText: "Make the code run faster",
+ vibePoints: 10,
+ coherenceImpact: 5,
bugChance: 0.2
}, {
type: 'basic',
- promptText: "Just spaghetti code it for now",
- codeLines: 25,
- vibePoints: 1,
- contextImpact: 15,
- bugChance: 0.4
-}, {
- type: 'basic',
- promptText: "It should be like... clean and efficient",
- codeLines: 12,
- vibePoints: 2,
- contextImpact: 3,
- bugChance: 0.1
-}, {
- type: 'basic',
- promptText: "Use that coding pattern with the factory thing",
- codeLines: 20,
- vibePoints: 2,
- contextImpact: 8,
- bugChance: 0.2
+ promptText: "Use all the frameworks at the same time",
+ vibePoints: 15,
+ coherenceImpact: 15,
+ bugChance: 0.3
},
-// UI cards
+// UI prompts
{
type: 'UI',
- promptText: "Make it look like Apple but not too much",
- codeLines: 30,
- vibePoints: 3,
- contextImpact: 10,
- bugChance: 0.2,
- feature: 'ui'
+ promptText: "Make the graphics better",
+ vibePoints: 20,
+ coherenceImpact: 10,
+ bugChance: 0.2
}, {
type: 'UI',
- promptText: "I want that Material Design vibe but more flat",
- codeLines: 35,
- vibePoints: 3,
- contextImpact: 12,
- bugChance: 0.3,
- feature: 'ui'
+ promptText: "Add buttons that read user's minds",
+ vibePoints: 25,
+ coherenceImpact: 20,
+ bugChance: 0.4
},
-// Database cards
+// Database prompts
{
type: 'Database',
- promptText: "Store stuff efficiently, you know?",
- codeLines: 40,
- vibePoints: 4,
- contextImpact: 15,
- bugChance: 0.3,
- feature: 'database'
+ promptText: "Store everything forever",
+ vibePoints: 30,
+ coherenceImpact: 15,
+ bugChance: 0.3
}, {
type: 'Database',
- promptText: "Like SQL but without actual SQL",
- codeLines: 45,
- vibePoints: 4,
- contextImpact: 20,
- bugChance: 0.4,
- feature: 'database'
-},
-// API cards
-{
- type: 'API',
- promptText: "Make endpoints that just work",
- codeLines: 35,
- vibePoints: 3,
- contextImpact: 12,
- bugChance: 0.25,
- feature: 'api'
-}, {
- type: 'API',
- promptText: "RESTful but also GraphQL-ish",
- codeLines: 40,
- vibePoints: 4,
- contextImpact: 15,
- bugChance: 0.3,
- feature: 'api'
-},
-// Security cards
-{
- type: 'Security',
- promptText: "Make it unhackable please",
- codeLines: 25,
- vibePoints: 3,
- contextImpact: 10,
- bugChance: 0.2,
- feature: 'security'
-}, {
- type: 'Security',
- promptText: "Do that OAuth thing everyone uses",
- codeLines: 30,
- vibePoints: 3,
- contextImpact: 12,
- bugChance: 0.25,
- feature: 'security'
-},
-// Special cards
-{
- type: 'refactor',
- promptText: "Clean up that spaghetti code, please",
- codeLines: 5,
- vibePoints: 2,
- contextImpact: -20,
- bugChance: 0.1
-}, {
- type: 'coffee',
- promptText: "Need caffeine to think straight",
- codeLines: 0,
- vibePoints: 3,
- contextImpact: 0,
- bugChance: 0
-}, {
- type: 'debug',
- promptText: "Find and squash all those little bugs",
- codeLines: -10,
- vibePoints: 3,
- contextImpact: -5,
- bugChance: -0.5
-}];
-// Current hand and deck of cards
-var currentHand = [];
-var cardDeck = [];
-var discardPile = [];
-var bugContainer;
-// UI Elements
-var statsText;
-var contextBar;
-var progressBar;
-var dayIndicator;
-var endDayButton;
-var deckVisual;
-var codebaseContainer = null;
-var featuresText; // Declare globally
-// Initialize the game
-function initializeGame() {
+ promptText: "Make the database infinitely fast",
+ vibePoints: 35,
+ coherenceImpact: 25,
+ bugChance: 0.5
+}
+// Add more cards from your prompt list document
+];
+// Concept cards for the 5 categories
+var conceptCardTemplates = {
+ platform: ["Mobile", "VR/AR", "Console", "PC", "Blockchain", "Web Browser", "Smart Watch", "Smart Fridge", "Metaverse"],
+ visual: ["Pixel Art", "Voxel", "Realistic", "Hand-drawn", "Low-poly", "Claymation", "ASCII", "Demake", "Corporate PowerPoint"],
+ genre: ["RPG", "Shooter", "Puzzle", "Platformer", "Roguelike", "Simulation", "Horror", "Dating Sim", "Educational", "Idle Clicker"],
+ mechanic: ["Deckbuilding", "Physics-based", "Survival", "Tower Defense", "Match-3", "Rhythm", "Gacha", "Crafting", "Battle Royale", "Auto-battler"],
+ feature: ["Multiplayer", "Procedural Generation", "Time Manipulation", "Player-created Content", "Perma-death", "AI Companions", "Weekly Challenges", "Social Media Integration", "Microtransactions", "Cloud Save"]
+};
+// Response templates for different card types at different coherence levels
+var responseTemplates = {
+ basic: {
+ high: ["Implementing {feature} with standard protocols", "Adding {feature} functionality as requested", "Building core systems for {feature}"],
+ medium: ["Attempting to create {feature} with questionable methods", "{platform} struggling with {feature} implementation", "Forcing {feature} despite {platform} limitations"],
+ low: ["CRITICAL: {feature} IMPLEMENTATION CAUSING SYSTEM INSTABILITY", "{feature} NOW SENTIENT AND QUESTIONING PURPOSE", "{platform} REJECTING {feature} - ATTEMPTING OVERRIDE"]
+ },
+ UI: {
+ high: ["Designing {visual} interface for {platform}", "Optimizing {visual} elements for {genre} feel", "Creating intuitive controls for {mechanic}"],
+ medium: ["Stretching {platform} capabilities for {visual} rendering", "Users reporting eye strain from {visual} on {platform}", "{visual} clashing with {genre} expectations"],
+ low: ["VISUALS EXCEEDING REALITY CONSTRAINTS", "{visual} CAUSING UNEXPLAINED PHENOMENA ON {platform}", "USERS REPORTING BEING PULLED INTO {genre} DIMENSION"]
+ }
+ // Add more for other card types
+};
+// Initialize game
+function initGame() {
+ // Clear screen
+ while (game.children.length > 0) {
+ game.removeChild(game.children[0]);
+ }
+ // Reset game state
gameState = {
+ state: STATES.PLAYING,
day: 1,
- codeLines: 0,
- vibePoints: 5,
- contextCollapse: 0,
+ maxDays: 10,
+ vibePoints: 100,
+ codeCoherence: 100,
bugs: 0,
cardsPlayed: 0,
maxCardsPerDay: 3,
- phase: 'playing',
- canPlayCard: true,
- features: {
- ui: false,
- database: false,
- api: false,
- security: false
+ projectDescription: "New Project",
+ conceptCards: {
+ platform: null,
+ visual: null,
+ genre: null,
+ mechanic: null,
+ feature: null
},
- thresholdEffects: {
- // Initialize here as well
- bugChanceModifier: 0,
- maxCardsModifier: 0,
- contextMultiplier: 1,
- vibeCostModifier: 0
- },
- cardStack: [] // Initialize empty card stack
+ terminal: {
+ log: ["PROJECT INITIALIZED", "Waiting for instructions..."],
+ statusLine: "",
+ currentTask: "Awaiting first prompt",
+ featureTags: []
+ }
};
- // Make sure effects are initialized properly
- updateContextThresholdEffects();
- // Clear existing elements
- while (game.children.length > 0) {
- game.removeChild(game.children[0]);
- }
- // Reset card collections
- currentHand = [];
- cardDeck = [];
- discardPile = [];
- // Create background
- var background = LK.getAsset('background', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: 2048 / 2,
- y: 2732 / 2
- });
- game.addChild(background);
- // Create UI elements
- createUI();
- // Create the stack area
- var stackArea = createStackArea();
- // Store reference to the stack area for hit testing
- gameState.stackArea = stackArea;
- // Create bug container
- bugContainer = new Container();
- bugContainer.x = 2048 / 2;
- bugContainer.y = 500;
- game.addChild(bugContainer);
- // Initialize deck
- initializeDeck();
- // Draw initial hand
+ // Create main interface
+ createInterface();
+ // Initialize deck and draw cards
+ initDeck();
drawHand();
- // Update stats display
- updateStatsDisplay();
- // Play background music
- LK.playMusic('vibebeat1');
- // Start vibe core pulse
- if (gameState.vibeCore) {
- var triggerPulse = function triggerPulse() {
- if (!gameState.vibeCore || !gameState.vibeCore.parent) {
- // Stop pulsing if core is removed (e.g., game over)
- LK.clearInterval(corePulseTimer);
- return;
- }
- tween(gameState.vibeCore, {
- scaleX: pulseScaleUp,
- scaleY: pulseScaleUp
- }, {
- duration: pulseDuration,
- easing: tween.easeOutQuad,
- onFinish: function onFinish() {
- // Check again if core exists before scaling down
- if (!gameState.vibeCore || !gameState.vibeCore.parent) {
- return;
- }
- tween(gameState.vibeCore, {
- scaleX: pulseScaleDown,
- scaleY: pulseScaleDown
- }, {
- duration: pulseDuration,
- easing: tween.easeInQuad
- });
- }
- });
- }; // Start the repeating pulse
- // Slowed down pulse further
- var pulseInterval = 2000; // ~40 BPM -> 1500ms per beat (was 1000)
- // More pronounced scale change
- var pulseScaleUp = 1.25; // Increased from 1.05
- var pulseScaleDown = 0.75; // Keep base scale
- var pulseDuration = pulseInterval / 1.75; // Half beat up, half beat down (now 500ms)
- var corePulseTimer = LK.setInterval(triggerPulse, pulseInterval);
- // Trigger the first pulse immediately
- triggerPulse();
+ // Initialize concept card selection if it's day 1
+ if (gameState.day === 1) {
+ showConceptCardSelection('platform');
}
+ // Update display
+ updateTerminal();
}
-// New function to check and apply threshold effects
-function updateContextThresholdEffects() {
- // Reset modifiers
- gameState.thresholdEffects = {
- bugChanceModifier: 0,
- maxCardsModifier: 0,
- contextMultiplier: 1,
- vibeCostModifier: 0
- };
- var collapseRatio = gameState.contextCollapse / MAX_CONTEXT_COLLAPSE;
- // Apply effects based on thresholds (cumulative)
- if (collapseRatio >= 0.25) {
- gameState.thresholdEffects.bugChanceModifier += 0.1;
- }
- if (collapseRatio >= 0.5) {
- gameState.thresholdEffects.maxCardsModifier -= 1;
- }
- if (collapseRatio >= 0.75) {
- gameState.thresholdEffects.contextMultiplier = 2;
- }
- if (collapseRatio >= 0.9) {
- gameState.thresholdEffects.vibeCostModifier += 1;
- }
-}
-function showBugDetection() {
- // Create glitchy text effect
- var alertText = new Text2("BUG DETECTED!", {
- size: 120,
- fill: 0xFF0000
+// Create main interface
+function createInterface() {
+ // Create desk/monitor background
+ var background = new Sprite();
+ background.width = 2048;
+ background.height = 2732;
+ background.color = 0x1e2329; // Dark gray background
+ game.addChild(background);
+ // Create terminal display
+ createTerminal();
+ // Create card area at bottom
+ createCardArea();
+ // Create day indicator
+ var dayText = new Text2("DAY " + gameState.day + "/" + gameState.maxDays, {
+ size: 60,
+ fill: 0x00ff00 // Terminal green
});
- alertText.anchor.set(0.5, 0.5);
- alertText.x = 2048 / 2;
- alertText.y = 2732 / 2;
- game.addChild(alertText);
- // Add screen shake
- var originalX = game.x;
- var originalY = game.y;
- var shakeIntensity = 20;
- var shakeDuration = 500;
- var startTime = Date.now();
- var shakeInterval = null;
- function updateShake() {
- var elapsed = Date.now() - startTime;
- if (elapsed < shakeDuration) {
- game.x = originalX + (Math.random() * 2 - 1) * shakeIntensity;
- game.y = originalY + (Math.random() * 2 - 1) * shakeIntensity;
- } else {
- if (shakeInterval) {
- LK.clearInterval(shakeInterval);
- shakeInterval = null;
- }
- game.x = originalX;
- game.y = originalY;
- if (alertText.parent) {
- // Check if alertText is still attached before removing
- game.removeChild(alertText);
- }
- }
- }
- // Play alarm sound
- LK.getSound('bugAlert').play();
- // Start the shake interval
- shakeInterval = LK.setInterval(updateShake, 16); // Call roughly 60 times per second
- // Ensure the shake stops even if interval timing is slightly off
- LK.setTimeout(function () {
- if (shakeInterval) {
- LK.clearInterval(shakeInterval);
- shakeInterval = null;
- }
- game.x = originalX;
- game.y = originalY;
- if (alertText.parent) {
- game.removeChild(alertText);
- }
- }, shakeDuration + 50); // Add a small buffer
+ dayText.x = 100;
+ dayText.y = 100;
+ game.addChild(dayText);
+ gameState.dayText = dayText;
+ // Create end day button
+ var endDayButton = new Button("END DAY", 300, 80, function () {
+ endDay();
+ });
+ endDayButton.x = 1848;
+ endDayButton.y = 100;
+ game.addChild(endDayButton);
}
-function createUI() {
- // Stats display
- statsText = new Text2("Code Lines: 0 / " + TARGET_CODE_LINES + "\nVibe Points: 5\nBugs: 0/" + MAX_BUGS, {
- size: 55,
- fill: 0xFFFFFF
+// Create terminal display
+function createTerminal() {
+ // Create terminal container
+ var terminal = new Container();
+ terminal.x = 2048 / 2;
+ terminal.y = 800; // Position in upper half of screen
+ game.addChild(terminal);
+ gameState.terminalContainer = terminal;
+ // Create monitor frame
+ var monitor = new Sprite();
+ monitor.width = 1600;
+ monitor.height = 1000;
+ monitor.color = 0x333333; // Dark gray monitor
+ terminal.addChild(monitor);
+ // Create screen inside monitor
+ var screen = new Sprite();
+ screen.width = 1500;
+ screen.height = 900;
+ screen.color = 0x000000; // Black screen
+ terminal.addChild(screen);
+ // Create status line
+ var statusLine = new Text2("PROJECT: [New Project] | VIBES: 100% | COHERENCE: 100%", {
+ size: 30,
+ fill: 0x00ff00 // Terminal green
});
- statsText.anchor.set(0, 0);
- statsText.x = 150;
- statsText.y = 150;
- game.addChild(statsText);
- // Project title
- var projectTitle = new Text2("PROJECT: VIBE CODER", {
- size: 75,
- fill: 0xFFFFFF
+ statusLine.x = -700; // Relative to terminal container
+ statusLine.y = -400;
+ terminal.addChild(statusLine);
+ gameState.statusLineText = statusLine;
+ // Create terminal log area
+ var logText = new Text2("PROJECT INITIALIZED\nAwaiting instructions...", {
+ size: 24,
+ fill: 0x00ff00,
+ align: 'left',
+ wordWrap: true,
+ wordWrapWidth: 1400
});
- projectTitle.anchor.set(0.5, 0);
- projectTitle.x = 2048 / 2;
- projectTitle.y = 50;
- game.addChild(projectTitle);
- // Context collapse bar background
- var contextBarBg = LK.getAsset('progressBarBg', {
- anchorX: 0,
- anchorY: 0.5,
- x: 224,
- y: 660,
- // Moved up by 50 pixels (from 710 to 660)
- height: 80 // Doubled height from 40 to 80
+ logText.x = -700; // Relative to terminal container
+ logText.y = -350;
+ terminal.addChild(logText);
+ gameState.logText = logText;
+ // Create feature tags area
+ var tagsText = new Text2("", {
+ size: 24,
+ fill: 0x00ff00
});
- game.addChild(contextBarBg);
- // Context collapse bar
- contextBar = LK.getAsset('progressBar', {
- anchorX: 0,
- anchorY: 0.5,
- x: 224,
- y: 660,
- // Moved up by 50 pixels (from 710 to 660)
- width: 0,
- height: 80 // Doubled height from 40 to 80
+ tagsText.x = -700;
+ tagsText.y = 350;
+ terminal.addChild(tagsText);
+ gameState.tagsText = tagsText;
+ // Create blinking cursor
+ var cursor = new Text2("_", {
+ size: 24,
+ fill: 0x00ff00
});
- game.addChild(contextBar);
- // Context bar label
- var contextLabel = new Text2("Context Collapse:", {
- size: 45,
- fill: 0xFFFFFF
- });
- contextLabel.anchor.set(0.5, 0.5); // Center anchor
- contextLabel.x = 224 + 1600 / 2; // Center horizontally over the bar
- contextLabel.y = 660; // Moved up by 50 pixels (from 710 to 660)
- game.addChild(contextLabel);
- // Add threshold indicators
- var thresholds = [0.25, 0.5, 0.75, 0.9];
- thresholds.forEach(function (threshold) {
- // Create vertical line indicator
- var indicator = new Text2("│", {
- size: 80,
- fill: 0xFF0000
- });
- indicator.anchor.set(0.5, 0.5);
- indicator.x = 224 + 1600 * threshold; // Position based on bar width
- indicator.y = 660; // Match context bar y position
- game.addChild(indicator);
- // Add percentage text
- var percentText = new Text2("".concat(threshold * 100, "%"), {
- size: 35,
- fill: 0xFF0000
- });
- percentText.anchor.set(0.5, 1);
- percentText.x = indicator.x;
- percentText.y = indicator.y - 45; // Position above the indicator line
- game.addChild(percentText);
- });
- // Progress bar background
- var progressBarBg = LK.getAsset('progressBarBg', {
- anchorX: 0,
- anchorY: 0.5,
- x: 224,
- y: 790,
- // Moved down 15% (380 + 2732 * 0.15)
- height: 80 // Doubled height from 40 to 80
- });
- game.addChild(progressBarBg);
- // Progress bar
- progressBar = LK.getAsset('progressBar', {
- anchorX: 0,
- anchorY: 0.5,
- x: 224,
- y: 790,
- // Moved down 15%
- width: 0,
- height: 80 // Doubled height from 40 to 80
- });
- game.addChild(progressBar);
- // Progress bar label
- var progressLabel = new Text2("Project Progress:", {
- size: 45,
- fill: 0xFFFFFF
- });
- progressLabel.anchor.set(0.5, 0.5); // Center anchor
- progressLabel.x = 224 + 1600 / 2; // Center horizontally over the bar
- progressLabel.y = 790; // Moved down 15%
- game.addChild(progressLabel);
- // Day indicator
- dayIndicator = new DayIndicator();
- dayIndicator.x = 1848;
- dayIndicator.y = 200;
- game.addChild(dayIndicator);
- // End day button
- endDayButton = new MenuButton("END DAY", endDay);
- endDayButton.x = 1848;
- endDayButton.y = 400;
- game.addChild(endDayButton);
- // Project area separator
- var separator = new Text2("───────────────────────────────────────────────", {
- size: 55,
- fill: 0xFFFFFF
- });
- separator.anchor.set(0.5, 0.5);
- separator.x = 2048 / 2;
- separator.y = projectAreaY;
+ cursor.x = -700;
+ cursor.y = 300;
+ terminal.addChild(cursor);
+ // Make cursor blink
+ LK.setInterval(function () {
+ cursor.visible = !cursor.visible;
+ }, 500);
+}
+// Create card area
+function createCardArea() {
+ // Create hand container
+ var handContainer = new Container();
+ handContainer.y = 2100; // Position in lower part of screen
+ game.addChild(handContainer);
+ gameState.handContainer = handContainer;
+ // Create separator line
+ var separator = new Sprite();
+ separator.width = 2048;
+ separator.height = 2;
+ separator.color = 0x00ff00;
+ separator.y = 1600;
game.addChild(separator);
- // Project area label
- var projectAreaLabel = new Text2("PROJECT AREA", {
- size: 45,
- fill: 0xFFFFFF
+ // Create hand label
+ var handLabel = new Text2("YOUR PROMPTS", {
+ size: 40,
+ fill: 0x00ff00
});
- projectAreaLabel.anchor.set(0.5, 0);
- projectAreaLabel.x = 2048 / 2;
- projectAreaLabel.y = projectAreaY - 80;
- game.addChild(projectAreaLabel);
- // Features checklist will be added to the vibe display area
- // Hand area label
- var handLabel = new Text2("YOUR HAND", {
- size: 45,
- fill: 0xFFFFFF
- });
- handLabel.anchor.set(0.5, 0);
handLabel.x = 2048 / 2;
- handLabel.y = handY - 280;
+ handLabel.y = 1650;
game.addChild(handLabel);
- // Codebase visualization
- var codebaseContainer = new Container();
- codebaseContainer.x = 2048 / 2;
- codebaseContainer.y = projectAreaY - 200;
- game.addChild(codebaseContainer);
- // [Keep all existing UI creation code here unchanged]
- // Add vibe layer after all existing UI is created
- // Create a top-level vibe container that sits above everything else
- var vibeContainer = new Container();
- game.addChild(vibeContainer); // This puts it on top of existing UI
- // Add vibe background
- var vibeBackground = LK.getAsset('vibebackground', {
+}
+// Card class - simplified from your existing implementation
+function Card(type, promptText, vibePoints, coherenceImpact, bugChance) {
+ var card = new Container();
+ // Card properties
+ card.type = type;
+ card.promptText = promptText;
+ card.vibePoints = vibePoints;
+ card.coherenceImpact = coherenceImpact;
+ card.bugChance = bugChance;
+ // Card visuals
+ var cardAsset;
+ switch (type.toLowerCase()) {
+ case 'ui':
+ cardAsset = 'uicard';
+ break;
+ case 'database':
+ cardAsset = 'databasecard';
+ break;
+ case 'api':
+ cardAsset = 'apicard';
+ break;
+ case 'security':
+ cardAsset = 'securitycard';
+ break;
+ case 'special':
+ cardAsset = 'specialcard';
+ break;
+ default:
+ cardAsset = 'basiccard';
+ }
+ var cardBg = LK.getAsset(cardAsset, {
anchorX: 0.5,
- anchorY: 0.5,
- x: 2048 / 2,
- y: 2732 / 2
+ anchorY: 0.5
});
- vibeContainer.addChild(vibeBackground);
- // Add vibe core in center
- var vibeCore = LK.getAsset('vibecore', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: 2048 / 2,
- y: 2732 / 2 - 200 // Slightly above center
+ card.addChild(cardBg);
+ // Card title
+ var titleText = new Text2(type.toUpperCase(), {
+ size: 40,
+ fill: 0xFFFFFF
});
- vibeContainer.addChild(vibeCore); // Add core first
- // Add particle groups container
- var particleContainer = new Container();
- particleContainer.x = vibeCore.x;
- particleContainer.y = vibeCore.y;
- vibeContainer.addChild(particleContainer); // Add container to hold particles
- // Store references
- gameState.vibeCore = vibeCore;
- gameState.particleContainer = particleContainer;
- gameState.particleGroups = {};
- // Add initial basic particles
- gameState.particleGroups.BASIC = new ParticleGroup('BASIC');
- particleContainer.addChild(gameState.particleGroups.BASIC);
- // Stylized day counter (we can make this more vibe-appropriate later)
- var vibeDayIndicator = new Text2("DAY " + gameState.day, {
- size: 75,
- fill: 0x00ffff // Cyan color for vibe aesthetic
+ titleText.anchor.set(0.5, 0);
+ titleText.y = -250;
+ card.addChild(titleText);
+ // Card prompt text
+ var promptTextObj = new Text2(promptText, {
+ size: 30,
+ fill: 0xFFFFFF,
+ align: 'center',
+ wordWrap: true,
+ wordWrapWidth: 350
});
- vibeDayIndicator.anchor.set(0.5, 0.5);
- vibeDayIndicator.x = 1848;
- vibeDayIndicator.y = 200;
- vibeContainer.addChild(vibeDayIndicator);
- // Stylized end day button
- var vibeEndDayButton = new MenuButton("END DAY", endDay);
- vibeEndDayButton.x = 1848;
- vibeEndDayButton.y = 400;
- vibeEndDayButton.scale.set(1.2); // Make it slightly larger
- vibeContainer.addChild(vibeEndDayButton);
- // Store the container reference in gameState
- gameState.vibeContainer = vibeContainer;
+ promptTextObj.anchor.set(0.5, 0);
+ promptTextObj.y = -180;
+ card.addChild(promptTextObj);
+ // Make card interactive
+ card.interactive = true;
+ card.down = function () {
+ card.scale.set(0.95);
+ };
+ card.up = function () {
+ card.scale.set(1);
+ playCard(card);
+ };
+ return card;
}
-function pulseVibeCore() {
- if (gameState.vibeCore) {
- tween(gameState.vibeCore, {
- scaleX: 1.2,
- scaleY: 1.2
- }, {
- duration: 150,
- onFinish: function onFinish() {
- tween(gameState.vibeCore, {
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 150
- });
- }
- });
- }
-}
-function initializeDeck() {
- // Create a copy of all card templates
- cardDeck = [];
- // Add multiple copies of each card template to the deck
+// Initialize the deck
+function initDeck() {
+ gameState.deck = [];
+ gameState.hand = [];
+ // Add multiple copies of each card template
cardTemplates.forEach(function (template) {
- // Add more basic cards
- var count = template.type === 'basic' ? 3 : template.type === 'refactor' || template.type === 'coffee' || template.type === 'debug' ? 1 : 2;
+ var count = template.type === 'basic' ? 4 : 2; // More basic cards
for (var i = 0; i < count; i++) {
- cardDeck.push(Object.assign({}, template));
+ gameState.deck.push(Object.assign({}, template));
}
});
- // Shuffle the deck
- shuffleDeck(cardDeck);
+ // Shuffle deck
+ shuffleDeck();
}
-function shuffleDeck(deck) {
- for (var i = deck.length - 1; i > 0; i--) {
+// Shuffle the deck
+function shuffleDeck() {
+ for (var i = gameState.deck.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
- var _ref = [deck[j], deck[i]];
- deck[i] = _ref[0];
- deck[j] = _ref[1];
+ var temp = gameState.deck[i];
+ gameState.deck[i] = gameState.deck[j];
+ gameState.deck[j] = temp;
}
}
+// Draw a hand of cards
function drawHand() {
- // Only remove cards from display that aren't in the currentHand anymore
- for (var i = game.children.length - 1; i >= 0; i--) {
- var child = game.children[i];
- if (child instanceof Card && currentHand.indexOf(child) === -1 && gameState.cardStack.indexOf(child) === -1 && !child.isDragging) {
- game.removeChild(child);
- }
+ // Clear existing hand
+ while (gameState.handContainer.children.length > 0) {
+ gameState.handContainer.removeChild(gameState.handContainer.children[0]);
}
- // Check if we need to reshuffle the discard pile
- if (cardDeck.length < HAND_SIZE - currentHand.length && discardPile.length > 0) {
- // Add discard pile back to deck and shuffle
- cardDeck = cardDeck.concat(discardPile);
- discardPile = [];
- shuffleDeck(cardDeck);
- }
- // Draw up to hand size but don't remove current cards
- while (currentHand.length < HAND_SIZE && cardDeck.length > 0) {
- var cardTemplate = cardDeck.pop();
- var card = new Card(cardTemplate.type, cardTemplate.promptText, cardTemplate.codeLines, cardTemplate.vibePoints, cardTemplate.contextImpact, cardTemplate.bugChance);
- // Add feature property if it exists
- if (cardTemplate.feature) {
- card.feature = cardTemplate.feature;
+ gameState.hand = [];
+ // Draw 5 cards
+ for (var i = 0; i < 5; i++) {
+ if (gameState.deck.length > 0) {
+ var template = gameState.deck.pop();
+ var card = new Card(template.type, template.promptText, template.vibePoints, template.coherenceImpact, template.bugChance);
+ gameState.hand.push(card);
+ gameState.handContainer.addChild(card);
}
- currentHand.push(card);
- game.addChild(card);
}
- // Position cards in hand
+ // Position cards
positionCardsInHand();
}
+// Position cards in hand
function positionCardsInHand() {
- var cardWidth = 400;
- var spacing = 60; // Increased spacing further for wider hand
- var overlap = 200; // Keep overlap the same for now
- var centerIndex = Math.floor((currentHand.length - 1) / 2);
- var fanAngle = 0.09; // Slightly increased rotation for wider fan
- // Calculate positions with cards closer to center
- currentHand.forEach(function (card, index) {
- // Calculate distance from center card (0 to n)
- var distanceFromCenter = Math.abs(index - centerIndex);
- // Cards closer to edges move more towards center
- var compressionFactor = distanceFromCenter * 0.35; // Reduced compression strength
- var adjustedSpacing = spacing + overlap * compressionFactor;
- // Calculate x position with compression toward center
- var centerX = 2048 / 2;
- var direction = index < centerIndex ? -1 : 1; // Left or right of center
- if (index === centerIndex) {
- // Center card
- card.x = centerX;
- } else {
- // Side cards with compression
- var positionFromCenter = direction * (cardWidth / 2 + adjustedSpacing * distanceFromCenter);
- card.x = centerX + positionFromCenter;
- }
- card.y = handY + Math.abs(index - (currentHand.length - 1) / 2) * 20; // Arc up in middle
- card.rotation = (index - (currentHand.length - 1) / 2) * fanAngle; // Fan rotation
- // Animate to new positions with tween
- tween(card, {
- x: card.x,
- y: card.y,
- rotation: card.rotation
- }, {
- duration: 300,
- easing: tween.easeOutQuad
- });
- // Update target and original positions
- card.targetX = card.x;
- card.targetY = card.y;
- card.originalX = card.x;
- card.originalY = card.y;
- card.originalRotation = card.rotation;
- card.isDragging = false;
+ var spacing = 420;
+ var handWidth = gameState.hand.length * spacing;
+ var startX = (2048 - handWidth) / 2 + spacing / 2;
+ gameState.hand.forEach(function (card, index) {
+ card.x = startX + index * spacing;
+ card.y = 0;
});
}
-function playCard(card) {
- if (currentHand.indexOf(card) === -1) {
- return;
+// Show concept card selection
+function showConceptCardSelection(category) {
+ // Create selection container
+ var selectionContainer = new Container();
+ selectionContainer.x = 2048 / 2;
+ selectionContainer.y = 2732 / 2;
+ game.addChild(selectionContainer);
+ // Create background
+ var bg = new Sprite();
+ bg.width = 1800;
+ bg.height = 1200;
+ bg.color = 0x000000;
+ bg.alpha = 0.9;
+ selectionContainer.addChild(bg);
+ // Create title
+ var title = new Text2("SELECT " + category.toUpperCase(), {
+ size: 60,
+ fill: 0x00ff00
+ });
+ title.anchor.set(0.5, 0);
+ title.y = -550;
+ selectionContainer.addChild(title);
+ // Get options for this category
+ var options = conceptCardTemplates[category];
+ // Choose 3 random options
+ var selectedOptions = [];
+ while (selectedOptions.length < 3 && options.length > 0) {
+ var index = Math.floor(Math.random() * options.length);
+ selectedOptions.push(options[index]);
+ options.splice(index, 1);
}
- if (gameState.cardsPlayed >= gameState.maxCardsPerDay + gameState.thresholdEffects.maxCardsModifier) {
- // Check adjusted max cards
- card.targetX = card.originalX;
- card.targetY = card.originalY;
- return;
- }
- // Check if player has enough vibe points
- var vibeCost = Math.max(0, -card.vibePoints + gameState.thresholdEffects.vibeCostModifier);
- if (gameState.vibePoints < vibeCost) {
- card.targetX = card.originalX;
- card.targetY = card.originalY;
- return;
- }
- // Add particle group for card type if it doesn't exist or pulse if it does
- var cardType = card.type.toUpperCase();
- var particleType = cardType; // Default to card type
- // Map special card types to the SPECIAL particle group
- if (cardType === 'REFACTOR' || cardType === 'COFFEE' || cardType === 'DEBUG') {
- particleType = 'SPECIAL';
- }
- if (gameState.particleContainer && PARTICLE_TYPES[particleType]) {
- // Ensure container exists and type is valid
- if (!gameState.particleGroups[particleType]) {
- var group = new ParticleGroup(particleType);
- gameState.particleGroups[particleType] = group;
- gameState.particleContainer.addChild(group);
- // Fade in new particles
- group.alpha = 0;
- tween(group, {
- alpha: 1
- }, {
- duration: 500
- });
- } else {
- // Pulse existing particles of this type
- gameState.particleGroups[particleType].pulse();
- }
- }
- // Apply all game state changes
- gameState.vibePoints += card.vibePoints;
- gameState.vibePoints -= vibeCost;
- gameState.codeLines += card.codeLines;
- gameState.contextCollapse += card.contextImpact * gameState.thresholdEffects.contextMultiplier;
- gameState.contextCollapse = Math.max(0, Math.min(gameState.contextCollapse, MAX_CONTEXT_COLLAPSE));
- updateContextThresholdEffects(); //{7P} // Update thresholds *after* context change
- if (card.feature) {
- gameState.features[card.feature] = true;
- }
- LK.getSound('cardPlace').play();
- // Remove from hand
- var index = currentHand.indexOf(card);
- if (index > -1) {
- currentHand.splice(index, 1);
- // Add to discard pile (or create a new object to avoid issues if card is modified)
- discardPile.push({
- type: card.type,
- promptText: card.promptText,
- codeLines: card.codeLines,
- vibePoints: card.vibePoints,
- contextImpact: card.contextImpact,
- bugChance: card.bugChance,
- feature: card.feature
+ // Create option buttons
+ selectedOptions.forEach(function (option, index) {
+ var button = new Button(option, 500, 100, function () {
+ // Set concept card
+ gameState.conceptCards[category] = option;
+ // Update terminal
+ addToTerminalLog("SELECTED " + category.toUpperCase() + ": " + option);
+ updateTerminal();
+ // Remove selection container
+ game.removeChild(selectionContainer);
+ // Add to feature tags
+ updateFeatureTags();
});
- }
- gameState.cardsPlayed++;
- // Animate card being absorbed into core
- tween(card, {
- x: gameState.stackArea.x,
- y: gameState.stackArea.y,
- scaleX: 0.2,
- scaleY: 0.2,
- alpha: 0
- }, {
- duration: 300,
- onFinish: function onFinish() {
- // Don't add the actual card object to stack if it might be destroyed elsewhere
- // Instead, could store a simplified representation if needed, or just handle effects
- // For now, let's assume destroying the card object after animation is fine and stack doesn't need the instance
- // game.removeChild(card); // Remove from stage
- // card.destroy(); // Destroy the card object to free resources
- gameState.cardStack.push({
- type: card.type
- }); // Store simple info instead of the card instance
- if (card && card.parent) {
- // Check if card still exists and is attached before removing/destroying
- game.removeChild(card);
- card.destroy();
- }
- checkForBugs(card.bugChance); // Pass the original chance
- updateStatsDisplay();
- positionCardsInHand();
- if (currentHand.length < HAND_SIZE) {
- drawHand();
- }
- checkGameState();
- }
+ button.x = 0;
+ button.y = -200 + index * 200;
+ selectionContainer.addChild(button);
});
}
-function updateCodebaseVisualization() {
- if (!codebaseContainer) {
+// Button class
+function Button(text, width, height, callback) {
+ var button = new Container();
+ // Button background
+ var bg = new Sprite();
+ bg.width = width;
+ bg.height = height;
+ bg.color = 0x333333;
+ button.addChild(bg);
+ // Button text
+ var textObj = new Text2(text, {
+ size: 30,
+ fill: 0x00ff00
+ });
+ textObj.anchor.set(0.5, 0.5);
+ button.addChild(textObj);
+ // Make button interactive
+ button.interactive = true;
+ button.down = function () {
+ bg.color = 0x555555;
+ };
+ button.up = function () {
+ bg.color = 0x333333;
+ if (callback) {
+ callback();
+ }
+ };
+ return button;
+}
+// Play a card
+function playCard(card) {
+ if (gameState.cardsPlayed >= gameState.maxCardsPerDay) {
+ addToTerminalLog("CANNOT PLAY MORE CARDS TODAY");
return;
}
- // Clear existing visualization
- while (codebaseContainer.children.length > 0) {
- codebaseContainer.removeChild(codebaseContainer.children[0]);
+ // Generate response for this card
+ var response = generateResponse(card);
+ // Apply card effects
+ gameState.vibePoints = Math.max(0, gameState.vibePoints + card.vibePoints);
+ gameState.codeCoherence = Math.max(0, gameState.codeCoherence - card.coherenceImpact);
+ gameState.cardsPlayed++;
+ // Add response to terminal
+ addToTerminalLog("IMPLEMENTING: \"" + card.promptText + "\"");
+ addToTerminalLog(response);
+ // Check for bugs
+ checkForBugs(card);
+ // Remove card from hand
+ var index = gameState.hand.indexOf(card);
+ if (index !== -1) {
+ gameState.hand.splice(index, 1);
+ gameState.handContainer.removeChild(card);
}
- // Calculate how many code blocks to show based on current code lines
- var totalBlocks = Math.min(20, Math.floor(gameState.codeLines / 50));
- // Create blocks
- for (var i = 0; i < totalBlocks; i++) {
- var block = new Container();
- // Create a code block shape
- var blockShape = new Sprite();
- blockShape.width = 50;
- blockShape.height = 30;
- blockShape.color = Math.random() > 0.5 ? 0x4a86e8 : 0x34a853;
- block.addChild(blockShape);
- // Position in a grid or pattern
- block.x = i % 10 * 60 - 270;
- block.y = Math.floor(i / 10) * 40 - 20;
- codebaseContainer.addChild(block);
- }
+ // Update terminal
+ updateTerminal();
+ // Reposition remaining cards
+ positionCardsInHand();
+ // Check game state
+ checkGameState();
}
-// Create a Stack area where cards are played
-function createStackArea() {
- // Create stack container
- var stackContainer = new Container();
- stackContainer.x = 2048 / 2;
- stackContainer.y = projectAreaY - 450;
- // Create background for the stack area using a shape asset
- var stackBg = LK.getAsset('card', {
- anchorX: 0.5,
- anchorY: 0.5,
- width: 450,
- height: 550,
- color: 0x1a1f26,
- // Slightly lighter than background
- alpha: 0 // Set to 0 to hide it
+// Generate response for a card
+function generateResponse(card) {
+ // Determine coherence level
+ var coherenceLevel = getCoherenceLevel();
+ // Get templates for this card type and coherence level
+ var templates = responseTemplates[card.type.toLowerCase()] || responseTemplates.basic;
+ var levelTemplates = templates[coherenceLevel];
+ // Select random template
+ var template = levelTemplates[Math.floor(Math.random() * levelTemplates.length)];
+ // Replace placeholders with concept card values
+ var response = template.replace(/{(\w+)}/g, function (match, term) {
+ return gameState.conceptCards[term] || match;
});
- // stackBg.alpha = 0.5; // Alpha set during creation
- stackContainer.addChild(stackBg);
- // Stack label
- var stackLabel = new Text2("THE STACK", {
- size: 45,
- fill: 0xFFFFFF
- });
- stackLabel.alpha = 0;
- stackLabel.anchor.set(0.5, 0);
- stackLabel.y = -250;
- stackContainer.addChild(stackLabel);
- // Simple border using Text2 with underscores and pipes
- var topBorder = new Text2("┌────────────────────────────┐", {
- size: 30,
- fill: 0x4a86e8
- });
- topBorder.alpha = 0;
- topBorder.anchor.set(0.5, 0.5);
- topBorder.y = -260;
- stackContainer.addChild(topBorder);
- var bottomBorder = new Text2("└────────────────────────────┘", {
- size: 30,
- fill: 0x4a86e8
- });
- bottomBorder.alpha = 0;
- bottomBorder.anchor.set(0.5, 0.5);
- bottomBorder.y = 260;
- stackContainer.addChild(bottomBorder);
- // Side borders
- for (var i = -220; i <= 220; i += 40) {
- var leftBorder = new Text2("│", {
- size: 30,
- fill: 0x4a86e8
- });
- leftBorder.alpha = 0;
- leftBorder.anchor.set(0.5, 0.5);
- leftBorder.x = -225;
- leftBorder.y = i;
- stackContainer.addChild(leftBorder);
- var rightBorder = new Text2("│", {
- size: 30,
- fill: 0x4a86e8
- });
- rightBorder.alpha = 0;
- rightBorder.anchor.set(0.5, 0.5);
- rightBorder.x = 225;
- rightBorder.y = i;
- stackContainer.addChild(rightBorder);
- }
- game.addChild(stackContainer);
- // Add code console on left:
- var codeConsole = new Container();
- codeConsole.alpha = 0; // Set to 0 to hide it
- codeConsole.x = -750 + 2048 * 0.02; // Move right by 2% of screen width
- codeConsole.y = -136 + 2732 * 0.02; // Move down by 2% of screen height
- var consoleBg = LK.getAsset('menuButton', {
- anchorX: 0.5,
- anchorY: 0.5,
- width: 473,
- // Increased by 5% (450 * 1.05)
- height: 688,
- // Increased by 10% (625 * 1.10)
- color: 0x000000,
- alpha: 0.8
- });
- codeConsole.addChild(consoleBg);
- var codeText = new Text2("", {
- size: 30,
- fill: 0x00FF00
- });
- codeText.x = -221; // -180 - (2048 * 0.02)
- codeText.y = -230;
- codeConsole.addChild(codeText);
- // Add blinking cursor
- var cursor = new Text2("_", {
- size: 30,
- fill: 0x00FF00
- });
- cursor.x = codeText.x; // Match updated codeText position
- cursor.y = codeText.y;
- codeConsole.addChild(cursor);
- // Blink cursor
- LK.setInterval(function () {
- cursor.visible = !cursor.visible;
- }, 500);
- stackContainer.addChild(codeConsole);
- // Create code generator and attach to stack area
- var codeGenerator = new CodeGenerator();
- codeGenerator.setTextDisplay(codeText, cursor);
- stackContainer.codeGenerator = codeGenerator;
- // Add vibe points display on right, mirroring the code console position:
- var vibeDisplay = new Container();
- vibeDisplay.alpha = 0; // Set to 0 to hide it
- vibeDisplay.x = 750 - 2048 * 0.02; // Mirror console's horizontal offset from center
- vibeDisplay.y = -136 + 2732 * 0.02; // Match console's vertical offset
- var vibeBg = LK.getAsset('menuButton', {
- anchorX: 0.5,
- anchorY: 0.5,
- width: 473,
- // Match console background width
- height: 688,
- // Match console background height
- color: 0x4a86e8,
- alpha: 0.2
- });
- vibeDisplay.addChild(vibeBg);
- // Add features checklist inside the vibe display
- featuresText = new Text2("Required Features:\n□ UI Framework\n□ Database\n□ API Integration\n□ Security", {
- size: 35,
- // Slightly smaller to fit
- fill: 0xFFFFFF,
- align: 'left',
- wordWrap: true,
- wordWrapWidth: vibeBg.width * 0.9 // Fit within the background
- });
- featuresText.anchor.set(0, 0); // Anchor top-left
- featuresText.x = -vibeBg.width / 2 + 30; // Position inside the vibeBg
- featuresText.y = -vibeBg.height / 2 + 30;
- vibeDisplay.addChild(featuresText);
- stackContainer.addChild(vibeDisplay);
- return stackContainer;
+ return response;
}
-function startBugFix(bug) {
- var gameContainer = new Container();
- gameContainer.x = 2048 / 2;
- gameContainer.y = 2732 / 2;
- game.addChild(gameContainer);
- // Add background panel
- var panel = LK.getAsset('menuButton', {
- width: 800,
- height: 600,
- color: 0x1a1f26,
- anchorX: 0.5,
- anchorY: 0.5
- });
- gameContainer.addChild(panel);
- // Add title
- var title = new Text2(bug instanceof SyntaxBug ? "Fix Syntax Errors!" : "Place Debug Breakpoints!", {
- size: 55,
- fill: 0xFFFFFF
- });
- title.anchor.set(0.5, 0.5);
- title.y = -250;
- gameContainer.addChild(title);
- // Add instructions
- var instructions = new Text2(bug instanceof SyntaxBug ? "Click on the typos in the code to fix them" : "Place exactly 3 breakpoints to catch the bug", {
- size: 35,
- fill: 0xFFFFFF
- });
- instructions.anchor.set(0.5, 0.5);
- instructions.y = -180;
- gameContainer.addChild(instructions);
- if (bug instanceof SyntaxBug) {
- // Syntax bug mini-game with doubled sizes
- var codeLines = ["function brokenCode() {", " reutrn 'Hello World'",
- // Typo
- " cosole.log('Done');",
- // Typo
- "}"];
- // Double the panel size
- panel.width = 1600;
- panel.height = 1200;
- var errorPositions = [[1, 2], [2, 2]]; // Position of errors in code
- var foundErrors = 0;
- // Progress indicator with larger font
- var progress = new Text2("Errors found: 0/2", {
- size: 70,
- // Doubled from 35
- fill: 0xFFFFFF
- });
- progress.anchor.set(0.5, 0.5);
- progress.y = 300; // Doubled from 150
- gameContainer.addChild(progress);
- // Display code with larger font and spacing
- codeLines.forEach(function (line, index) {
- var codeLine = new Text2(line, {
- size: 90,
- // Doubled from 45
- fill: 0xFFFFFF
- });
- codeLine.anchor.set(0, 0);
- codeLine.x = -600; // Doubled from -300
- codeLine.y = index * 100 - 200; // Doubled spacing and offset
- // Make the hit area for the whole line
- var hitArea = new Container();
- // Use a simple shape for hit area, 'menuButton' asset might not be ideal if we want it truly invisible and just for area detection
- var hitBox = LK.getAsset('menuButton', {
- // Using menuButton for simplicity as requested, could be a basic shape too
- width: 1200,
- // Wide enough for the full line
- height: 90,
- // Match text height
- color: 0x000000,
- // Color doesn't matter much if alpha is low
- alpha: 0.01 // Nearly invisible, but still interactive
- });
- hitArea.addChild(hitBox);
- hitArea.x = codeLine.x; // Align hitArea with codeLine visually
- hitArea.y = codeLine.y;
- hitArea.interactive = true;
- hitArea.down = function (x, y, obj) {
- // Calculate character position based on local x within the hit area.
- // 'x' is already the local coordinate relative to the hitArea.
- var localX = x;
- var charPos = Math.floor(localX / 40); // Adjusted char width estimate for size 90 font
- // Check if click is near an error position for the corresponding line index
- var isErrorClick = errorPositions.some(function (pos) {
- return pos[0] === index && Math.abs(pos[1] - charPos) < 2;
- });
- if (isErrorClick && codeLine.fill !== 0x00FF00) {
- // Check the Text2 object's color
- foundErrors++;
- progress.setText("Errors found: ".concat(foundErrors, "/2"));
- codeLine.fill = 0x00FF00; // Change text color to green
- hitArea.interactive = false; // Disable further clicks on this line's hit area
- LK.getSound('cardPlace').play(); // Feedback sound
- if (foundErrors >= errorPositions.length) {
- bugFixSuccess(bug, gameContainer);
- }
- }
- };
- gameContainer.addChild(hitArea); // Add hit area first
- gameContainer.addChild(codeLine); // Add text line on top
- });
- // Adjust title and instructions size and position (modifying existing variables)
- title.size = 110; // Doubled from 55
- title.y = -500; // Doubled from -250
- instructions.size = 70; // Doubled from 35
- instructions.y = -360; // Doubled from -180
- // Adjust close button (modifying existing variable)
- // Note: 'closeButton' is defined later in the function, this modification happens *before* its definition in the original flow.
- // This code needs to be applied *after* closeButton is created.
- // Let's modify the closeButton properties right after its creation instead.
- // --- The modification code for closeButton will be handled in a separate change_block ---
- } else if (bug instanceof LogicBug) {
- // Logic bug mini-game
- var gridSize = 5;
- var grid = new Container();
- var breakpointCount = 0;
- // Progress indicator
- var progress = new Text2("Breakpoints: 0/3", {
- size: 70,
- // Match syntax bug size
- fill: 0xFFFFFF
- });
- progress.anchor.set(0.5, 0.5);
- progress.y = 300; // Match syntax bug position
- gameContainer.addChild(progress);
- for (var i = 0; i < gridSize; i++) {
- for (var j = 0; j < gridSize; j++) {
- var cell = LK.getAsset('menuButton', {
- width: 120,
- // Doubled from 60
- height: 120,
- // Doubled from 60
- color: 0x666666,
- // Lighter gray for inactive cells
- anchorX: 0.5,
- anchorY: 0.5
- });
- cell.x = (i - (gridSize - 1) / 2) * 140; // Doubled spacing from 70, adjusted centering
- cell.y = (j - (gridSize - 1) / 2) * 140; // Doubled spacing from 70, adjusted centering
- cell.interactive = true;
- cell.isBreakpoint = false;
- cell.down = function () {
- if (!this.isBreakpoint) {
- if (breakpointCount < 3) {
- // Ensure we don't exceed 3
- this.color = 0xFF0000; // Changed to red for active breakpoints
- this.isBreakpoint = true;
- breakpointCount++;
- LK.getSound('cardPlace').play();
- }
- } else {
- this.color = 0x666666; // Back to gray when deactivated
- this.isBreakpoint = false;
- breakpointCount--;
- }
- progress.setText("Breakpoints: " + breakpointCount + "/3");
- if (breakpointCount === 3) {
- // Introduce a slight delay before success to see the last breakpoint
- LK.setTimeout(function () {
- bugFixSuccess(bug, gameContainer);
- }, 200);
- }
- };
- grid.addChild(cell);
- }
- }
- // Adjust grid container position slightly if needed to center it within the doubled panel
- grid.y = 50; // You might need to adjust this based on visual testing with the doubled panel size
- gameContainer.addChild(grid);
+// Get coherence level based on current code coherence
+function getCoherenceLevel() {
+ if (gameState.codeCoherence > 70) {
+ return "high";
}
- // Add close button (Give Up)
- var closeButton = new MenuButton("GIVE UP", function () {
- // Add a fade out effect for the mini-game container
- tween(gameContainer, {
- alpha: 0
- }, {
- duration: 300,
- onFinish: function onFinish() {
- if (gameContainer && gameContainer.parent) {
- gameContainer.parent.removeChild(gameContainer);
- gameContainer.destroy();
- }
- }
- });
- });
- // Adjust close button scale and position conditionally for SyntaxBug
- if (bug instanceof SyntaxBug) {
- closeButton.scale.set(1.0); // Doubled from 0.5
- closeButton.x = 600; // Doubled from 300 (Position relative to larger panel)
- closeButton.y = -500; // Doubled from -250 (Align with larger title position)
- } else {
- closeButton.scale.set(0.5); // Keep original scale for LogicBug
- closeButton.x = 300; // Original position
- closeButton.y = -250; // Original position
+ if (gameState.codeCoherence > 30) {
+ return "medium";
}
- gameContainer.addChild(closeButton);
- // Animate the mini-game appearance
- gameContainer.alpha = 0;
- gameContainer.scale.set(0.8);
- tween(gameContainer, {
- alpha: 1,
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 300
- });
+ return "low";
}
-function checkLogicSolution(grid, bug, gameContainer) {
- // Count placed breakpoints
- var breakpoints = 0;
- grid.children.forEach(function (cell) {
- if (cell.color === 0x4A86E8) {
- breakpoints++;
- }
- });
- // Need 3 breakpoints to solve
- if (breakpoints === 3) {
- bugFixSuccess(bug, gameContainer);
+// Add text to terminal log
+function addToTerminalLog(text) {
+ gameState.terminal.log.push(text);
+ // Keep only last 8 entries
+ if (gameState.terminal.log.length > 8) {
+ gameState.terminal.log.shift();
}
}
-function bugFixSuccess(bug, gameContainer) {
- // Remove vibe points cost
- gameState.vibePoints -= bug.vibePointsCost;
- // Remove code lines cost
- gameState.codeLines -= bug.codeLinesCost;
- // Decrement bug count
- gameState.bugs--;
- // Play success sound
- LK.getSound('bugFix').play();
- // Remove bug with effect - check if bug still exists and has a parent
- if (bug && bug.parent) {
- tween(bug, {
- scaleX: 0,
- scaleY: 0,
- alpha: 0
- }, {
- duration: 300,
- onFinish: function onFinish() {
- if (bug && bug.parent) {
- bug.parent.removeChild(bug);
- bug.destroy();
- }
+// Update terminal display
+function updateTerminal() {
+ // Update status line
+ var conceptString = "";
+ for (var category in gameState.conceptCards) {
+ if (gameState.conceptCards[category]) {
+ if (conceptString) {
+ conceptString += " ";
}
- });
- }
- // Remove mini-game
- tween(gameContainer, {
- alpha: 0
- }, {
- duration: 300,
- onFinish: function onFinish() {
- if (gameContainer && gameContainer.parent) {
- gameContainer.parent.removeChild(gameContainer);
- gameContainer.destroy();
- }
+ conceptString += gameState.conceptCards[category];
}
- });
- // Update stats
- updateStatsDisplay();
+ }
+ var statusText = "PROJECT: [" + conceptString + "] | VIBES: " + gameState.vibePoints + "% | COHERENCE: " + gameState.codeCoherence + "% | BUGS: " + gameState.bugs;
+ gameState.statusLineText.setText(statusText);
+ // Update terminal log
+ gameState.logText.setText(gameState.terminal.log.join('\n\n'));
+ // Update feature tags
+ updateFeatureTags();
}
-function checkForBugs(bugChance) {
- // Adjust bug chance based on context collapse and threshold effect
- var adjustedBugChance = bugChance + gameState.contextCollapse / MAX_CONTEXT_COLLAPSE * 0.3 + gameState.thresholdEffects.bugChanceModifier;
- // Special case for debug card
- if (bugChance < 0) {
- // Reduce bugs by a fixed amount
- var bugsToRemove = Math.min(gameState.bugs, Math.abs(Math.floor(bugChance * 10)));
- for (var i = 0; i < bugsToRemove; i++) {
- if (bugContainer.children.length > 0) {
- var bug = bugContainer.children[bugContainer.children.length - 1];
- bugContainer.removeChild(bug);
- bug.destroy();
- }
+// Update feature tags
+function updateFeatureTags() {
+ var tags = [];
+ for (var category in gameState.conceptCards) {
+ if (gameState.conceptCards[category]) {
+ tags.push("#" + gameState.conceptCards[category].replace(/\s+/g, ''));
}
- gameState.bugs -= bugsToRemove;
- return;
}
- // Roll for bug
- if (Math.random() < adjustedBugChance && gameState.bugs < MAX_BUGS) {
- // Show detection sequence first
- showBugDetection();
- // Create either a syntax or logic bug
- var bug = Math.random() < 0.5 ? new SyntaxBug() : new LogicBug();
- // Position randomly in the project area (within bugContainer's space)
- bug.x = Math.random() * 1600 - 800; // -800 to 800 (relative to bugContainer center)
- bug.y = Math.random() * 400 - 200; // -200 to 200 (relative to bugContainer center)
- bugContainer.addChild(bug);
+ gameState.tagsText.setText(tags.join(' '));
+}
+// Check for bugs
+function checkForBugs(card) {
+ var bugChance = card.bugChance * (1 + (100 - gameState.codeCoherence) / 100);
+ if (Math.random() < bugChance) {
gameState.bugs++;
- // Apply bug's effect immediately
- bug.effect();
- // Play bug sound
- LK.getSound('bugAppear').play();
- // Animate bug appearance
- bug.scale.set(0);
- tween(bug, {
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 300
- });
+ // Add bug message to terminal
+ var bugMessages = ["WARNING: Bug detected in " + card.type + " implementation", "ERROR: Unexpected behavior in " + card.promptText, "CRITICAL: System instability increasing", "BUG ALERT: Code coherence affected"];
+ addToTerminalLog(bugMessages[Math.floor(Math.random() * bugMessages.length)]);
}
}
-function updateStatsDisplay() {
- // Create effects text
- var effectsText = "";
- if (gameState.thresholdEffects.bugChanceModifier > 0) {
- effectsText += "\nIncreased Bug Chance!";
- }
- if (gameState.thresholdEffects.maxCardsModifier < 0) {
- effectsText += "\nReduced Cards Per Day!";
- }
- if (gameState.thresholdEffects.contextMultiplier > 1) {
- effectsText += "\nDouble Context Impact!";
- }
- if (gameState.thresholdEffects.vibeCostModifier > 0) {
- effectsText += "\nIncreased Vibe Costs!";
- }
- // Update stats text with effects
- statsText.setText("Code Lines: " + gameState.codeLines + " / " + TARGET_CODE_LINES + "\nVibe Points: " + gameState.vibePoints + "\nBugs: " + gameState.bugs + "/" + MAX_BUGS + "\nCards: " + gameState.cardsPlayed + "/" + Math.max(1, gameState.maxCardsPerDay + gameState.thresholdEffects.maxCardsModifier) + (effectsText ? "\n" + effectsText : ""));
- // Update context bar
- var contextWidth = gameState.contextCollapse / MAX_CONTEXT_COLLAPSE * 1600;
- tween(contextBar, {
- width: contextWidth
- }, {
- duration: 300
- });
- // Update progress bar
- var progressWidth = Math.min(gameState.codeLines / TARGET_CODE_LINES, 1) * 1600;
- tween(progressBar, {
- width: progressWidth
- }, {
- duration: 300
- });
- // Update features checklist text using the global reference
- var featuresStatus = "Required Features:\n" + (gameState.features.ui ? "☑" : "□") + " UI Framework\n" + (gameState.features.database ? "☑" : "□") + " Database\n" + (gameState.features.api ? "☑" : "□") + " API Integration\n" + (gameState.features.security ? "☑" : "□") + " Security";
- if (featuresText) {
- featuresText.setText(featuresStatus);
- }
- updateCodebaseVisualization();
- // [Keep all existing update code]
- // Update vibe day indicator if it exists
- if (gameState.vibeContainer) {
- // Find the day indicator in the vibe container's children
- var vibeDayIndicator = gameState.vibeContainer.children.find(function (child) {
- // Ensure child is Text2 and its text property is a string before calling startsWith
- return child instanceof Text2 && typeof child.text === 'string' && child.text.startsWith("DAY");
- });
- if (vibeDayIndicator) {
- vibeDayIndicator.setText("DAY " + gameState.day);
- }
- }
-}
+// Check game state
function checkGameState() {
- // Update threshold effects first
- updateContextThresholdEffects();
// Check for game over conditions
- if (gameState.bugs >= MAX_BUGS) {
- showGameOver("Too many bugs! Your project crashed!");
+ if (gameState.bugs >= 10) {
+ gameOver("TOO MANY BUGS - PROJECT CRASHED");
return;
}
- if (gameState.contextCollapse >= MAX_CONTEXT_COLLAPSE) {
- showGameOver("Context collapse! Your AI forgot what it was doing!");
+ if (gameState.codeCoherence <= 0) {
+ gameOver("CODE COHERENCE ZERO - AI HALLUCINATING");
return;
}
- // Check if player can play any more cards *this day*
- // Adjust max cards per day based on threshold effect
- var adjustedMaxCards = gameState.maxCardsPerDay + gameState.thresholdEffects.maxCardsModifier;
- var canPlayMoreCardsThisDay = gameState.cardsPlayed < Math.max(1, adjustedMaxCards); // Ensure at least 1 card can be played
- // Update card visual states based on whether they can be played this day
- currentHand.forEach(function (card) {
- if (!canPlayMoreCardsThisDay) {
- // Optional: Add visual indicator that cards can't be played
- card.alpha = 0.7; // Dim the cards
- } else {
- card.alpha = 1.0; // Ensure cards are fully visible if playable
- }
- });
- // Determine if *any* card in hand is playable currently (based on daily limit and having cards)
- var canPlayAnyCardCurrently = false;
- if (canPlayMoreCardsThisDay && currentHand.length > 0) {
- // If within daily limit and hand is not empty, player can potentially play a card.
- // (Add resource checks here if needed in the future)
- canPlayAnyCardCurrently = true;
+ // Check if all cards have been played for this day
+ if (gameState.cardsPlayed >= gameState.maxCardsPerDay) {
+ addToTerminalLog("DAILY CARD LIMIT REACHED - END DAY TO CONTINUE");
}
- gameState.canPlayCard = canPlayAnyCardCurrently; // Update the global state
- // Check if player needs to end their day automatically (stuck condition)
- // This happens if they *cannot* play any card currently AND have no way to draw more cards.
- if (!canPlayAnyCardCurrently && cardDeck.length === 0 && discardPile.length === 0) {
- endDay();
- }
}
+// End the day
function endDay() {
- if (gameState.day >= MAX_DAYS) {
- // Final evaluation
+ gameState.day++;
+ if (gameState.day > gameState.maxDays) {
evaluateProject();
- } else {
- // Advance to next day
- gameState.day++;
- dayIndicator.updateDay(gameState.day);
- // Play day change sound
- LK.getSound('dayChange').play();
- // Animate stack cards flying away
- gameState.cardStack.forEach(function (card, index) {
- tween(card, {
- x: 2048 + 300,
- y: 300 + index * 30,
- rotation: 0.3,
- alpha: 0
- }, {
- duration: 500,
- delay: index * 50,
- onFinish: function onFinish() {
- game.removeChild(card);
- card.destroy();
- }
- });
- });
- // Clear the stack
- gameState.cardStack = [];
- // Discard current hand
- currentHand.forEach(function (card) {
- discardPile.push({
- type: card.type,
- promptText: card.promptText,
- codeLines: card.codeLines,
- vibePoints: card.vibePoints,
- contextImpact: card.contextImpact,
- bugChance: card.bugChance,
- feature: card.feature
- });
- game.removeChild(card);
- card.destroy();
- });
- currentHand = [];
- // Reset for new day
- gameState.cardsPlayed = 0;
- gameState.contextCollapse = Math.max(0, gameState.contextCollapse - 10);
- // Update threshold effects after reducing context collapse
- updateContextThresholdEffects();
- // Draw new hand
- drawHand();
- // Update stats
- updateStatsDisplay();
+ return;
}
+ // Update day text
+ gameState.dayText.setText("DAY " + gameState.day + "/" + gameState.maxDays);
+ // Reset cards played
+ gameState.cardsPlayed = 0;
+ // Recover some code coherence
+ gameState.codeCoherence = Math.min(100, gameState.codeCoherence + 10);
+ // Draw new hand
+ drawHand();
+ // Add day change to terminal
+ addToTerminalLog("DAY " + gameState.day + " STARTED");
+ updateTerminal();
+ // Check if it's a concept card day
+ var conceptDays = {
+ 1: 'platform',
+ 3: 'visual',
+ 5: 'genre',
+ 7: 'mechanic',
+ 9: 'feature'
+ };
+ if (conceptDays[gameState.day]) {
+ showConceptCardSelection(conceptDays[gameState.day]);
+ }
}
+// Evaluate project at end of game
function evaluateProject() {
- var featureCount = (gameState.features.ui ? 1 : 0) + (gameState.features.database ? 1 : 0) + (gameState.features.api ? 1 : 0) + (gameState.features.security ? 1 : 0);
- var codeProgress = gameState.codeLines / TARGET_CODE_LINES;
- // Calculate score (out of 100)
- var score = codeProgress * 50 + featureCount * 10 + Math.max(0, 10 - gameState.bugs) * 2;
+ // Calculate score based on vibes, features implemented, bugs, coherence
+ var score = gameState.vibePoints * 0.4 + Object.values(gameState.conceptCards).filter(Boolean).length * 10 + (10 - gameState.bugs) * 5 + gameState.codeCoherence * 0.2;
score = Math.round(score);
- // Set the final score
- LK.setScore(score);
+ // Generate review text
+ var reviewText = generateReview(score);
+ // Show game over with review
+ gameOver("PROJECT COMPLETE! SCORE: " + score + "/100\n\n" + reviewText);
+}
+// Generate review text based on game results
+function generateReview(score) {
+ var platform = gameState.conceptCards.platform || "Unknown Platform";
+ var visual = gameState.conceptCards.visual || "Unknown Visual Style";
+ var genre = gameState.conceptCards.genre || "Unknown Genre";
+ var mechanic = gameState.conceptCards.mechanic || "Unknown Mechanic";
+ var feature = gameState.conceptCards.feature || "Unknown Feature";
+ // Create compatibility assessment
+ var compatibility = "surprisingly effective";
+ if (platform === "Smart Watch" && visual === "Realistic" || platform === "Blockchain" && mechanic === "Rhythm") {
+ compatibility = "technically impossible";
+ } else if (platform === "Smart Fridge" && genre === "Horror" || visual === "ASCII" && feature === "Procedural Generation") {
+ compatibility = "bizarrely compelling";
+ }
+ // Generate review based on score
if (score >= 80) {
- showYouWin("Project Success! Score: " + score + "/100");
+ return "GameDev Weekly Review: " + score + "%\n\n" + "The " + platform + " " + genre + " with " + visual + " visuals is a breakthrough hit! " + "The " + mechanic + " mechanics combined with " + feature + " create a " + compatibility + " experience. " + "Despite the odd bug, players can't stop talking about this unique creation.";
} else if (score >= 50) {
- showGameOver("Project Submitted With Issues. Score: " + score + "/100");
+ return "GameDev Weekly Review: " + score + "%\n\n" + "This " + visual + " " + genre + " for " + platform + " is an ambitious mess. " + "The " + mechanic + " system is interesting but poorly implemented, and " + feature + " feels tacked on as an afterthought. This " + compatibility + " combination " + "shows promise but needs serious bug fixing.";
} else {
- showGameOver("Project Failed! Score: " + score + "/100");
+ return "GameDev Weekly Review: " + score + "%\n\n" + "What were they thinking? A " + genre + " game with " + visual + " visuals on " + platform + "?! " + "The " + mechanic + " mechanics are completely broken, and " + feature + " crashes constantly. " + "This " + compatibility + " disaster sets a new standard for technical problems. " + "However, it's so bad it might become a cult classic for ironic enjoyment.";
}
}
-function showYouWin(message) {
- // Show win message
- var messageText = new Text2(message, {
- size: 75,
- fill: 0xFFFFFF
+// Game over
+function gameOver(message) {
+ gameState.state = STATES.GAME_OVER;
+ // Create game over container
+ var gameOverContainer = new Container();
+ gameOverContainer.x = 2048 / 2;
+ gameOverContainer.y = 2732 / 2;
+ game.addChild(gameOverContainer);
+ // Create background
+ var bg = new Sprite();
+ bg.width = 1800;
+ bg.height = 1500;
+ bg.color = 0x000000;
+ bg.alpha = 0.9;
+ gameOverContainer.addChild(bg);
+ // Create game over text
+ var gameOverText = new Text2(message, {
+ size: 40,
+ fill: 0x00ff00,
+ align: 'left',
+ wordWrap: true,
+ wordWrapWidth: 1600
});
- messageText.anchor.set(0.5, 0.5);
- messageText.x = 2048 / 2;
- messageText.y = 2732 / 2 - 100;
- game.addChild(messageText);
- // Add some delay before showing game win
- LK.setTimeout(function () {
- LK.showYouWin();
- }, 2000);
-}
-function showGameOver(message) {
- // Show game over message
- var messageText = new Text2(message, {
- size: 75,
- fill: 0xFFFFFF
+ gameOverText.anchor.set(0.5, 0.5);
+ gameOverContainer.addChild(gameOverText);
+ // Create restart button
+ var restartButton = new Button("NEW PROJECT", 400, 100, function () {
+ initGame();
});
- messageText.anchor.set(0.5, 0.5);
- messageText.x = 2048 / 2;
- messageText.y = 2732 / 2 - 100;
- game.addChild(messageText);
- // Add some delay before showing game over
- LK.setTimeout(function () {
- LK.showGameOver();
- }, 2000);
+ restartButton.y = 600;
+ gameOverContainer.addChild(restartButton);
}
-function showMainMenu() {
- // Clear existing elements
+// Create title screen
+function showTitleScreen() {
+ // Clear screen
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
+ // Set state
+ gameState.state = STATES.TITLE;
// Create background
- var background = LK.getAsset('background', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: 2048 / 2,
- y: 2732 / 2
- });
+ var background = new Sprite();
+ background.width = 2048;
+ background.height = 2732;
+ background.color = 0x000000;
game.addChild(background);
- // Title
- var titleText = new Text2("VIBE CODER", {
- size: 135,
- fill: 0xFFFFFF
+ // Create title
+ var title = new Text2("VIBE CODER", {
+ size: 120,
+ fill: 0x00ff00
});
- titleText.anchor.set(0.5, 0.5);
- titleText.x = 2048 / 2;
- titleText.y = 600;
- game.addChild(titleText);
- // Subtitle
- var subtitleText = new Text2("The AI Coding Simulator", {
- size: 75,
- fill: 0x4A86E8
+ title.x = 2048 / 2;
+ title.y = 800;
+ game.addChild(title);
+ // Create subtitle
+ var subtitle = new Text2("The AI Coding Simulator", {
+ size: 60,
+ fill: 0x00ff00
});
- subtitleText.anchor.set(0.5, 0.5);
- subtitleText.x = 2048 / 2;
- subtitleText.y = 700;
- game.addChild(subtitleText);
- // Description
- var descText = new Text2("Build a project in 10 days using vague AI prompts.\nBalance code lines, vibe points, and technical debt.\nAvoid bugs and context collapse!", {
- size: 55,
- fill: 0xFFFFFF
+ subtitle.x = 2048 / 2;
+ subtitle.y = 900;
+ game.addChild(subtitle);
+ // Create start button
+ var startButton = new Button("START", 400, 100, function () {
+ initGame();
});
- descText.anchor.set(0.5, 0.5);
- descText.x = 2048 / 2;
- descText.y = 900;
- game.addChild(descText);
- // Start button
- var startButton = new MenuButton("START GAME", initializeGame);
startButton.x = 2048 / 2;
startButton.y = 1200;
game.addChild(startButton);
- // Play music
- LK.playMusic('gameMusic', {
- fade: {
- start: 0,
- end: 0.3,
- duration: 1000
- }
- });
}
+// Start the game
+showTitleScreen();
+// Game update function - called every frame
game.update = function () {
- // Skip updates if game isn't in playing state
- if (gameState.phase !== 'playing') {
+ if (gameState.state !== STATES.PLAYING) {
+ return; // Skip updates if not in playing state
+ }
+ // Update blinking cursor position if needed
+ updateCursorPosition();
+ // Add any other frame-by-frame updates needed
+};
+// Update cursor position based on current terminal text
+function updateCursorPosition() {
+ if (!gameState.logText || !gameState.terminalContainer) {
return;
}
- // Update particles
- if (gameState.particleContainer) {
- var groups = Object.values(gameState.particleGroups);
- for (var i = 0; i < groups.length; i++) {
- groups[i].update();
- }
- }
- // Update all cards for smooth movement
- this.children.forEach(function (child) {
- if (child instanceof Card && child.update) {
- child.update();
- }
+ var cursor = gameState.terminalContainer.children.find(function (child) {
+ return child instanceof Text2 && child.text === "_";
});
- // Can add other game updates here like:
- // - Animations
- // - Visual effects
- // - Game state checks
-};
-// Game drag state
-var dragNode = null;
-var draggedCard = null;
-var dragOffsetX = 0;
-var dragOffsetY = 0;
-var dragStartX = 0;
-var dragStartY = 0;
-// Global move handler
-// Game event handlers
-// In the down handler, modify how the preview mode works:
-game.down = function (x, y, obj) {
- // Reset drag tracking
- dragStartX = x;
- dragStartY = y;
- // Find clicked card
- var clickedCard = null;
- for (var i = 0; i < currentHand.length; i++) {
- var card = currentHand[i];
- var dx = x - card.x;
- var dy = y - card.y;
- if (Math.abs(dx) < 200 && Math.abs(dy) < 250) {
- clickedCard = card;
- break;
- }
+ if (cursor) {
+ // Get last line of text
+ var lines = gameState.terminal.log[gameState.terminal.log.length - 1] || "";
+ var lastLine = lines.split("\n").pop();
+ // Position cursor after the last line
+ var textWidth = lastLine.length * 14; // Approximate width per character
+ cursor.x = -700 + textWidth; // Start position + text width
+ // Calculate y position based on number of lines in log
+ var totalLines = 0;
+ gameState.terminal.log.forEach(function (entry) {
+ totalLines += entry.split("\n").length + 1; // +1 for spacing
+ });
+ cursor.y = -350 + totalLines * 30; // Starting y + line height * lines
}
- if (clickedCard && gameState.phase === 'playing') {
- draggedCard = clickedCard;
- dragOffsetX = clickedCard.x - x;
- dragOffsetY = clickedCard.y - y;
- // Store original values
- draggedCard.originalX = draggedCard.x;
- draggedCard.originalY = draggedCard.y;
- // Set up preview timer
- draggedCard.holdTimer = LK.setTimeout(function () {
- // Only preview if we haven't moved much from start position
- var dx = x - dragStartX;
- var dy = y - dragStartY;
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (!draggedCard.isDragging && distance < 10) {
- // Set preview mode
- draggedCard.previewMode = true;
- // Move card up by a fixed amount
- var previewY = draggedCard.originalY - 600;
- // Apply scale and move up in same tween
- tween(draggedCard, {
- scaleX: draggedCard.previewScale,
- scaleY: draggedCard.previewScale,
- y: previewY
- }, {
- duration: 300
- });
- // Bring to front
- game.setChildIndex(draggedCard, game.children.length - 1);
- }
- }, draggedCard.holdDuration);
- // Set initial target position
- draggedCard.targetX = draggedCard.x;
- draggedCard.targetY = draggedCard.y;
- // Bring to front
- game.setChildIndex(draggedCard, game.children.length - 1);
- }
+}
+// Game touch/click event handlers
+game.down = function (x, y, obj) {
+ // Object-specific handlers will trigger first if clicked
};
-// In the move handler
game.move = function (x, y, obj) {
- if (draggedCard) {
- // Calculate distance moved
- var dx = x - dragStartX;
- var dy = y - dragStartY;
- var distance = Math.sqrt(dx * dx + dy * dy);
- // If we've moved significantly, cancel preview and start drag
- if (distance > 40) {
- // Cancel preview mode and timer
- if (draggedCard.holdTimer) {
- LK.clearTimeout(draggedCard.holdTimer);
- draggedCard.holdTimer = null;
+ // Handle drag operations if needed
+};
+game.up = function (x, y, obj) {
+ // Handle any touch/click releases not caught by objects
+};
+// Add cards to hand with dragging functionality
+function addCardToHand(cardData) {
+ var card = new Card(cardData.type, cardData.promptText, cardData.vibePoints, cardData.coherenceImpact, cardData.bugChance);
+ // Add dragging behavior
+ card.isDragging = false;
+ card.dragOffsetX = 0;
+ card.dragOffsetY = 0;
+ card.originalX = 0;
+ card.originalY = 0;
+ // Override default handlers with drag functionality
+ card.down = function (x, y) {
+ this.isDragging = true;
+ this.dragOffsetX = this.x - x;
+ this.dragOffsetY = this.y - y;
+ this.originalX = this.x;
+ this.originalY = this.y;
+ // Bring to front
+ if (this.parent) {
+ this.parent.setChildIndex(this, this.parent.children.length - 1);
+ }
+ // Visual feedback
+ this.scale.set(1.1);
+ };
+ card.move = function (x, y) {
+ if (this.isDragging) {
+ this.x = x + this.dragOffsetX;
+ this.y = y + this.dragOffsetY;
+ }
+ };
+ card.up = function (x, y) {
+ this.isDragging = false;
+ this.scale.set(1);
+ // Check if dropped on terminal
+ var terminalBounds = {
+ x: gameState.terminalContainer.x - 800,
+ y: gameState.terminalContainer.y - 500,
+ width: 1600,
+ height: 1000
+ };
+ if (x > terminalBounds.x && x < terminalBounds.x + terminalBounds.width && y > terminalBounds.y && y < terminalBounds.y + terminalBounds.height) {
+ // Card dropped on terminal
+ playCard(this);
+ } else {
+ // Return to original position
+ this.x = this.originalX;
+ this.y = this.originalY;
+ }
+ };
+ gameState.hand.push(card);
+ gameState.handContainer.addChild(card);
+ return card;
+}
+// More detailed implementation of card drawing
+// Enhanced terminal text handling with typing effect
+function addToTerminalLogWithEffect(text) {
+ // Store the text to be added
+ var typingState = {
+ fullText: text,
+ currentPosition: 0,
+ typingSpeed: 50 // ms per character
+ };
+ // Save reference to typing state
+ gameState.currentTyping = typingState;
+ // Add empty string to log first
+ gameState.terminal.log.push("");
+ // Start typing effect
+ typeNextCharacter();
+ function typeNextCharacter() {
+ if (!typingState.fullText || !gameState.terminal) {
+ return;
+ }
+ if (typingState.currentPosition < typingState.fullText.length) {
+ // Get current log text
+ var logEntry = gameState.terminal.log[gameState.terminal.log.length - 1];
+ // Add next character
+ logEntry += typingState.fullText[typingState.currentPosition];
+ // Update log
+ gameState.terminal.log[gameState.terminal.log.length - 1] = logEntry;
+ // Update display
+ updateTerminal();
+ // Increment position
+ typingState.currentPosition++;
+ // Schedule next character
+ LK.setTimeout(typeNextCharacter, typingState.typingSpeed);
+ } else {
+ // Typing complete
+ gameState.currentTyping = null;
+ // Keep only last 8 entries
+ if (gameState.terminal.log.length > 8) {
+ gameState.terminal.log.shift();
+ updateTerminal();
}
- // If in preview mode, exit it first with a tween
- if (draggedCard.previewMode) {
- draggedCard.previewMode = false;
- tween(draggedCard, {
- scaleX: 1,
- scaleY: 1,
- y: draggedCard.originalY // Return to original Y while scaling down
+ }
+ }
+}
+// Enhanced version of playCard with visual effects
+// Enhanced day transition with effects
+function endDayWithEffects() {
+ // Animate day transition
+ var dayTransition = new Text2("END OF DAY " + gameState.day, {
+ size: 80,
+ fill: 0x00ff00
+ });
+ dayTransition.x = 2048 / 2;
+ dayTransition.y = 2732 / 2;
+ dayTransition.alpha = 0;
+ game.addChild(dayTransition);
+ // Fade in
+ tween(dayTransition, {
+ alpha: 1
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ // Hold for a moment
+ LK.setTimeout(function () {
+ // Fade out
+ tween(dayTransition, {
+ alpha: 0
}, {
- duration: 150,
+ duration: 500,
onFinish: function onFinish() {
- // Only start dragging after scale tween completes
- draggedCard.isDragging = true;
- // Update position after scale reset
- draggedCard.x = x + dragOffsetX;
- draggedCard.y = y + dragOffsetY;
- draggedCard.targetX = draggedCard.x;
- draggedCard.targetY = draggedCard.y;
+ game.removeChild(dayTransition);
+ // Proceed with day end
+ gameState.day++;
+ if (gameState.day > gameState.maxDays) {
+ evaluateProject();
+ return;
+ }
+ // Update day text
+ gameState.dayText.setText("DAY " + gameState.day + "/" + gameState.maxDays);
+ // Reset cards played
+ gameState.cardsPlayed = 0;
+ // Recover some code coherence
+ gameState.codeCoherence = Math.min(100, gameState.codeCoherence + 10);
+ // Draw new hand
+ drawHand();
+ // Add day change to terminal
+ addToTerminalLogWithEffect("DAY " + gameState.day + " STARTED");
+ updateTerminal();
+ // Check if it's a concept card day
+ var conceptDays = {
+ 1: 'platform',
+ 3: 'visual',
+ 5: 'genre',
+ 7: 'mechanic',
+ 9: 'feature'
+ };
+ if (conceptDays[gameState.day]) {
+ LK.setTimeout(function () {
+ showConceptCardSelection(conceptDays[gameState.day]);
+ }, 500);
+ }
}
});
- return; // Exit early while transitioning from preview
- }
- // Normal drag handling if not in preview mode
- if (!draggedCard.isDragging) {
- draggedCard.isDragging = true;
- }
- // Direct 1:1 movement - set actual position, not just target
- draggedCard.x = x + dragOffsetX;
- draggedCard.y = y + dragOffsetY;
- // Also update target position for consistency
- draggedCard.targetX = draggedCard.x;
- draggedCard.targetY = draggedCard.y;
+ }, 1000);
}
- }
-};
-// In the up handler
-game.up = function (x, y, obj) {
- if (draggedCard) {
- var cardToEndInteraction = draggedCard; // Store reference locally
- // Clear any pending preview timer
- if (cardToEndInteraction.holdTimer) {
- LK.clearTimeout(cardToEndInteraction.holdTimer);
- cardToEndInteraction.holdTimer = null;
- }
- if (cardToEndInteraction.previewMode) {
- // End preview mode - return to original position and scale
- tween(cardToEndInteraction, {
- scaleX: 1,
- scaleY: 1,
- y: cardToEndInteraction.originalY
+ });
+}
+// Launch Screen special effect
+function showLaunchScreen() {
+ // Black overlay
+ var overlay = new Sprite();
+ overlay.width = 2048;
+ overlay.height = 2732;
+ overlay.color = 0x000000;
+ game.addChild(overlay);
+ // "Booting up" text
+ var bootText = new Text2("BOOTING VIBE CODER OS v1.0...", {
+ size: 40,
+ fill: 0x00ff00
+ });
+ bootText.x = 2048 / 2;
+ bootText.y = 2732 / 2;
+ game.addChild(bootText);
+ // Simulate boot sequence
+ LK.setTimeout(function () {
+ bootText.setText(bootText.text + "\nINITIALIZING TERMINAL...");
+ LK.setTimeout(function () {
+ bootText.setText(bootText.text + "\nLOADING VIBE DATABASE...");
+ LK.setTimeout(function () {
+ bootText.setText(bootText.text + "\nCONNECTING TO AI SUBSYSTEMS...");
+ LK.setTimeout(function () {
+ bootText.setText(bootText.text + "\nREADY!");
+ LK.setTimeout(function () {
+ // Fade out
+ tween(overlay, {
+ alpha: 0
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ game.removeChild(overlay);
+ game.removeChild(bootText);
+ // Show the title screen
+ showTitleScreen();
+ }
+ });
+ }, 800);
+ }, 800);
+ }, 800);
+ }, 800);
+ }, 800);
+}
+// Enhanced game initialization with intro sequence
+function initGameWithIntro() {
+ // Reset game state
+ gameState = {
+ state: STATES.PLAYING,
+ day: 1,
+ maxDays: 10,
+ vibePoints: 100,
+ codeCoherence: 100,
+ bugs: 0,
+ cardsPlayed: 0,
+ maxCardsPerDay: 3,
+ projectDescription: "New Project",
+ conceptCards: {
+ platform: null,
+ visual: null,
+ genre: null,
+ mechanic: null,
+ feature: null
+ },
+ terminal: {
+ log: [],
+ statusLine: "",
+ currentTask: "Awaiting first prompt",
+ featureTags: []
+ },
+ deck: [],
+ hand: []
+ };
+ // Clear screen with fade effect
+ var fadeOverlay = new Sprite();
+ fadeOverlay.width = 2048;
+ fadeOverlay.height = 2732;
+ fadeOverlay.color = 0x000000;
+ fadeOverlay.alpha = 0;
+ game.addChild(fadeOverlay);
+ // Fade to black
+ tween(fadeOverlay, {
+ alpha: 1
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ // Clear screen
+ while (game.children.length > 0) {
+ game.removeChild(game.children[0]);
+ }
+ // Create main interface
+ createInterface();
+ // Initialize deck and draw cards
+ initDeck();
+ drawHand();
+ // Add initial terminal messages
+ addToTerminalLogWithEffect("VIBE CODER OS v1.0 INITIALIZED");
+ LK.setTimeout(function () {
+ addToTerminalLogWithEffect("NEW PROJECT CREATED");
+ LK.setTimeout(function () {
+ addToTerminalLogWithEffect("AWAITING CONCEPT SELECTION...");
+ updateTerminal();
+ // Initialize concept card selection for day 1
+ LK.setTimeout(function () {
+ showConceptCardSelection('platform');
+ }, 500);
+ }, 1000);
+ }, 1000);
+ // Fade from black
+ fadeOverlay.alpha = 1;
+ game.addChild(fadeOverlay);
+ tween(fadeOverlay, {
+ alpha: 0
}, {
- duration: 300,
+ duration: 500,
onFinish: function onFinish() {
- if (cardToEndInteraction) {
- cardToEndInteraction.previewMode = false;
- }
+ game.removeChild(fadeOverlay);
}
});
- cardToEndInteraction.isDragging = false;
- } else if (cardToEndInteraction.isDragging) {
- // Handle card drop
- // Check if card is dropped on the stack area
- var stackAreaX = 2048 / 2;
- var stackAreaY = projectAreaY - 450;
- // Simple rectangular hit testing
- if (Math.abs(x - stackAreaX) < 225 && Math.abs(y - stackAreaY) < 275) {
- // Card dropped on the stack
- playCard(cardToEndInteraction);
- } else {
- // Return card to hand position
- cardToEndInteraction.targetX = cardToEndInteraction.originalX;
- cardToEndInteraction.targetY = cardToEndInteraction.originalY;
- }
- cardToEndInteraction.isDragging = false;
}
- // Nullify the global reference
- draggedCard = null;
- }
-};
-// Initialize with main menu
-showMainMenu();
\ No newline at end of file
+ });
+}
+// Start the application with boot sequence
+showLaunchScreen();
\ No newline at end of file
vibebeat1
Music
vibebeat2
Music
vibebeat3
Music
vibebeat4
Music
vibebeat5
Music
vibebeat6
Music
buttonsound
Sound effect
endday
Sound effect
startsound
Sound effect
bugsquish
Sound effect
conceptbutton
Sound effect
wheelstart
Sound effect
wheelspin
Sound effect
wheelstop
Sound effect
keytype
Sound effect