User prompt
move the threshold effects text to centre on the x axis and move it up 7%
User prompt
update as needed with: // Modify updateStatsDisplay() function: function updateStatsDisplay() { // Create effects text let 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 : "") ); // Rest of function remains the same... }
User prompt
update as needed with: // Modify checkForBugs() function: 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; // Rest of the function remains the same... } // Modify playCard() function: function playCard(card) { // Check if player has enough vibe points (including threshold cost) const vibeCost = Math.max(0, -card.vibePoints + gameState.thresholdEffects.vibeCostModifier); if (gameState.vibePoints < vibeCost) { // Return card to hand position card.targetX = card.originalX; card.targetY = card.originalY; return; } // Apply context impact with multiplier gameState.contextCollapse += card.contextImpact * gameState.thresholdEffects.contextMultiplier; gameState.contextCollapse = Math.max(0, Math.min(gameState.contextCollapse, MAX_CONTEXT_COLLAPSE)); // Rest of function remains the same... } // Modify checkGameState() function: function checkGameState() { // Update threshold effects updateContextThresholdEffects(); // Adjust max cards per day based on threshold effect const adjustedMaxCards = gameState.maxCardsPerDay + gameState.thresholdEffects.maxCardsModifier; const canPlayMoreCardsThisDay = gameState.cardsPlayed < Math.max(1, adjustedMaxCards); // Rest of function remains the same... }
User prompt
update as needed with: // Add to gameState initialization: gameState.thresholdEffects = { bugChanceModifier: 0, maxCardsModifier: 0, contextMultiplier: 1, vibeCostModifier: 0 }; // New function to check and apply threshold effects function updateContextThresholdEffects() { // Reset modifiers gameState.thresholdEffects = { bugChanceModifier: 0, maxCardsModifier: 0, contextMultiplier: 1, vibeCostModifier: 0 }; const 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; } }
User prompt
update only as needed with: // Inside createUI() function, after creating the context bar: // Add threshold indicators const thresholds = [0.25, 0.5, 0.75, 0.9]; thresholds.forEach(threshold => { // Create vertical line indicator const 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 const percentText = new Text2(`${threshold * 100}%`, { size: 35, fill: 0xFF0000 }); percentText.anchor.set(0.5, 1); percentText.x = indicator.x; percentText.y = indicator.y - 45; game.addChild(percentText); });
Code edit (1 edits merged)
Please save this source code
User prompt
Center the labels for both meters to the center of the meters.
User prompt
Move the context collapse meter up by 50 pixels.
User prompt
Double the height of both of the meters
Code edit (1 edits merged)
Please save this source code
User prompt
Update as needed with: 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 > 10) { // Cancel preview mode and timer if (draggedCard.holdTimer) { LK.clearTimeout(draggedCard.holdTimer); draggedCard.holdTimer = null; } // If in preview mode, exit it first with a tween if (draggedCard.previewMode) { draggedCard.previewMode = false; tween(draggedCard, { scaleX: 1, scaleY: 1 }, { duration: 150, onFinish: function() { // 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; } }); return; // Exit early while transitioning from preview } // Normal drag handling if not in preview mode if (!draggedCard.isDragging) { draggedCard.isDragging = true; } draggedCard.x = x + dragOffsetX; draggedCard.y = y + dragOffsetY; draggedCard.targetX = draggedCard.x; draggedCard.targetY = draggedCard.y; } } }; ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Move the required features display into the vibe window.
User prompt
Move the context collapse meter and project meter down by 15%
User prompt
Change the size and coordinates of the window on the right to mirror the console window.
User prompt
Move the code line counter display from the top of the screen to centered underneath the console window.
User prompt
Move the code line counter display under the console window.
User prompt
Move the placement of the cursor in the console window left by 2% and move code animation location to match.
User prompt
Increase the height of the console window by 10% and the width by 5%
User prompt
Increase the speed of the coding animation.
User prompt
Create an animation to generate pseudo code in the console window whenever a card with code lines is played. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Move the console right by 2% and down by 2%
User prompt
Move the console left by 5% and up by 5%
User prompt
Make the console thinner by 10%
User prompt
Move the console left by 5%
User prompt
Increase the size of the console by 25% and move it left by 10a%
/**** * Plugins ****/ 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) { // Fix bug gameState.codeLines -= self.codeLinesCost; gameState.vibePoints -= self.vibePointsCost; gameState.bugs--; LK.getSound('bugFix').play(); updateStatsDisplay(); // Remove bug with effect tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.parent.removeChild(self); self.destroy(); } }); } }; 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; // Card background var cardBg = self.attachAsset('card', { anchorX: 0.5, anchorY: 0.5 }); // Card text self.titleText = new Text2(self.type.toUpperCase(), { size: 55, fill: 0x000000 }); 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: 0x000000 }); 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: 0x000000 }); 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1e2329 }); /**** * 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; // Game state variables var gameState = { day: 1, codeLines: 0, vibePoints: 5, contextCollapse: 0, cardsPlayed: 0, maxCardsPerDay: 3, bugs: 0, phase: 'menu', // 'menu', 'playing', 'dayEnd', 'gameOver' canPlayCard: true, features: { ui: false, database: false, api: false, security: false }, thresholdEffects: { bugChanceModifier: 0, maxCardsModifier: 0, contextMultiplier: 1, vibeCostModifier: 0 } }; // 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 var cardTemplates = [ // Basic cards { type: 'basic', promptText: "Make it work like that app, you know the one", codeLines: 15, vibePoints: 1, contextImpact: 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 }, // UI cards { type: 'UI', promptText: "Make it look like Apple but not too much", codeLines: 30, vibePoints: 3, contextImpact: 10, bugChance: 0.2, feature: 'ui' }, { type: 'UI', promptText: "I want that Material Design vibe but more flat", codeLines: 35, vibePoints: 3, contextImpact: 12, bugChance: 0.3, feature: 'ui' }, // Database cards { type: 'Database', promptText: "Store stuff efficiently, you know?", codeLines: 40, vibePoints: 4, contextImpact: 15, bugChance: 0.3, feature: 'database' }, { 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() { gameState = { day: 1, codeLines: 0, vibePoints: 5, contextCollapse: 0, bugs: 0, cardsPlayed: 0, maxCardsPerDay: 3, phase: 'playing', canPlayCard: true, features: { ui: false, database: false, api: false, security: false }, thresholdEffects: { // Initialize here as well bugChanceModifier: 0, maxCardsModifier: 0, contextMultiplier: 1, vibeCostModifier: 0 }, cardStack: [] // Initialize empty card stack }; // 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 drawHand(); // Update stats display updateStatsDisplay(); // Play background music LK.playMusic('gameMusic'); } // 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 createUI() { // Stats display statsText = new Text2("Code Lines: 0 / " + TARGET_CODE_LINES + "\nVibe Points: 5\nBugs: 0/" + MAX_BUGS, { size: 55, fill: 0xFFFFFF }); 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 }); 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 }); 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 }); 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; game.addChild(separator); // Project area label var projectAreaLabel = new Text2("PROJECT AREA", { size: 45, fill: 0xFFFFFF }); 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; game.addChild(handLabel); // Codebase visualization var codebaseContainer = new Container(); codebaseContainer.x = 2048 / 2; codebaseContainer.y = projectAreaY - 200; game.addChild(codebaseContainer); } function initializeDeck() { // Create a copy of all card templates cardDeck = []; // Add multiple copies of each card template to the deck 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; for (var i = 0; i < count; i++) { cardDeck.push(Object.assign({}, template)); } }); // Shuffle the deck shuffleDeck(cardDeck); } function shuffleDeck(deck) { for (var i = 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]; } } 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); } } // 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; } currentHand.push(card); game.addChild(card); } // Position cards in hand positionCardsInHand(); } 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; }); } function playCard(card) { if (currentHand.indexOf(card) === -1) { return; } if (gameState.cardsPlayed >= gameState.maxCardsPerDay) { // Return card to hand position card.targetX = card.originalX; card.targetY = card.originalY; return; } // Check if player has enough vibe points (including threshold cost) var vibeCost = Math.max(0, -card.vibePoints + gameState.thresholdEffects.vibeCostModifier); // Vibe points are added, so cost is the negative value if (gameState.vibePoints < vibeCost) { // Return card to hand position card.targetX = card.originalX; card.targetY = card.originalY; return; } // Apply all game state changes gameState.vibePoints += card.vibePoints; // Still apply the card's base points gameState.vibePoints -= vibeCost; // Deduct the calculated cost (handles modifier) gameState.codeLines += card.codeLines; // Apply context impact with multiplier gameState.contextCollapse += card.contextImpact * gameState.thresholdEffects.contextMultiplier; gameState.contextCollapse = Math.max(0, Math.min(gameState.contextCollapse, MAX_CONTEXT_COLLAPSE)); if (card.feature) { gameState.features[card.feature] = true; } LK.getSound('cardPlace').play(); // Generate code in console when a card with code lines is played if (card.codeLines > 0 && gameState.stackArea && gameState.stackArea.codeGenerator) { // Animate console to highlight it var consoleBg = gameState.stackArea.children[0].children[0]; tween(consoleBg, { alpha: 1.0, scaleX: 1.05, scaleY: 1.05 }, { duration: 300, onFinish: function onFinish() { tween(consoleBg, { alpha: 0.8, scaleX: 1.0, scaleY: 1.0 }, { duration: 300 }); } }); // Generate code based on card type gameState.stackArea.codeGenerator.generateCodeFromCard(card); } // Remove from hand var index = currentHand.indexOf(card); if (index > -1) { currentHand.splice(index, 1); // Add to discard pile data (but keep the card visual) discardPile.push({ type: card.type, promptText: card.promptText, codeLines: card.codeLines, vibePoints: card.vibePoints, contextImpact: card.contextImpact, bugChance: card.bugChance, feature: card.feature }); } gameState.cardsPlayed++; // Position the card in the stack with slight offset based on stack size var stackPosition = gameState.cardStack.length; var offsetX = stackPosition * 5 - 10; // Small horizontal offset var offsetY = stackPosition * -10; // Stack cards upward // Animate card to stack position tween(card, { x: gameState.stackArea.x + offsetX, y: gameState.stackArea.y + offsetY, scaleX: 0.8, scaleY: 0.8 }, { duration: 300, onFinish: function onFinish() { // Add to stack AFTER animation completes gameState.cardStack.push(card); checkForBugs(card.bugChance); updateStatsDisplay(); positionCardsInHand(); if (currentHand.length < HAND_SIZE) { drawHand(); } checkGameState(); } }); } function updateCodebaseVisualization() { if (!codebaseContainer) { return; } // Clear existing visualization while (codebaseContainer.children.length > 0) { codebaseContainer.removeChild(codebaseContainer.children[0]); } // 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); } } // 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 }); stackBg.alpha = 0.5; stackContainer.addChild(stackBg); // Stack label var stackLabel = new Text2("THE STACK", { size: 45, fill: 0xFFFFFF }); 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.anchor.set(0.5, 0.5); topBorder.y = -260; stackContainer.addChild(topBorder); var bottomBorder = new Text2("└────────────────────────────┘", { size: 30, fill: 0x4a86e8 }); 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.anchor.set(0.5, 0.5); leftBorder.x = -225; leftBorder.y = i; stackContainer.addChild(leftBorder); var rightBorder = new Text2("│", { size: 30, fill: 0x4a86e8 }); 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.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.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; } 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(); } } gameState.bugs -= bugsToRemove; return; } // Roll for bug if (Math.random() < adjustedBugChance && gameState.bugs < MAX_BUGS) { // Create a new bug var bug = new Bug(); // Position randomly in the project area bug.x = Math.random() * 1600 - 800; // -800 to 800 bug.y = Math.random() * 400 - 200; // -200 to 200 bugContainer.addChild(bug); gameState.bugs++; // Play bug sound LK.getSound('bugAppear').play(); // Animate bug appearance bug.scale.set(0); tween(bug, { scaleX: 1, scaleY: 1 }, { duration: 300 }); } } function updateStatsDisplay() { // Update stats text statsText.setText("Code Lines: " + gameState.codeLines + " / " + TARGET_CODE_LINES + "\nVibe Points: " + gameState.vibePoints + "\nBugs: " + gameState.bugs + "/" + MAX_BUGS + "\nCards: " + gameState.cardsPlayed + "/" + gameState.maxCardsPerDay); // 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(); } function checkGameState() { // Update threshold effects first updateContextThresholdEffects(); // Check for game over conditions if (gameState.bugs >= MAX_BUGS) { showGameOver("Too many bugs! Your project crashed!"); return; } if (gameState.contextCollapse >= MAX_CONTEXT_COLLAPSE) { showGameOver("Context collapse! Your AI forgot what it was doing!"); 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; } 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(); } } function endDay() { if (gameState.day >= MAX_DAYS) { // Final evaluation 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); // Draw new hand drawHand(); // Update stats updateStatsDisplay(); } } 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; score = Math.round(score); // Set the final score LK.setScore(score); if (score >= 80) { showYouWin("Project Success! Score: " + score + "/100"); } else if (score >= 50) { showGameOver("Project Submitted With Issues. Score: " + score + "/100"); } else { showGameOver("Project Failed! Score: " + score + "/100"); } } function showYouWin(message) { // Show win message var messageText = new Text2(message, { size: 75, fill: 0xFFFFFF }); 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 }); 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); } function showMainMenu() { // Clear existing elements while (game.children.length > 0) { game.removeChild(game.children[0]); } // Create background var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(background); // Title var titleText = new Text2("VIBE CODER", { size: 135, fill: 0xFFFFFF }); 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 }); 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 }); 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 } }); } game.update = function () { // Skip updates if game isn't in playing state if (gameState.phase !== 'playing') { return; } // Update all cards for smooth movement this.children.forEach(function (child) { if (child instanceof Card && child.update) { child.update(); } }); // 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 (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); } }; // 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; } // 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 }, { duration: 150, 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; } }); 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; } } }; // 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 }, { duration: 300, onFinish: function onFinish() { if (cardToEndInteraction) { cardToEndInteraction.previewMode = false; } } }); 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();
===================================================================
--- original.js
+++ change.js
@@ -818,12 +818,22 @@
card.targetX = card.originalX;
card.targetY = card.originalY;
return;
}
+ // Check if player has enough vibe points (including threshold cost)
+ var vibeCost = Math.max(0, -card.vibePoints + gameState.thresholdEffects.vibeCostModifier); // Vibe points are added, so cost is the negative value
+ if (gameState.vibePoints < vibeCost) {
+ // Return card to hand position
+ card.targetX = card.originalX;
+ card.targetY = card.originalY;
+ return;
+ }
// Apply all game state changes
- gameState.vibePoints += card.vibePoints;
+ gameState.vibePoints += card.vibePoints; // Still apply the card's base points
+ gameState.vibePoints -= vibeCost; // Deduct the calculated cost (handles modifier)
gameState.codeLines += card.codeLines;
- gameState.contextCollapse += card.contextImpact;
+ // Apply context impact with multiplier
+ gameState.contextCollapse += card.contextImpact * gameState.thresholdEffects.contextMultiplier;
gameState.contextCollapse = Math.max(0, Math.min(gameState.contextCollapse, MAX_CONTEXT_COLLAPSE));
if (card.feature) {
gameState.features[card.feature] = true;
}
@@ -1046,10 +1056,10 @@
stackContainer.addChild(vibeDisplay);
return stackContainer;
}
function checkForBugs(bugChance) {
- // Adjust bug chance based on context collapse
- var adjustedBugChance = bugChance + gameState.contextCollapse / MAX_CONTEXT_COLLAPSE * 0.3;
+ // 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)));
@@ -1108,8 +1118,10 @@
}
updateCodebaseVisualization();
}
function checkGameState() {
+ // Update threshold effects first
+ updateContextThresholdEffects();
// Check for game over conditions
if (gameState.bugs >= MAX_BUGS) {
showGameOver("Too many bugs! Your project crashed!");
return;
@@ -1118,9 +1130,11 @@
showGameOver("Context collapse! Your AI forgot what it was doing!");
return;
}
// Check if player can play any more cards *this day*
- var canPlayMoreCardsThisDay = gameState.cardsPlayed < gameState.maxCardsPerDay;
+ // 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
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