/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Anomaly = Container.expand(function (type, difficulty) { var self = Container.call(this); self.type = type || 'minor'; self.difficulty = difficulty || 1; self.maxTime = self.type === 'major' ? 8000 : 5000; self.currentTime = self.maxTime; self.isActive = false; self.isCompleted = false; self.isFailed = false; // Visual elements var anomalyGraphic = self.attachAsset(self.type === 'major' ? 'anomalyMajor' : 'anomalyMinor', { anchorX: 0.5, anchorY: 0.5 }); var timerBg = self.attachAsset('timerBarBg', { anchorX: 0.5, anchorY: 0.5, y: 80 }); var timerBar = self.attachAsset('timerBar', { anchorX: 0.5, anchorY: 0.5, y: 80 }); self.timerBar = timerBar; // Timer text self.timerText = new Text2('5.0s', { size: 30, fill: 0xFFFFFF }); self.timerText.anchor.set(0.5, 0.5); self.timerText.y = 110; self.addChild(self.timerText); // Type label self.typeLabel = new Text2(self.type.toUpperCase(), { size: 25, fill: 0xFFFFFF }); self.typeLabel.anchor.set(0.5, 0.5); self.typeLabel.y = -60; self.addChild(self.typeLabel); self.updateTimer = function () { if (!self.isActive || self.isCompleted || self.isFailed) return; self.currentTime -= 16.67; // 60fps if (self.currentTime <= 0) { self.currentTime = 0; self.fail(); return; } var timePercent = self.currentTime / self.maxTime; self.timerBar.scaleX = timePercent; // Color timer based on remaining time if (timePercent > 0.5) { self.timerBar.tint = 0x27ae60; // green } else if (timePercent > 0.25) { self.timerBar.tint = 0xf39c12; // orange } else { self.timerBar.tint = 0xe74c3c; // red } self.timerText.setText((self.currentTime / 1000).toFixed(1) + 's'); }; self.activate = function () { self.isActive = true; anomalyGraphic.tint = 0xffffff; // Flash effect LK.effects.flashObject(anomalyGraphic, 0xffffff, 200); }; self.complete = function () { if (self.isCompleted || self.isFailed) return; self.isCompleted = true; self.isActive = false; anomalyGraphic.tint = 0x27ae60; LK.getSound('anomalySuccess').play(); // Award points var points = self.type === 'major' ? 50 : 25; LK.setScore(LK.getScore() + points); // Fade out tween(self, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; self.fail = function () { if (self.isCompleted || self.isFailed) return; self.isFailed = true; self.isActive = false; anomalyGraphic.tint = 0xe74c3c; LK.getSound('anomalyFail').play(); // Apply debuff if (self.type === 'major') { majorFailures++; temporalCohesion -= 25; } else { minorFailures++; temporalCohesion -= 10; } // Screen flash LK.effects.flashScreen(0xe74c3c, 500); // Fade out tween(self, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; self.down = function (x, y, obj) { if (!self.isActive || self.isCompleted || self.isFailed) return; // Start mini-game self.startMiniGame(); }; self.startMiniGame = function () { // Simple pattern matching mini-game var targetClicks = Math.floor(2 + self.difficulty); var clickCount = 0; var originalScale = anomalyGraphic.scaleX; var pulseInterval = LK.setInterval(function () { tween(anomalyGraphic, { scaleX: originalScale * 1.2, scaleY: originalScale * 1.2 }, { duration: 150, onFinish: function onFinish() { tween(anomalyGraphic, { scaleX: originalScale, scaleY: originalScale }, { duration: 150 }); } }); }, 300); var _clickHandler = function clickHandler(x, y, obj) { if (!self.isActive) return; clickCount++; if (clickCount >= targetClicks) { LK.clearInterval(pulseInterval); self.complete(); game.off('down', _clickHandler); } }; game.on('down', _clickHandler); // Auto-fail after remaining time LK.setTimeout(function () { if (self.isActive && !self.isCompleted) { LK.clearInterval(pulseInterval); game.off('down', _clickHandler); } }, self.currentTime); }; self.update = function () { self.updateTimer(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ var temporalCohesion = 100; var maxTemporalCohesion = 100; var minorFailures = 0; var majorFailures = 0; var activeAnomalies = []; var cyclesSurvived = 0; var anomalySpawnTimer = 0; var cohesionDrainTimer = 0; var gameActive = true; // Tutorial state var tutorialActive = true; var tutorialStep = 0; var tutorialPaused = false; var tutorialAnomaly = null; var tutorialTexts = []; // Central nexus var nexus = game.addChild(LK.getAsset('nexus', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1200 })); // UI Elements var cohesionBarBg = LK.gui.top.addChild(LK.getAsset('cohesionBarBg', { anchorX: 0.5, anchorY: 0, x: LK.gui.top.width / 2, y: 120 })); var cohesionBar = LK.gui.top.addChild(LK.getAsset('cohesionBar', { anchorX: 0.5, anchorY: 0, x: LK.gui.top.width / 2, y: 120 })); var cohesionText = new Text2('Temporal Cohesion: 100%', { size: 40, fill: 0x3498DB }); cohesionText.anchor.set(0.5, 0); cohesionText.x = LK.gui.top.width / 2; cohesionText.y = 50; LK.gui.top.addChild(cohesionText); var cyclesText = new Text2('Cycles: 0', { size: 35, fill: 0xFFFFFF }); cyclesText.anchor.set(0, 0); cyclesText.x = 120; cyclesText.y = 50; LK.gui.top.addChild(cyclesText); var debuffText = new Text2('Debuffs: 0', { size: 35, fill: 0xE74C3C }); debuffText.anchor.set(1, 0); debuffText.x = LK.gui.top.width - 50; debuffText.y = 50; LK.gui.top.addChild(debuffText); // Tutorial UI var tutorialOverlay = new Container(); tutorialOverlay.alpha = 0; LK.gui.center.addChild(tutorialOverlay); var tutorialBox = tutorialOverlay.addChild(LK.getAsset('cohesionBarBg', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 8 })); var tutorialText = new Text2('', { size: 45, fill: 0xFFFFFF, wordWrap: true, wordWrapWidth: 800 }); tutorialText.anchor.set(0.5, 0.5); tutorialOverlay.addChild(tutorialText); var tutorialSkipText = new Text2('Tap anywhere to continue', { size: 35, fill: 0xF39C12 }); tutorialSkipText.anchor.set(0.5, 0.5); tutorialSkipText.y = 150; tutorialOverlay.addChild(tutorialSkipText); function showTutorialStep(step) { if (!tutorialActive) return; var instructions = ["Welcome, Chronomancer!\n\nYou are humanity's last hope against timeline collapse. Reality is fracturing around you.", "This is your Temporal Cohesion meter.\n\nIt represents reality's stability. When it reaches zero, everything ends.", "Temporal Anomalies will appear around you.\n\nEach has a countdown timer. When it reaches zero, the anomaly fails.", "Tap an anomaly to begin fixing it.\n\nYou must click it multiple times while it pulses to succeed.", "You can only work on one anomaly at a time.\n\nOthers will continue counting down while you're busy.", "Failed anomalies damage your Temporal Cohesion.\n\nMajor anomalies (purple) cause more damage than minor ones (orange).", "The game never truly ends in victory.\n\nYour goal is to survive as long as possible and minimize damage.", "Choose wisely, Chronomancer.\n\nSome losses are inevitable. The timeline's fate rests in your hands."]; if (step >= instructions.length) { endTutorial(); return; } tutorialText.setText(instructions[step]); tween(tutorialOverlay, { alpha: 1 }, { duration: 500 }); tutorialPaused = true; } function nextTutorialStep() { if (!tutorialActive || !tutorialPaused) return; tween(tutorialOverlay, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { tutorialStep++; if (tutorialStep === 2) { // Spawn tutorial anomaly after explaining cohesion spawnTutorialAnomaly(); } LK.setTimeout(function () { showTutorialStep(tutorialStep); }, 500); } }); tutorialPaused = false; } function spawnTutorialAnomaly() { if (tutorialAnomaly) return; tutorialAnomaly = new Anomaly('minor', 1); tutorialAnomaly.x = nexus.x + 300; tutorialAnomaly.y = nexus.y - 200; tutorialAnomaly.currentTime = 8000; // Give more time in tutorial tutorialAnomaly.maxTime = 8000; game.addChild(tutorialAnomaly); activeAnomalies.push(tutorialAnomaly); LK.setTimeout(function () { if (tutorialAnomaly && tutorialAnomaly.parent) { tutorialAnomaly.activate(); } }, 1000); } function endTutorial() { tutorialActive = false; tutorialOverlay.alpha = 0; // Clean up tutorial anomaly if (tutorialAnomaly && tutorialAnomaly.parent && !tutorialAnomaly.isCompleted) { tutorialAnomaly.destroy(); for (var i = activeAnomalies.length - 1; i >= 0; i--) { if (activeAnomalies[i] === tutorialAnomaly) { activeAnomalies.splice(i, 1); break; } } } // Start normal game spawnAnomaly(); spawnAnomaly(); } function spawnAnomaly() { if (tutorialActive) return; if (activeAnomalies.length >= 4) return; var type = Math.random() < 0.3 ? 'major' : 'minor'; var anomaly = new Anomaly(type, 1 + Math.floor(cyclesSurvived / 5)); // Position around the nexus var angle = Math.random() * Math.PI * 2; var distance = 400 + Math.random() * 300; anomaly.x = nexus.x + Math.cos(angle) * distance; anomaly.y = nexus.y + Math.sin(angle) * distance; // Ensure anomaly stays within bounds anomaly.x = Math.max(200, Math.min(1848, anomaly.x)); anomaly.y = Math.max(400, Math.min(2332, anomaly.y)); game.addChild(anomaly); activeAnomalies.push(anomaly); // Auto-activate after brief delay LK.setTimeout(function () { if (anomaly.parent) { anomaly.activate(); } }, 500); } function updateUI() { var cohesionPercent = temporalCohesion / maxTemporalCohesion; cohesionBar.scaleX = cohesionPercent; // Color cohesion bar if (cohesionPercent > 0.6) { cohesionBar.tint = 0x3498db; } else if (cohesionPercent > 0.3) { cohesionBar.tint = 0xf39c12; } else { cohesionBar.tint = 0xe74c3c; } cohesionText.setText('Temporal Cohesion: ' + Math.floor(temporalCohesion) + '%'); cyclesText.setText('Cycles: ' + cyclesSurvived); debuffText.setText('Debuffs: ' + (minorFailures + majorFailures)); } function checkGameOver() { if (temporalCohesion <= 0) { gameActive = false; LK.effects.flashScreen(0xe74c3c, 2000); LK.setTimeout(function () { LK.showGameOver(); }, 2000); } } function cleanupAnomalies() { for (var i = activeAnomalies.length - 1; i >= 0; i--) { var anomaly = activeAnomalies[i]; if (anomaly.isCompleted || anomaly.isFailed || !anomaly.parent) { activeAnomalies.splice(i, 1); } } } // Tutorial tap handler game.down = function (x, y, obj) { if (tutorialActive && tutorialPaused) { nextTutorialStep(); return; } }; // Start tutorial LK.setTimeout(function () { showTutorialStep(0); }, 1000); game.update = function () { if (!gameActive) return; // Skip normal game logic during tutorial if (tutorialActive && tutorialStep < 6) { return; } // Spawn anomalies anomalySpawnTimer += 16.67; if (anomalySpawnTimer >= 3000 - cyclesSurvived * 50) { anomalySpawnTimer = 0; spawnAnomaly(); } // Drain cohesion cohesionDrainTimer += 16.67; if (cohesionDrainTimer >= 2000) { cohesionDrainTimer = 0; temporalCohesion -= 1 + minorFailures * 0.5 + majorFailures * 1; if (temporalCohesion < 50 && LK.ticks % 120 === 0) { LK.getSound('cohesionDrain').play(); } } // Tutorial completion check if (tutorialActive && tutorialAnomaly && (tutorialAnomaly.isCompleted || tutorialAnomaly.isFailed)) { if (tutorialStep === 6) { LK.setTimeout(function () { showTutorialStep(7); }, 1500); } } // Update cycle counter var newCycles = Math.floor(LK.ticks / 3600); // Every 60 seconds if (newCycles > cyclesSurvived) { cyclesSurvived = newCycles; LK.setScore(LK.getScore() + 100); } // Nexus pulse effect if (LK.ticks % 60 === 0) { var pulseIntensity = 1 - temporalCohesion / maxTemporalCohesion; if (pulseIntensity > 0.5) { tween(nexus, { scaleX: 1.1, scaleY: 1.1 }, { duration: 300, onFinish: function onFinish() { tween(nexus, { scaleX: 1, scaleY: 1 }, { duration: 300 }); } }); } } cleanupAnomalies(); updateUI(); checkGameOver(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Anomaly = Container.expand(function (type, difficulty) {
var self = Container.call(this);
self.type = type || 'minor';
self.difficulty = difficulty || 1;
self.maxTime = self.type === 'major' ? 8000 : 5000;
self.currentTime = self.maxTime;
self.isActive = false;
self.isCompleted = false;
self.isFailed = false;
// Visual elements
var anomalyGraphic = self.attachAsset(self.type === 'major' ? 'anomalyMajor' : 'anomalyMinor', {
anchorX: 0.5,
anchorY: 0.5
});
var timerBg = self.attachAsset('timerBarBg', {
anchorX: 0.5,
anchorY: 0.5,
y: 80
});
var timerBar = self.attachAsset('timerBar', {
anchorX: 0.5,
anchorY: 0.5,
y: 80
});
self.timerBar = timerBar;
// Timer text
self.timerText = new Text2('5.0s', {
size: 30,
fill: 0xFFFFFF
});
self.timerText.anchor.set(0.5, 0.5);
self.timerText.y = 110;
self.addChild(self.timerText);
// Type label
self.typeLabel = new Text2(self.type.toUpperCase(), {
size: 25,
fill: 0xFFFFFF
});
self.typeLabel.anchor.set(0.5, 0.5);
self.typeLabel.y = -60;
self.addChild(self.typeLabel);
self.updateTimer = function () {
if (!self.isActive || self.isCompleted || self.isFailed) return;
self.currentTime -= 16.67; // 60fps
if (self.currentTime <= 0) {
self.currentTime = 0;
self.fail();
return;
}
var timePercent = self.currentTime / self.maxTime;
self.timerBar.scaleX = timePercent;
// Color timer based on remaining time
if (timePercent > 0.5) {
self.timerBar.tint = 0x27ae60; // green
} else if (timePercent > 0.25) {
self.timerBar.tint = 0xf39c12; // orange
} else {
self.timerBar.tint = 0xe74c3c; // red
}
self.timerText.setText((self.currentTime / 1000).toFixed(1) + 's');
};
self.activate = function () {
self.isActive = true;
anomalyGraphic.tint = 0xffffff;
// Flash effect
LK.effects.flashObject(anomalyGraphic, 0xffffff, 200);
};
self.complete = function () {
if (self.isCompleted || self.isFailed) return;
self.isCompleted = true;
self.isActive = false;
anomalyGraphic.tint = 0x27ae60;
LK.getSound('anomalySuccess').play();
// Award points
var points = self.type === 'major' ? 50 : 25;
LK.setScore(LK.getScore() + points);
// Fade out
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.fail = function () {
if (self.isCompleted || self.isFailed) return;
self.isFailed = true;
self.isActive = false;
anomalyGraphic.tint = 0xe74c3c;
LK.getSound('anomalyFail').play();
// Apply debuff
if (self.type === 'major') {
majorFailures++;
temporalCohesion -= 25;
} else {
minorFailures++;
temporalCohesion -= 10;
}
// Screen flash
LK.effects.flashScreen(0xe74c3c, 500);
// Fade out
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.down = function (x, y, obj) {
if (!self.isActive || self.isCompleted || self.isFailed) return;
// Start mini-game
self.startMiniGame();
};
self.startMiniGame = function () {
// Simple pattern matching mini-game
var targetClicks = Math.floor(2 + self.difficulty);
var clickCount = 0;
var originalScale = anomalyGraphic.scaleX;
var pulseInterval = LK.setInterval(function () {
tween(anomalyGraphic, {
scaleX: originalScale * 1.2,
scaleY: originalScale * 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(anomalyGraphic, {
scaleX: originalScale,
scaleY: originalScale
}, {
duration: 150
});
}
});
}, 300);
var _clickHandler = function clickHandler(x, y, obj) {
if (!self.isActive) return;
clickCount++;
if (clickCount >= targetClicks) {
LK.clearInterval(pulseInterval);
self.complete();
game.off('down', _clickHandler);
}
};
game.on('down', _clickHandler);
// Auto-fail after remaining time
LK.setTimeout(function () {
if (self.isActive && !self.isCompleted) {
LK.clearInterval(pulseInterval);
game.off('down', _clickHandler);
}
}, self.currentTime);
};
self.update = function () {
self.updateTimer();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
var temporalCohesion = 100;
var maxTemporalCohesion = 100;
var minorFailures = 0;
var majorFailures = 0;
var activeAnomalies = [];
var cyclesSurvived = 0;
var anomalySpawnTimer = 0;
var cohesionDrainTimer = 0;
var gameActive = true;
// Tutorial state
var tutorialActive = true;
var tutorialStep = 0;
var tutorialPaused = false;
var tutorialAnomaly = null;
var tutorialTexts = [];
// Central nexus
var nexus = game.addChild(LK.getAsset('nexus', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
// UI Elements
var cohesionBarBg = LK.gui.top.addChild(LK.getAsset('cohesionBarBg', {
anchorX: 0.5,
anchorY: 0,
x: LK.gui.top.width / 2,
y: 120
}));
var cohesionBar = LK.gui.top.addChild(LK.getAsset('cohesionBar', {
anchorX: 0.5,
anchorY: 0,
x: LK.gui.top.width / 2,
y: 120
}));
var cohesionText = new Text2('Temporal Cohesion: 100%', {
size: 40,
fill: 0x3498DB
});
cohesionText.anchor.set(0.5, 0);
cohesionText.x = LK.gui.top.width / 2;
cohesionText.y = 50;
LK.gui.top.addChild(cohesionText);
var cyclesText = new Text2('Cycles: 0', {
size: 35,
fill: 0xFFFFFF
});
cyclesText.anchor.set(0, 0);
cyclesText.x = 120;
cyclesText.y = 50;
LK.gui.top.addChild(cyclesText);
var debuffText = new Text2('Debuffs: 0', {
size: 35,
fill: 0xE74C3C
});
debuffText.anchor.set(1, 0);
debuffText.x = LK.gui.top.width - 50;
debuffText.y = 50;
LK.gui.top.addChild(debuffText);
// Tutorial UI
var tutorialOverlay = new Container();
tutorialOverlay.alpha = 0;
LK.gui.center.addChild(tutorialOverlay);
var tutorialBox = tutorialOverlay.addChild(LK.getAsset('cohesionBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 8
}));
var tutorialText = new Text2('', {
size: 45,
fill: 0xFFFFFF,
wordWrap: true,
wordWrapWidth: 800
});
tutorialText.anchor.set(0.5, 0.5);
tutorialOverlay.addChild(tutorialText);
var tutorialSkipText = new Text2('Tap anywhere to continue', {
size: 35,
fill: 0xF39C12
});
tutorialSkipText.anchor.set(0.5, 0.5);
tutorialSkipText.y = 150;
tutorialOverlay.addChild(tutorialSkipText);
function showTutorialStep(step) {
if (!tutorialActive) return;
var instructions = ["Welcome, Chronomancer!\n\nYou are humanity's last hope against timeline collapse. Reality is fracturing around you.", "This is your Temporal Cohesion meter.\n\nIt represents reality's stability. When it reaches zero, everything ends.", "Temporal Anomalies will appear around you.\n\nEach has a countdown timer. When it reaches zero, the anomaly fails.", "Tap an anomaly to begin fixing it.\n\nYou must click it multiple times while it pulses to succeed.", "You can only work on one anomaly at a time.\n\nOthers will continue counting down while you're busy.", "Failed anomalies damage your Temporal Cohesion.\n\nMajor anomalies (purple) cause more damage than minor ones (orange).", "The game never truly ends in victory.\n\nYour goal is to survive as long as possible and minimize damage.", "Choose wisely, Chronomancer.\n\nSome losses are inevitable. The timeline's fate rests in your hands."];
if (step >= instructions.length) {
endTutorial();
return;
}
tutorialText.setText(instructions[step]);
tween(tutorialOverlay, {
alpha: 1
}, {
duration: 500
});
tutorialPaused = true;
}
function nextTutorialStep() {
if (!tutorialActive || !tutorialPaused) return;
tween(tutorialOverlay, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
tutorialStep++;
if (tutorialStep === 2) {
// Spawn tutorial anomaly after explaining cohesion
spawnTutorialAnomaly();
}
LK.setTimeout(function () {
showTutorialStep(tutorialStep);
}, 500);
}
});
tutorialPaused = false;
}
function spawnTutorialAnomaly() {
if (tutorialAnomaly) return;
tutorialAnomaly = new Anomaly('minor', 1);
tutorialAnomaly.x = nexus.x + 300;
tutorialAnomaly.y = nexus.y - 200;
tutorialAnomaly.currentTime = 8000; // Give more time in tutorial
tutorialAnomaly.maxTime = 8000;
game.addChild(tutorialAnomaly);
activeAnomalies.push(tutorialAnomaly);
LK.setTimeout(function () {
if (tutorialAnomaly && tutorialAnomaly.parent) {
tutorialAnomaly.activate();
}
}, 1000);
}
function endTutorial() {
tutorialActive = false;
tutorialOverlay.alpha = 0;
// Clean up tutorial anomaly
if (tutorialAnomaly && tutorialAnomaly.parent && !tutorialAnomaly.isCompleted) {
tutorialAnomaly.destroy();
for (var i = activeAnomalies.length - 1; i >= 0; i--) {
if (activeAnomalies[i] === tutorialAnomaly) {
activeAnomalies.splice(i, 1);
break;
}
}
}
// Start normal game
spawnAnomaly();
spawnAnomaly();
}
function spawnAnomaly() {
if (tutorialActive) return;
if (activeAnomalies.length >= 4) return;
var type = Math.random() < 0.3 ? 'major' : 'minor';
var anomaly = new Anomaly(type, 1 + Math.floor(cyclesSurvived / 5));
// Position around the nexus
var angle = Math.random() * Math.PI * 2;
var distance = 400 + Math.random() * 300;
anomaly.x = nexus.x + Math.cos(angle) * distance;
anomaly.y = nexus.y + Math.sin(angle) * distance;
// Ensure anomaly stays within bounds
anomaly.x = Math.max(200, Math.min(1848, anomaly.x));
anomaly.y = Math.max(400, Math.min(2332, anomaly.y));
game.addChild(anomaly);
activeAnomalies.push(anomaly);
// Auto-activate after brief delay
LK.setTimeout(function () {
if (anomaly.parent) {
anomaly.activate();
}
}, 500);
}
function updateUI() {
var cohesionPercent = temporalCohesion / maxTemporalCohesion;
cohesionBar.scaleX = cohesionPercent;
// Color cohesion bar
if (cohesionPercent > 0.6) {
cohesionBar.tint = 0x3498db;
} else if (cohesionPercent > 0.3) {
cohesionBar.tint = 0xf39c12;
} else {
cohesionBar.tint = 0xe74c3c;
}
cohesionText.setText('Temporal Cohesion: ' + Math.floor(temporalCohesion) + '%');
cyclesText.setText('Cycles: ' + cyclesSurvived);
debuffText.setText('Debuffs: ' + (minorFailures + majorFailures));
}
function checkGameOver() {
if (temporalCohesion <= 0) {
gameActive = false;
LK.effects.flashScreen(0xe74c3c, 2000);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
}
function cleanupAnomalies() {
for (var i = activeAnomalies.length - 1; i >= 0; i--) {
var anomaly = activeAnomalies[i];
if (anomaly.isCompleted || anomaly.isFailed || !anomaly.parent) {
activeAnomalies.splice(i, 1);
}
}
}
// Tutorial tap handler
game.down = function (x, y, obj) {
if (tutorialActive && tutorialPaused) {
nextTutorialStep();
return;
}
};
// Start tutorial
LK.setTimeout(function () {
showTutorialStep(0);
}, 1000);
game.update = function () {
if (!gameActive) return;
// Skip normal game logic during tutorial
if (tutorialActive && tutorialStep < 6) {
return;
}
// Spawn anomalies
anomalySpawnTimer += 16.67;
if (anomalySpawnTimer >= 3000 - cyclesSurvived * 50) {
anomalySpawnTimer = 0;
spawnAnomaly();
}
// Drain cohesion
cohesionDrainTimer += 16.67;
if (cohesionDrainTimer >= 2000) {
cohesionDrainTimer = 0;
temporalCohesion -= 1 + minorFailures * 0.5 + majorFailures * 1;
if (temporalCohesion < 50 && LK.ticks % 120 === 0) {
LK.getSound('cohesionDrain').play();
}
}
// Tutorial completion check
if (tutorialActive && tutorialAnomaly && (tutorialAnomaly.isCompleted || tutorialAnomaly.isFailed)) {
if (tutorialStep === 6) {
LK.setTimeout(function () {
showTutorialStep(7);
}, 1500);
}
}
// Update cycle counter
var newCycles = Math.floor(LK.ticks / 3600); // Every 60 seconds
if (newCycles > cyclesSurvived) {
cyclesSurvived = newCycles;
LK.setScore(LK.getScore() + 100);
}
// Nexus pulse effect
if (LK.ticks % 60 === 0) {
var pulseIntensity = 1 - temporalCohesion / maxTemporalCohesion;
if (pulseIntensity > 0.5) {
tween(nexus, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
onFinish: function onFinish() {
tween(nexus, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
}
}
cleanupAnomalies();
updateUI();
checkGameOver();
};