User prompt
Move the console left by 5%
User prompt
Increase the size of the console by 25% and move it left by 10a%
User prompt
Move the project area down 10%
Code edit (1 edits merged)
Please save this source code
User prompt
Move the cards in the hand outwards a bit more. Increase the size of the hand from side to side a bit more.
User prompt
Fan the cards in the hand more.
User prompt
Fan the cards in the outwards a bit more.
Code edit (1 edits merged)
Please save this source code
User prompt
Reduce card overlap a little bit by spreading the hand out a bit.
User prompt
Reduce card overlap by a little bit more.
User prompt
Remove the deck from the UI
User prompt
Reduce the overlap by a little bit.
User prompt
Condense the cards in the hand mote by moving both sides towards the center card with more overlap. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: undefined is not an object (evaluating 'contextBarBg.y = progressBarY')' in or related to this line: 'contextBarBg.y = progressBarY;' Line Number: 454
User prompt
Please fix the bug: 'ReferenceError: Can't find variable: contextBarBg' in or related to this line: 'contextBarBg.y = progressBarY;' Line Number: 450
User prompt
Update with: function createUI() { // Move stats to top right statsText.x = 1700; statsText.y = 50; // Move progress bars to top center var progressBarY = 150; contextBarBg.y = progressBarY; contextBar.y = progressBarY; contextLabel.y = progressBarY; var codeBarY = progressBarY + 60; progressBarBg.y = codeBarY; progressBar.y = codeBarY; progressLabel.y = codeBarY; }
User prompt
Please fix the bug: 'TypeError: undefined is not a constructor (evaluating 'new Sprite()')' in or related to this line: 'var consoleBg = new Sprite();' Line Number: 800
User prompt
Update as needed with: function createStackArea() { // Existing setup code... // Add code console on left: var codeConsole = new Container(); codeConsole.x = -500; // Left side of stack var consoleBg = new Sprite(); consoleBg.width = 400; consoleBg.height = 500; consoleBg.color = 0x000000; consoleBg.alpha = 0.8; codeConsole.addChild(consoleBg); var codeText = new Text2("", { size: 30, fill: 0x00FF00 }); codeText.x = -180; codeText.y = -230; codeConsole.addChild(codeText); // Add blinking cursor var cursor = new Text2("_", { size: 30, fill: 0x00FF00 }); cursor.x = codeText.x; cursor.y = codeText.y; codeConsole.addChild(cursor); // Blink cursor LK.setInterval(function() { cursor.visible = !cursor.visible; }, 500); stackContainer.addChild(codeConsole); // Add vibe points display on right: var vibeDisplay = new Container(); vibeDisplay.x = 500; // Right side of stack var vibeBg = new Sprite(); vibeBg.width = 400; vibeBg.height = 500; vibeBg.color = 0x4a86e8; vibeBg.alpha = 0.2; vibeDisplay.addChild(vibeBg); stackContainer.addChild(vibeDisplay); return stackContainer; }
User prompt
Update with: function positionCardsInHand() { var cardWidth = 400; var spacing = 50; var totalWidth = currentHand.length * cardWidth + (currentHand.length - 1) * spacing; var startX = (2048 - totalWidth) / 2 + cardWidth / 2; var fanAngle = 0.05; // Slight rotation for fan effect currentHand.forEach(function(card, index) { card.x = startX + index * (cardWidth + spacing); 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 card.targetX = card.x; card.targetY = card.y; card.originalX = card.x; card.originalY = card.y; card.originalRotation = card.rotation; card.isDragging = false; }); }
User prompt
Update with: var handY = 2732 - 400;
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
update as needed with: game.up = function (x, y, obj) { if (draggedCard) { var cardToEndInteraction = draggedCard; // Clear pending preview timer as before... if (cardToEndInteraction.previewMode) { // Handle preview mode as before... } else if (cardToEndInteraction.isDragging) { // Check if card is dropped on the stack area var stackAreaX = 2048 / 2; var stackAreaY = projectAreaY - 150; // 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; } };
User prompt
update as needed with: function createUI() { // Existing UI code... // Create the stack area var stackArea = createStackArea(); // Store reference to the stack area for hit testing gameState.stackArea = stackArea; // Rest of existing UI code... }
Code edit (14 edits merged)
Please save this source code
/****
* 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 = 400; // .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 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
}
};
// Card position constants
var projectAreaY = 2732 * 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;
// 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
},
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');
}
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: 300
});
game.addChild(contextBarBg);
// Context collapse bar
contextBar = LK.getAsset('progressBar', {
anchorX: 0,
anchorY: 0.5,
x: 224,
y: 300,
width: 0
});
game.addChild(contextBar);
// Context bar label
var contextLabel = new Text2("Context Collapse:", {
size: 45,
fill: 0xFFFFFF
});
contextLabel.anchor.set(0, 0.5);
contextLabel.x = 150;
contextLabel.y = 300;
game.addChild(contextLabel);
// Progress bar background
var progressBarBg = LK.getAsset('progressBarBg', {
anchorX: 0,
anchorY: 0.5,
x: 224,
y: 380
});
game.addChild(progressBarBg);
// Progress bar
progressBar = LK.getAsset('progressBar', {
anchorX: 0,
anchorY: 0.5,
x: 224,
y: 380,
width: 0
});
game.addChild(progressBar);
// Progress bar label
var progressLabel = new Text2("Project Progress:", {
size: 45,
fill: 0xFFFFFF
});
progressLabel.anchor.set(0, 0.5);
progressLabel.x = 150;
progressLabel.y = 380;
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
var featuresText = new Text2("Required Features:\n□ UI Framework\n□ Database\n□ API Integration\n□ Security", {
size: 45,
fill: 0xFFFFFF
});
featuresText.anchor.set(0, 0);
featuresText.x = 1600;
featuresText.y = 150;
game.addChild(featuresText);
// 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 = 30; // Increased spacing for more spread
var overlap = 200; // Keep overlap the same for now
var centerIndex = Math.floor((currentHand.length - 1) / 2);
var fanAngle = 0.08; // Increased rotation for more fan effect
// 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.25; // 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;
}
// Apply all game state changes
gameState.vibePoints += card.vibePoints;
gameState.codeLines += card.codeLines;
gameState.contextCollapse += card.contextImpact;
gameState.contextCollapse = Math.max(0, Math.min(gameState.contextCollapse, MAX_CONTEXT_COLLAPSE));
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 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 = -500; // Left side of stack
var consoleBg = LK.getAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 500,
color: 0x000000,
alpha: 0.8
});
codeConsole.addChild(consoleBg);
var codeText = new Text2("", {
size: 30,
fill: 0x00FF00
});
codeText.x = -180;
codeText.y = -230;
codeConsole.addChild(codeText);
// Add blinking cursor
var cursor = new Text2("_", {
size: 30,
fill: 0x00FF00
});
cursor.x = codeText.x;
cursor.y = codeText.y;
codeConsole.addChild(cursor);
// Blink cursor
LK.setInterval(function () {
cursor.visible = !cursor.visible;
}, 500);
stackContainer.addChild(codeConsole);
// Add vibe points display on right:
var vibeDisplay = new Container();
vibeDisplay.x = 500; // Right side of stack
var vibeBg = LK.getAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 500,
color: 0x4a86e8,
alpha: 0.2
});
vibeDisplay.addChild(vibeBg);
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;
// 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
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";
// Find and update features text
game.children.forEach(function (child) {
if (child instanceof Text2 && child.getText && typeof child.getText === 'function') {
var text = child.getText();
if (text && text.includes("Required Features")) {
child.setText(featuresStatus);
}
}
});
updateCodebaseVisualization();
}
function checkGameState() {
// 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*
var canPlayMoreCardsThisDay = gameState.cardsPlayed < gameState.maxCardsPerDay;
// 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 > 10) {
// Cancel preview mode and timer
if (draggedCard.holdTimer) {
LK.clearTimeout(draggedCard.holdTimer);
draggedCard.holdTimer = null;
}
// If in preview mode, exit it first
if (draggedCard.previewMode) {
draggedCard.previewMode = false;
draggedCard.scaleX = 1;
draggedCard.scaleY = 1;
}
// Start dragging
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
@@ -584,18 +584,18 @@
positionCardsInHand();
}
function positionCardsInHand() {
var cardWidth = 400;
- var spacing = 30; // Increased spacing for less overlap
- var overlap = 150; // Reduced overlap amount
+ var spacing = 30; // Increased spacing for more spread
+ var overlap = 200; // Keep overlap the same for now
var centerIndex = Math.floor((currentHand.length - 1) / 2);
- var fanAngle = 0.06; // Slight rotation for fan effect (increased slightly)
+ var fanAngle = 0.08; // Increased rotation for more fan effect
// 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.2; // Reduced compression strength
+ var compressionFactor = distanceFromCenter * 0.25; // 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
@@ -606,9 +606,9 @@
// 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) * 25; // Arc up in middle (increased slightly)
+ 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,
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