/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var CosmicBeam = Container.expand(function () { var self = Container.call(this); // Create beam using luminaDust asset as stretched light beam var beamGraphics = self.attachAsset('luminaDust', { anchorX: 0.0, anchorY: 0.5 }); // Choose random traversal direction (horizontal, vertical, or diagonal) var traversalType = Math.floor(Math.random() * 3); var startX, startY, endX, endY; switch (traversalType) { case 0: // Horizontal traversal startX = -300; startY = Math.random() * 2732; endX = 2348; endY = startY + (Math.random() - 0.5) * 200; // Slight curve break; case 1: // Vertical traversal startX = Math.random() * 2048; startY = -300; endX = startX + (Math.random() - 0.5) * 200; endY = 3032; break; case 2: // Diagonal traversal if (Math.random() < 0.5) { // Top-left to bottom-right startX = -300; startY = -300; endX = 2348; endY = 3032; } else { // Top-right to bottom-left startX = 2348; startY = -300; endX = -300; endY = 3032; } break; } // Calculate beam properties var deltaX = endX - startX; var deltaY = endY - startY; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); var angle = Math.atan2(deltaY, deltaX); // Configure beam appearance beamGraphics.scaleX = distance / 20; // Stretch to cover full traversal beamGraphics.scaleY = 0.05 + Math.random() * 0.05; // Very thin beam with soft edges beamGraphics.rotation = angle; beamGraphics.alpha = 0.0; // Start invisible // Very faint ethereal colors for subtle appearance var beamColors = [0xffffff, // Pure white 0xe6f0ff, // Cool blue-white 0xfff4e6, // Warm golden-white 0xf0e6ff, // Purple-white 0xe6fff0 // Green-white ]; var colorIndex = Math.floor(Math.random() * beamColors.length); beamGraphics.tint = beamColors[colorIndex]; // Beam lifecycle properties self.lifeSpan = 180 + Math.random() * 240; // 3-7 seconds at 60fps self.age = 0; self.materializationDuration = 30 + Math.random() * 30; // 0.5-1 second materialization self.fadeDuration = 60 + Math.random() * 60; // 1-2 second fade out self.traversalSpeed = 0.8 + Math.random() * 0.4; // Slow traversal speed // Position at start self.x = startX; self.y = startY; // Store traversal target self.targetX = endX; self.targetY = endY; self.traversalProgress = 0.0; // Slow materialization phase tween(beamGraphics, { alpha: 0.03 + Math.random() * 0.05 // Very low opacity maximum }, { duration: self.materializationDuration * 16.67, // Convert to milliseconds easing: tween.easeOut }); self.update = function () { self.age++; // Slow traversal across screen if (self.age > self.materializationDuration) { self.traversalProgress += self.traversalSpeed / distance; self.x = startX + (endX - startX) * self.traversalProgress; self.y = startY + (endY - startY) * self.traversalProgress; } // Begin fade out near end of lifespan if (self.age > self.lifeSpan - self.fadeDuration) { var fadeProgress = (self.lifeSpan - self.age) / self.fadeDuration; beamGraphics.alpha *= fadeProgress; } // Subtle flickering during visibility for ethereal effect if (beamGraphics.alpha > 0.01) { var flicker = 0.85 + Math.sin(self.age * 0.2) * 0.15; beamGraphics.alpha *= flicker; } // Remove when expired or off-screen if (self.age >= self.lifeSpan || self.traversalProgress >= 1.0) { self.destroy(); for (var i = cosmicBeams.length - 1; i >= 0; i--) { if (cosmicBeams[i] === self) { cosmicBeams.splice(i, 1); break; } } } }; return self; }); var CosmicParticle = Container.expand(function (x, y) { var self = Container.call(this); var particleGraphics = self.attachAsset('luminaDust', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; // Particle properties for curving movement self.curvePhase = Math.random() * Math.PI * 2; self.curveSpeed = 0.005 + Math.random() * 0.003; // Very slow curving motion self.curveAmplitude = 50 + Math.random() * 100; // Gentle curve amplitude self.driftX = (Math.random() - 0.5) * 0.3; // Slow horizontal drift self.driftY = (Math.random() - 0.5) * 0.2; // Slow vertical drift self.lifeSpan = 1800 + Math.random() * 1200; // 30-50 seconds at 60fps self.age = 0; self.fadeInDuration = 300 + Math.random() * 300; // 5-10 seconds fade in self.fadeOutStart = self.lifeSpan - 600; // Start fading out 10 seconds before end // Initialize with very low opacity particleGraphics.alpha = 0.0; particleGraphics.scaleX = 0.3 + Math.random() * 0.4; // Small, soft particles particleGraphics.scaleY = particleGraphics.scaleX; // Match nebula palette or slight contrast var particleColors = [0xffd700, // Golden (slight contrast to purple nebula) 0xe6e6ff, // Soft blue-white (matches cool nebula tones) 0xddd4ff, // Purple-white (matches nebula palette) 0xffd4e6, // Warm pink-white (slight contrast) 0xb19cd9 // Violet (matches evolved nebula) ]; var colorIndex = Math.min(currentColorPhase, particleColors.length - 1); particleGraphics.tint = particleColors[colorIndex]; self.update = function () { self.age++; // Gentle curving movement along curved paths var curveOffset = Math.sin(self.age * self.curveSpeed + self.curvePhase) * self.curveAmplitude; self.x += self.driftX + Math.cos(self.age * self.curveSpeed * 0.7) * 0.1; self.y += self.driftY + Math.sin(self.age * self.curveSpeed * 0.5) * 0.1; // Add gentle curve displacement var baseX = self.x + curveOffset * 0.01; var baseY = self.y + Math.cos(self.age * self.curveSpeed * 0.8 + self.curvePhase) * self.curveAmplitude * 0.008; self.x = baseX; self.y = baseY; // Fade in/out lifecycle - no abrupt appearance/disappearance if (self.age < self.fadeInDuration) { // Gradual fade in var fadeInProgress = self.age / self.fadeInDuration; particleGraphics.alpha = (0.05 + Math.random() * 0.08) * fadeInProgress; // Very low opacity } else if (self.age > self.fadeOutStart) { // Gradual fade out var fadeOutProgress = (self.lifeSpan - self.age) / (self.lifeSpan - self.fadeOutStart); particleGraphics.alpha = (0.05 + Math.random() * 0.08) * fadeOutProgress; } else { // Subtle opacity fluctuation during main life var opacityFluctuation = 0.05 + Math.sin(self.age * 0.02) * 0.03; particleGraphics.alpha = Math.max(0.02, Math.min(0.13, opacityFluctuation)); } // Gentle scale breathing var scaleBreathing = 1.0 + Math.sin(self.age * 0.008) * 0.1; particleGraphics.scaleX = (0.3 + Math.random() * 0.4) * scaleBreathing; particleGraphics.scaleY = particleGraphics.scaleX; // Soft rotation particleGraphics.rotation += 0.001; // Remove when lifespan is complete if (self.age >= self.lifeSpan) { self.destroy(); for (var i = cosmicParticles.length - 1; i >= 0; i--) { if (cosmicParticles[i] === self) { cosmicParticles.splice(i, 1); break; } } } }; return self; }); var CosmicRay = Container.expand(function (startX, startY, endX, endY) { var self = Container.call(this); // Create ray using luminaDust asset as a stretched beam var rayGraphics = self.attachAsset('luminaDust', { anchorX: 0.0, anchorY: 0.5 }); self.x = startX; self.y = startY; // Calculate ray properties var deltaX = endX - startX; var deltaY = endY - startY; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); var angle = Math.atan2(deltaY, deltaX); // Configure ray appearance rayGraphics.scaleX = distance / 20; // Stretch to cover distance rayGraphics.scaleY = 0.1 + Math.random() * 0.1; // Very thin beam rayGraphics.rotation = angle; rayGraphics.alpha = 0.0; // Start invisible // Very faint cosmic colors var rayColors = [0xffffff, // Pure white 0xe6e6ff, // Cool blue-white 0xffd4e6, // Warm pink-white 0xddd4ff, // Purple-white 0xfff4d4 // Golden-white ]; var colorIndex = Math.floor(Math.random() * rayColors.length); rayGraphics.tint = rayColors[colorIndex]; self.lifeSpan = 120 + Math.random() * 180; // 2-5 seconds at 60fps self.age = 0; self.fadeInDuration = 20 + Math.random() * 20; // Quick fade in self.fadeOutStart = self.lifeSpan - 30; // Start fading out early // Animate ray appearance - brief flash effect tween(rayGraphics, { alpha: 0.08 + Math.random() * 0.12 // Very faint maximum opacity }, { duration: 300 + Math.random() * 200, // Quick appearance easing: tween.easeOut, onFinish: function onFinish() { // Hold briefly then fade out LK.setTimeout(function () { tween(rayGraphics, { alpha: 0.0 }, { duration: 500 + Math.random() * 300, // Slow fade out easing: tween.easeIn }); }, 200 + Math.random() * 400); } }); self.update = function () { self.age++; // Subtle flickering during visibility if (rayGraphics.alpha > 0.02) { var flicker = 0.9 + Math.sin(self.age * 0.3) * 0.1; rayGraphics.alpha *= flicker; } // Remove when expired if (self.age >= self.lifeSpan) { self.destroy(); for (var i = cosmicRays.length - 1; i >= 0; i--) { if (cosmicRays[i] === self) { cosmicRays.splice(i, 1); break; } } } }; return self; }); var DistantStar = Container.expand(function (x, y) { var self = Container.call(this); var starGraphics = self.attachAsset('distantStar', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.driftSpeedX = (Math.random() - 0.5) * 0.1; self.driftSpeedY = (Math.random() - 0.5) * 0.1; self.shimmerPhase = Math.random() * Math.PI * 2; self.shimmerSpeed = 0.01 + Math.random() * 0.02; // Extremely slow cosmic flow movement - barely perceptible self.cosmicFlowX = (Math.random() - 0.5) * 0.02; // Very slow horizontal flow self.cosmicFlowY = (Math.random() - 0.5) * 0.015; // Very slow vertical flow self.spiralAngle = Math.random() * Math.PI * 2; // Initial spiral position self.spiralSpeed = 0.0001 + Math.random() * 0.0001; // Extremely slow spiral self.spiralRadius = Math.random() * 0.5; // Spiral influence radius starGraphics.alpha = 0.2 + Math.random() * 0.4; starGraphics.scaleX = 0.5 + Math.random() * 0.5; starGraphics.scaleY = starGraphics.scaleX; // Star twinkling properties for independent brightness fluctuations self.twinkleChance = 0.003 + Math.random() * 0.002; // Small percentage chance per frame self.isTwinkling = false; self.baseBrightness = starGraphics.alpha; self.twinkleIntensity = 0.3 + Math.random() * 0.5; // Random twinkling intensity self.update = function () { // Very slow drift movement self.x += self.driftSpeedX; self.y += self.driftSpeedY; // Extremely slow cosmic flow - creates impression of vast cosmic distances // Only noticeable after several seconds of observation self.x += self.cosmicFlowX; self.y += self.cosmicFlowY; // Add subtle spiral movement flowing outward from center var centerX = 1024; var centerY = 1366; var spiralX = Math.cos(self.spiralAngle) * self.spiralRadius; var spiralY = Math.sin(self.spiralAngle) * self.spiralRadius; self.x += spiralX; self.y += spiralY; self.spiralAngle += self.spiralSpeed; // Subtle shimmer animation var shimmer = 0.8 + Math.sin(LK.ticks * self.shimmerSpeed + self.shimmerPhase) * 0.3; starGraphics.alpha = (0.2 + Math.random() * 0.4) * shimmer; // Independent star twinkling system - asynchronous brightness fluctuations if (!self.isTwinkling && Math.random() < self.twinkleChance) { // Start twinkling animation self.isTwinkling = true; // Create random twinkling pattern with varying durations var twinkleDuration = 200 + Math.random() * 400; // 200-600ms var targetBrightness = self.baseBrightness * (1.0 + self.twinkleIntensity); // Brightness increase phase tween(starGraphics, { alpha: targetBrightness, scaleX: starGraphics.scaleX * (1.0 + self.twinkleIntensity * 0.3), scaleY: starGraphics.scaleY * (1.0 + self.twinkleIntensity * 0.3) }, { duration: twinkleDuration * 0.3, easing: tween.easeOut, onFinish: function onFinish() { // Brightness decrease phase tween(starGraphics, { alpha: self.baseBrightness * (0.7 + Math.random() * 0.3), scaleX: starGraphics.scaleX * (0.8 + Math.random() * 0.2), scaleY: starGraphics.scaleY * (0.8 + Math.random() * 0.2) }, { duration: twinkleDuration * 0.7, easing: tween.easeInOut, onFinish: function onFinish() { // Reset twinkling state self.isTwinkling = false; // Occasionally create a double-twinkle effect if (Math.random() < 0.2) { // Quick second twinkle after short delay LK.setTimeout(function () { if (!self.isTwinkling) { self.isTwinkling = true; tween(starGraphics, { alpha: targetBrightness * 0.6, scaleX: starGraphics.scaleX * 1.1, scaleY: starGraphics.scaleY * 1.1 }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { self.isTwinkling = false; } }); } }, 100 + Math.random() * 200); } } }); } }); } // Dynamic color tinting based on cosmic progression var starTints = [0xffffff, // Base: pure white 0xe6e6ff, // Phase 1: cool blue-white 0xddd4ff, // Phase 2: purple-white 0xffd4e6 // Phase 3: warm purple-pink ]; var currentTint = starTints[Math.min(currentColorPhase, starTints.length - 1)]; starGraphics.tint = currentTint; // Wrap around screen boundaries if (self.x < -10) self.x = 2058; if (self.x > 2058) self.x = -10; if (self.y < -10) self.y = 2742; if (self.y > 2742) self.y = -10; }; return self; }); var FluxVoid = Container.expand(function () { var self = Container.call(this); var voidGraphics = self.attachAsset('fluxVoid', { anchorX: 0.5, anchorY: 0.5 }); self.duration = 300; // 5 seconds self.timer = 0; self.x = Math.random() * 1500 + 274; self.y = Math.random() * 2000 + 366; self.down = function (x, y, obj) { // 70% chance for reward, 30% for penalty var isReward = Math.random() < 0.7; var amount = Math.floor(luminaDust * 0.2); // 20% of current dust if (isReward) { luminaDust += amount; LK.effects.flashObject(self, 0x00ff00, 500); } else { luminaDust = Math.max(0, luminaDust - amount); LK.effects.flashObject(self, 0xff0000, 500); } storage.luminaDust = luminaDust; updateDustDisplay(); LK.getSound('fluxEvent').play(); // Remove this void self.destroy(); for (var i = fluxVoids.length - 1; i >= 0; i--) { if (fluxVoids[i] === self) { fluxVoids.splice(i, 1); break; } } }; self.update = function () { self.timer++; // Pulsing effect var pulse = 1.0 + Math.sin(LK.ticks * 0.1) * 0.3; voidGraphics.scaleX = pulse; voidGraphics.scaleY = pulse; // Fade out near end if (self.timer > self.duration - 60) { voidGraphics.alpha = (self.duration - self.timer) / 60; } // Remove when expired if (self.timer >= self.duration) { self.destroy(); for (var i = fluxVoids.length - 1; i >= 0; i--) { if (fluxVoids[i] === self) { fluxVoids.splice(i, 1); break; } } } }; return self; }); var LuminaCore = Container.expand(function () { var self = Container.call(this); var coreGraphics = self.attachAsset('luminaCore', { anchorX: 0.5, anchorY: 0.5 }); self.baseScale = 1.0; self.clickPower = storage.clickPower || 1; self.coreLevel = storage.coreLevel || 1; self.down = function (x, y, obj) { // Click effect tween(coreGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); tween(coreGraphics, { scaleX: self.baseScale, scaleY: self.baseScale }, { duration: 100 }); // Generate lumina dust var dustGenerated = self.clickPower * temporalMultiplier; luminaDust += dustGenerated; storage.luminaDust = luminaDust; // Spawn visual dust particle spawnDustParticle(self.x, self.y); LK.getSound('coreClick').play(); // Update displays updateDustDisplay(); }; self.update = function () { // Gentle pulsing animation var pulseScale = 1.0 + Math.sin(LK.ticks * 0.05) * 0.1; coreGraphics.scaleX = self.baseScale * pulseScale; coreGraphics.scaleY = self.baseScale * pulseScale; // Color shifting based on core level var colorShift = Math.sin(LK.ticks * 0.02) * 0.3; coreGraphics.tint = 0x6a5acd + colorShift * 0x101010; }; return self; }); var LuminaEnergyWisp = Container.expand(function (x, y) { var self = Container.call(this); var wispGraphics = self.attachAsset('luminaDust', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; // Ethereal movement properties self.flowSpeed = 0.3 + Math.random() * 0.5; // Gentle flowing speed self.flowDirection = Math.random() * Math.PI * 2; // Random initial direction self.flowPhase = Math.random() * Math.PI * 2; self.waveAmplitude = 30 + Math.random() * 40; // Sine wave amplitude for ethereal movement self.waveFrequency = 0.008 + Math.random() * 0.004; // Wave frequency for organic flow self.lifeSpan = 1800 + Math.random() * 1800; // 30-60 seconds at 60fps self.age = 0; // Energy attraction to Lumina Core for permeating effect self.coreAttraction = 0.02 + Math.random() * 0.01; // Subtle attraction force self.orbitRadius = 150 + Math.random() * 200; // Preferred orbit distance self.spiralTendency = (Math.random() - 0.5) * 0.003; // Slight spiral movement // Visual properties for ethereal appearance wispGraphics.alpha = 0.0; // Start invisible wispGraphics.scaleX = 0.4 + Math.random() * 0.3; // Small ethereal particles wispGraphics.scaleY = wispGraphics.scaleX; wispGraphics.tint = 0x9370db; // Lumina purple energy color // Fade in effect tween(wispGraphics, { alpha: 0.15 + Math.random() * 0.15 // Subtle ethereal visibility }, { duration: 1000 + Math.random() * 1000, easing: tween.easeOut }); self.update = function () { self.age++; // Ethereal flowing movement with wave patterns var waveOffsetX = Math.sin(self.age * self.waveFrequency + self.flowPhase) * self.waveAmplitude; var waveOffsetY = Math.cos(self.age * self.waveFrequency * 0.7 + self.flowPhase) * self.waveAmplitude * 0.6; // Flow in direction with ethereal wave motion self.x += Math.cos(self.flowDirection) * self.flowSpeed + waveOffsetX * 0.01; self.y += Math.sin(self.flowDirection) * self.flowSpeed + waveOffsetY * 0.01; // Subtle attraction to Lumina Core for energy permeation effect var coreX = 1024; var coreY = 1366; var distanceToCore = Math.sqrt((self.x - coreX) * (self.x - coreX) + (self.y - coreY) * (self.y - coreY)); // Apply gentle attraction when not too close if (distanceToCore > self.orbitRadius) { var attractionX = (coreX - self.x) / distanceToCore * self.coreAttraction; var attractionY = (coreY - self.y) / distanceToCore * self.coreAttraction; self.x += attractionX; self.y += attractionY; } // Add subtle spiral movement around core var angleToCore = Math.atan2(self.y - coreY, self.x - coreX); angleToCore += self.spiralTendency; var spiralX = coreX + Math.cos(angleToCore) * distanceToCore; var spiralY = coreY + Math.sin(angleToCore) * distanceToCore; self.x += (spiralX - self.x) * 0.01; // Very subtle spiral influence self.y += (spiralY - self.y) * 0.01; // Ethereal pulsing and energy fluctuation var energyPulse = 0.7 + Math.sin(self.age * 0.03 + self.flowPhase) * 0.3; var energyFlicker = 0.8 + Math.sin(self.age * 0.08) * 0.2; wispGraphics.alpha *= energyPulse * energyFlicker; // Subtle scale breathing for ethereal effect var scaleBreathing = 1.0 + Math.sin(self.age * 0.02 + self.flowPhase) * 0.15; wispGraphics.scaleX = (0.4 + Math.random() * 0.3) * scaleBreathing; wispGraphics.scaleY = wispGraphics.scaleX; // Gentle rotation to enhance ethereal movement wispGraphics.rotation += 0.005 + Math.sin(self.age * 0.01) * 0.003; // Color shifting for energy effect - hints at Lumina Core's influence var colorShift = Math.sin(self.age * 0.015) * 0.1; var r = 0.58 + colorShift; // Purple base with shifting var g = 0.44 + colorShift * 0.5; var b = 0.86 + colorShift * 0.3; var shiftedColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255); wispGraphics.tint = shiftedColor; // Fade out near end of lifespan if (self.age > self.lifeSpan - 600) { // Last 10 seconds var fadeProgress = (self.lifeSpan - self.age) / 600; wispGraphics.alpha *= fadeProgress; } // Remove when expired if (self.age >= self.lifeSpan) { self.destroy(); for (var i = luminaEnergyWisps.length - 1; i >= 0; i--) { if (luminaEnergyWisps[i] === self) { luminaEnergyWisps.splice(i, 1); break; } } } }; return self; }); var NebulaCloud = Container.expand(function (x, y, scale, speed) { var self = Container.call(this); var cloudGraphics = self.attachAsset('nebulaCloud', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.baseScale = scale || 1.0; self.speed = speed || 0.001; self.phaseOffset = Math.random() * Math.PI * 2; cloudGraphics.scaleX = self.baseScale; cloudGraphics.scaleY = self.baseScale; cloudGraphics.alpha = 0.3; // Undulation properties for organic texture shifting self.undulationPhaseX = Math.random() * Math.PI * 2; self.undulationPhaseY = Math.random() * Math.PI * 2; self.undulationSpeedX = 0.003 + Math.random() * 0.002; // Very slow undulation self.undulationSpeedY = 0.002 + Math.random() * 0.003; self.undulationIntensity = 0.15 + Math.random() * 0.1; // Subtle intensity variation self.colorShiftPhase = Math.random() * Math.PI * 2; self.colorShiftSpeed = 0.001 + Math.random() * 0.0005; // Very slow color blending self.expansionPhase = Math.random() * Math.PI * 2; self.expansionSpeed = 0.0008 + Math.random() * 0.0004; // Slow expansion/contraction // Initialize very slow breathing/swirling tween animation self.breathingCycle = function () { // Slow breathing scale animation (8-12 second cycles) var breathDuration = 8000 + Math.random() * 4000; // 8-12 seconds var breathScale = 0.95 + Math.random() * 0.1; // Subtle scale variation tween(cloudGraphics, { scaleX: self.baseScale * breathScale, scaleY: self.baseScale * breathScale * 0.8 }, { duration: breathDuration, easing: tween.easeInOut, onFinish: function onFinish() { // Breathe back out tween(cloudGraphics, { scaleX: self.baseScale, scaleY: self.baseScale * 0.8 }, { duration: breathDuration, easing: tween.easeInOut, onFinish: function onFinish() { // Continue the breathing cycle self.breathingCycle(); } }); } }); }; // Start the breathing cycle self.breathingCycle(); // Initialize continuous undulation animation system self.undulationCycle = function () { // Create continuous, non-looping undulation with varying parameters var undulationDuration = 45000 + Math.random() * 30000; // 45-75 seconds for very slow movement var targetScaleX = self.baseScale * (0.7 + Math.random() * 0.6); // Wide range of scale variation var targetScaleY = self.baseScale * (0.8 + Math.random() * 0.4); // Different Y scaling for organic feel var targetAlpha = 0.2 + Math.random() * 0.3; // Subtle alpha variation // Create organic, flowing undulation with easing tween(cloudGraphics, { scaleX: targetScaleX, scaleY: targetScaleY, alpha: targetAlpha }, { duration: undulationDuration, easing: tween.easeInOut, onFinish: function onFinish() { // Continue with new random parameters for infinite variation self.undulationCycle(); } }); // Add secondary undulation layer for more complex movement LK.setTimeout(function () { var secondaryDuration = 35000 + Math.random() * 25000; // Slightly different timing var secondaryScaleX = self.baseScale * (0.8 + Math.random() * 0.4); var secondarySkew = (Math.random() - 0.5) * 0.3; // Add subtle skewing effect tween(cloudGraphics, { scaleX: secondaryScaleX, rotation: cloudGraphics.rotation + secondarySkew }, { duration: secondaryDuration, easing: tween.easeInOut }); }, undulationDuration * 0.3); // Offset timing for layered effect }; // Start undulation cycle with random delay LK.setTimeout(function () { self.undulationCycle(); }, Math.random() * 10000); // Add subtle swirling motion with tween self.swirlingCycle = function () { var swirlingDuration = 15000 + Math.random() * 10000; // 15-25 seconds var swirlingIntensity = 20 + Math.random() * 30; // Subtle movement range var targetX = self.x + (Math.random() - 0.5) * swirlingIntensity; var targetY = self.y + (Math.random() - 0.5) * swirlingIntensity; tween(self, { x: targetX, y: targetY }, { duration: swirlingDuration, easing: tween.easeInOut, onFinish: function onFinish() { // Continue the swirling cycle self.swirlingCycle(); } }); }; // Start the swirling cycle with a random delay LK.setTimeout(function () { self.swirlingCycle(); }, Math.random() * 5000); self.update = function () { // Gentle floating movement self.x += Math.sin(LK.ticks * self.speed + self.phaseOffset) * 0.2; self.y += Math.cos(LK.ticks * self.speed * 0.7 + self.phaseOffset) * 0.15; // Continuous organic undulation - creates flowing, shifting texture effect var undulationX = Math.sin(LK.ticks * self.undulationSpeedX + self.undulationPhaseX) * self.undulationIntensity; var undulationY = Math.cos(LK.ticks * self.undulationSpeedY + self.undulationPhaseY) * self.undulationIntensity; var undulationScale = 1.0 + Math.sin(LK.ticks * self.undulationSpeedX * 0.5 + self.undulationPhaseX) * 0.08; // Apply undulation to create organic texture shifting cloudGraphics.scaleX *= (1.0 + undulationX) * undulationScale; cloudGraphics.scaleY *= (1.0 + undulationY) * undulationScale * 0.8; // Slow expansion/contraction cycles - simulates breathing nebula var expansionCycle = Math.sin(LK.ticks * self.expansionSpeed + self.expansionPhase) * 0.12; cloudGraphics.scaleX *= 1.0 + expansionCycle; cloudGraphics.scaleY *= 1.0 + expansionCycle * 0.7; // Continuous color blending and shifting for internal wisps effect var colorWaveR = Math.sin(LK.ticks * self.colorShiftSpeed + self.colorShiftPhase) * 0.15; var colorWaveG = Math.cos(LK.ticks * self.colorShiftSpeed * 1.3 + self.colorShiftPhase) * 0.1; var colorWaveB = Math.sin(LK.ticks * self.colorShiftSpeed * 0.8 + self.colorShiftPhase + Math.PI) * 0.2; // Progressive color palette with Core evolution-based transitions var progressiveColors = [0x2c1b47, // Base: dark purple-blue 0x3d2b5d, // Evolution 1: deeper purple 0x4a3373, // Evolution 2: warmer purple 0x6b4ba6, // Evolution 3: vibrant violet 0x8a6bc4 // Transcendence: warm violet with energy ]; var baseColor = progressiveColors[Math.min(currentColorPhase, progressiveColors.length - 1)]; // Enhanced color blending for evolution phases if (coreEvolutions > 0) { // Add golden hints during advanced evolutions var goldenInfluence = Math.min(coreEvolutions * 0.1, 0.3); var r = (baseColor >> 16 & 0xFF) / 255.0; var g = (baseColor >> 8 & 0xFF) / 255.0; var b = (baseColor & 0xFF) / 255.0; // Blend in golden warmth r = Math.min(1.0, r + goldenInfluence * 0.2); g = Math.min(1.0, g + goldenInfluence * 0.15); baseColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255); } // Extract RGB components and apply organic color shifting var r = (baseColor >> 16 & 0xFF) / 255.0; var g = (baseColor >> 8 & 0xFF) / 255.0; var b = (baseColor & 0xFF) / 255.0; // Apply continuous color waves for internal wisp blending r = Math.max(0, Math.min(1, r + colorWaveR)); g = Math.max(0, Math.min(1, g + colorWaveG)); b = Math.max(0, Math.min(1, b + colorWaveB)); // Reconstruct color with organic shifting var shiftedColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255); cloudGraphics.tint = shiftedColor; // Gentle alpha breathing with undulation var alphaPulse = 0.3 + Math.sin(LK.ticks * self.speed * 1.5 + self.phaseOffset) * 0.1; var alphaUndulation = Math.cos(LK.ticks * self.undulationSpeedY + self.undulationPhaseY) * 0.05; cloudGraphics.alpha = Math.max(0.1, Math.min(0.6, alphaPulse + alphaUndulation)); // Very slow rotation with slight variation var rotationVariation = Math.sin(LK.ticks * self.undulationSpeedX * 0.3) * 0.002; cloudGraphics.rotation += self.speed * 0.5 + rotationVariation; }; return self; }); var SpireNode = Container.expand(function (angle, distance) { var self = Container.call(this); var nodeGraphics = self.attachAsset('spireNode', { anchorX: 0.5, anchorY: 0.5 }); self.angle = angle; self.distance = distance; self.dustPerSecond = 0.5; self.lastDustTime = LK.ticks; self.decayTimer = 0; self.isDecaying = false; self.update = function () { // Orbital movement self.x = 1024 + Math.cos(self.angle + LK.ticks * 0.01) * self.distance; self.y = 1366 + Math.sin(self.angle + LK.ticks * 0.01) * self.distance; // Generate dust automatically if (LK.ticks - self.lastDustTime >= 60) { // Every second at 60fps if (!self.isDecaying) { luminaDust += self.dustPerSecond; storage.luminaDust = luminaDust; updateDustDisplay(); spawnDustParticle(self.x, self.y); } self.lastDustTime = LK.ticks; } // Handle decay system self.decayTimer++; if (self.decayTimer > 1800) { // 30 seconds at 60fps self.isDecaying = true; nodeGraphics.tint = 0xff4444; } // Gentle rotation nodeGraphics.rotation += 0.02; }; self.repair = function () { self.isDecaying = false; self.decayTimer = 0; nodeGraphics.tint = 0xffffff; // Repair cost var repairCost = 10; if (luminaDust >= repairCost) { luminaDust -= repairCost; storage.luminaDust = luminaDust; updateDustDisplay(); } }; self.down = function (x, y, obj) { if (self.isDecaying) { self.repair(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a0d2e }); /**** * Game Code ****/ // Game state variables var luminaDust = storage.luminaDust || 0; var spireNodes = []; var fluxVoids = []; var dustParticles = []; var nebulaClouds = []; var distantStars = []; var cosmicParticles = []; // Track low-density cosmic particles var luminaEnergyWisps = []; // Track ethereal Lumina energy wisps var cosmicRays = []; // Track faint cosmic ray beams var cosmicBeams = []; // Track ethereal traversing light beams var temporalMultiplier = 1.0; var nextFluxTime = LK.ticks + Math.random() * 1800 + 1200; // 20-50 seconds var nextTemporalTime = LK.ticks + Math.random() * 3600 + 1800; // 30-90 seconds var nextCosmicParticleTime = LK.ticks + Math.random() * 900 + 600; // 10-25 seconds between spawns // Color palette for cosmic atmosphere progression var colorPalette = { baseBackground: 0x1a0d2e, // Deep purple void earlyNebula: 0x2c1b47, // Dark purple-blue midNebula: 0x3d2b5d, // Deeper purple lateNebula: 0x4a3373, // Warmer purple advancedNebula: 0x5d4088 // Purple with golden hints }; var currentColorPhase = storage.colorPhase || 0; // 0-4 representing progression through color phases // Core evolution tracking for significant transformations var coreEvolutions = storage.coreEvolutions || 0; var lastEvolutionCheck = storage.lastEvolutionCheck || 0; var transcendenceLevel = storage.transcendenceLevel || 0; // UI Elements var dustDisplay = new Text2('Lumina Dust: 0', { size: 80, fill: 0xFFD700 }); dustDisplay.anchor.set(0.5, 0); LK.gui.top.addChild(dustDisplay); var clickPowerDisplay = new Text2('Click Power: 1x', { size: 60, fill: 0xFFFFFF }); clickPowerDisplay.anchor.set(0, 0); clickPowerDisplay.x = 50; clickPowerDisplay.y = 150; LK.gui.topLeft.addChild(clickPowerDisplay); var nodeCountDisplay = new Text2('Spire Nodes: 0', { size: 60, fill: 0x40E0D0 }); nodeCountDisplay.anchor.set(0, 0); nodeCountDisplay.x = 50; nodeCountDisplay.y = 220; LK.gui.topLeft.addChild(nodeCountDisplay); var temporalDisplay = new Text2('Temporal: 1.0x', { size: 50, fill: 0xFF69B4 }); temporalDisplay.anchor.set(1, 0); LK.gui.topRight.addChild(temporalDisplay); // Purchase buttons var buyNodeButton = new Text2('Buy Spire Node\nCost: 50 Dust', { size: 50, fill: 0x40E0D0 }); buyNodeButton.anchor.set(0.5, 1); LK.gui.bottom.addChild(buyNodeButton); var upgradeClickButton = new Text2('Upgrade Click\nCost: 100 Dust', { size: 50, fill: 0xFFD700 }); upgradeClickButton.anchor.set(0.5, 1); upgradeClickButton.y = -120; LK.gui.bottom.addChild(upgradeClickButton); // Create nebulous gas clouds for atmospheric depth for (var i = 0; i < 6; i++) { var cloudX = Math.random() * 2048; var cloudY = Math.random() * 2732; var cloudScale = 0.8 + Math.random() * 0.6; var cloudSpeed = 0.0005 + Math.random() * 0.001; var cloud = game.addChild(new NebulaCloud(cloudX, cloudY, cloudScale, cloudSpeed)); nebulaClouds.push(cloud); } // Create scattered distant stars for ambient particle drift for (var i = 0; i < 150; i++) { var starX = Math.random() * 2048; var starY = Math.random() * 2732; var star = game.addChild(new DistantStar(starX, starY)); distantStars.push(star); } // Initialize starfield layer movement for cosmic flow var starfieldFlowDirection = Math.random() * Math.PI * 2; // Random flow direction var starfieldFlowSpeed = 0.008 + Math.random() * 0.004; // Extremely slow flow speed var starfieldSpiralCenter = { x: 1024, y: 1366 }; // Spiral center point // Create the main Lumina Core var luminaCore = game.addChild(new LuminaCore()); luminaCore.x = 1024; luminaCore.y = 1366; // Load existing spire nodes var savedNodeCount = storage.spireNodeCount || 0; for (var i = 0; i < savedNodeCount; i++) { var angle = i / savedNodeCount * Math.PI * 2; var distance = 200 + i * 30; var node = game.addChild(new SpireNode(angle, distance)); spireNodes.push(node); } function updateDustDisplay() { dustDisplay.setText('Lumina Dust: ' + Math.floor(luminaDust)); } function updateClickPowerDisplay() { clickPowerDisplay.setText('Click Power: ' + luminaCore.clickPower + 'x'); } function updateNodeCountDisplay() { nodeCountDisplay.setText('Spire Nodes: ' + spireNodes.length); } function updateTemporalDisplay() { temporalDisplay.setText('Temporal: ' + temporalMultiplier.toFixed(1) + 'x'); } function spawnDustParticle(x, y) { var particle = LK.getAsset('luminaDust', { anchorX: 0.5, anchorY: 0.5 }); particle.x = x + (Math.random() - 0.5) * 100; particle.y = y + (Math.random() - 0.5) * 100; particle.alpha = 1.0; particle.timer = 0; particle.maxTime = 60; // 1 second game.addChild(particle); dustParticles.push(particle); // Animate particle var targetY = particle.y - 100; tween(particle, { y: targetY, alpha: 0 }, { duration: 1000, onFinish: function onFinish() { particle.destroy(); for (var i = dustParticles.length - 1; i >= 0; i--) { if (dustParticles[i] === particle) { dustParticles.splice(i, 1); break; } } } }); } function createFluxVoid() { var fluxVoid = game.addChild(new FluxVoid()); fluxVoids.push(fluxVoid); } function spawnCosmicParticle() { // Low-density spawning - only spawn if particle count is low if (cosmicParticles.length < 8) { // Maximum 8 particles at once for low density // Spawn near edges of screen for natural drift across view var spawnSide = Math.floor(Math.random() * 4); var x, y; switch (spawnSide) { case 0: // Top edge x = Math.random() * 2048; y = -100; break; case 1: // Right edge x = 2148; y = Math.random() * 2732; break; case 2: // Bottom edge x = Math.random() * 2048; y = 2832; break; case 3: // Left edge x = -100; y = Math.random() * 2732; break; } var particle = game.addChild(new CosmicParticle(x, y)); cosmicParticles.push(particle); } } function spawnLuminaEnergyWisp() { // Moderate density spawning - maintain ethereal energy presence if (luminaEnergyWisps.length < 12) { // Maximum 12 wisps for ethereal atmosphere // Spawn in various patterns around the environment var spawnPattern = Math.floor(Math.random() * 3); var x, y; switch (spawnPattern) { case 0: // Spawn around Lumina Core area for energy emission effect var angle = Math.random() * Math.PI * 2; var distance = 300 + Math.random() * 200; x = 1024 + Math.cos(angle) * distance; y = 1366 + Math.sin(angle) * distance; break; case 1: // Spawn from screen edges flowing inward var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: x = Math.random() * 2048; y = -50; break; // Top case 1: x = 2098; y = Math.random() * 2732; break; // Right case 2: x = Math.random() * 2048; y = 2782; break; // Bottom case 3: x = -50; y = Math.random() * 2732; break; // Left } break; case 2: // Spawn randomly throughout environment for permeating effect x = Math.random() * 2048; y = Math.random() * 2732; break; } var wisp = game.addChild(new LuminaEnergyWisp(x, y)); luminaEnergyWisps.push(wisp); } } function spawnCosmicRay() { // Very low frequency spawning - only spawn occasionally if (cosmicRays.length < 3) { // Maximum 3 rays at once for subtlety // Choose ray path type var rayType = Math.floor(Math.random() * 4); var startX, startY, endX, endY; switch (rayType) { case 0: // Diagonal from top-left to bottom-right startX = -100 + Math.random() * 500; startY = -100 + Math.random() * 300; endX = 1548 + Math.random() * 500; endY = 2432 + Math.random() * 300; break; case 1: // Diagonal from top-right to bottom-left startX = 1548 + Math.random() * 500; startY = -100 + Math.random() * 300; endX = -100 + Math.random() * 500; endY = 2432 + Math.random() * 300; break; case 2: // Horizontal across screen startX = -200; startY = Math.random() * 2732; endX = 2248; endY = startY + (Math.random() - 0.5) * 400; // Slight curve break; case 3: // Vertical or steep diagonal startX = Math.random() * 2048; startY = -200; endX = startX + (Math.random() - 0.5) * 800; endY = 2932; break; } var ray = game.addChild(new CosmicRay(startX, startY, endX, endY)); cosmicRays.push(ray); } } function spawnCosmicBeam() { // Rare spawning - very infrequent ethereal light beams if (cosmicBeams.length < 2) { // Maximum 2 beams at once for rarity var beam = game.addChild(new CosmicBeam()); cosmicBeams.push(beam); } } function triggerTemporalDisruption() { // Random multiplier between 0.5x and 1.5x temporalMultiplier = 0.5 + Math.random(); updateTemporalDisplay(); // Effect lasts 10 seconds LK.setTimeout(function () { temporalMultiplier = 1.0; updateTemporalDisplay(); }, 10000); LK.effects.flashScreen(0x4169e1, 1000); } function triggerNebulaColorEvolution() { // Dramatic color palette shift for all nebula clouds var evolutionColors = [[0x2c1b47, 0x3d2b5d], // Early: cool blues and purples [0x4a3373, 0x5d4088], // Mid: warmer purples [0x6b4ba6, 0x7b5bb6], // Advanced: vibrant violets [0x8a6bc4, 0x9370db], // Transcendent: warm violets with energy [0xa478d4, 0xb19cd9] // Ultimate: violet-green with golden hints ]; var currentColors = evolutionColors[Math.min(coreEvolutions, evolutionColors.length - 1)]; // Apply evolution to all nebula clouds with staggered timing for (var i = 0; i < nebulaClouds.length; i++) { var cloud = nebulaClouds[i]; var evolutionDelay = i * 500; // Stagger each cloud by 500ms var targetColor = currentColors[i % currentColors.length]; LK.setTimeout(function (cloudRef, color) { return function () { // Dramatic color transition tween(cloudRef.children[0], { tint: color }, { duration: 8000, // 8 second evolution easing: tween.easeInOut }); // Temporary scale pulse during evolution tween(cloudRef.children[0], { scaleX: cloudRef.baseScale * 1.3, scaleY: cloudRef.baseScale * 1.3 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(cloudRef.children[0], { scaleX: cloudRef.baseScale, scaleY: cloudRef.baseScale }, { duration: 6000, easing: tween.easeInOut }); } }); }; }(cloud, targetColor), evolutionDelay); } } function triggerCosmicTranscendence() { // Ultimate transformation - shift to warm violets and green hints var transcendentColors = [0xa478d4, 0xb19cd9, 0x98d982]; // Violet-green palette // Transform all cosmic elements for (var i = 0; i < nebulaClouds.length; i++) { var cloud = nebulaClouds[i]; var transcendentColor = transcendentColors[i % transcendentColors.length]; // Ultimate color transformation tween(cloud.children[0], { tint: transcendentColor }, { duration: 12000, // 12 second transcendence easing: tween.easeInOut }); // Cosmic energy surge effect tween(cloud.children[0], { alpha: 0.8, // Brighter during transcendence scaleX: cloud.baseScale * 1.5, scaleY: cloud.baseScale * 1.5 }, { duration: 3000, easing: tween.easeInOut, onFinish: function onFinish() { tween(cloud.children[0], { alpha: 0.4, scaleX: cloud.baseScale * 1.1, scaleY: cloud.baseScale * 1.1 }, { duration: 9000, easing: tween.easeInOut }); } }); } // Transform distant stars to match transcendent energy for (var i = 0; i < distantStars.length; i++) { var star = distantStars[i]; if (Math.random() < 0.6) { // 60% of stars participate tween(star.children[0], { tint: 0xffd700, // Golden energy alpha: 0.8, scaleX: 1.5, scaleY: 1.5 }, { duration: 6000, easing: tween.easeInOut, onFinish: function onFinish() { tween(star.children[0], { alpha: 0.4, scaleX: 0.8, scaleY: 0.8 }, { duration: 6000, easing: tween.easeInOut }); } }); } } } // Button handlers buyNodeButton.down = function (x, y, obj) { var cost = 50 + spireNodes.length * 25; if (luminaDust >= cost) { luminaDust -= cost; storage.luminaDust = luminaDust; var angle = spireNodes.length / (spireNodes.length + 1) * Math.PI * 2; var distance = 200 + spireNodes.length * 30; var node = game.addChild(new SpireNode(angle, distance)); spireNodes.push(node); storage.spireNodeCount = spireNodes.length; updateDustDisplay(); updateNodeCountDisplay(); LK.getSound('purchase').play(); // Update button cost display var newCost = 50 + spireNodes.length * 25; buyNodeButton.setText('Buy Spire Node\nCost: ' + newCost + ' Dust'); } }; upgradeClickButton.down = function (x, y, obj) { var cost = 100 * luminaCore.clickPower; if (luminaDust >= cost) { luminaDust -= cost; storage.luminaDust = luminaDust; luminaCore.clickPower++; storage.clickPower = luminaCore.clickPower; updateDustDisplay(); updateClickPowerDisplay(); LK.getSound('purchase').play(); // Update button cost display var newCost = 100 * luminaCore.clickPower; upgradeClickButton.setText('Upgrade Click\nCost: ' + newCost + ' Dust'); } }; // Initialize displays updateDustDisplay(); updateClickPowerDisplay(); updateNodeCountDisplay(); updateTemporalDisplay(); // Update button costs var nodeCost = 50 + spireNodes.length * 25; buyNodeButton.setText('Buy Spire Node\nCost: ' + nodeCost + ' Dust'); var clickCost = 100 * luminaCore.clickPower; upgradeClickButton.setText('Upgrade Click\nCost: ' + clickCost + ' Dust'); // Play ambient music LK.playMusic('cosmicAmbient'); // Initialize cosmic breathing cycle - creates universe-wide living rhythm var _cosmicBreathingCycle = function cosmicBreathingCycle() { var breathDuration = 25000 + Math.random() * 15000; // 25-40 second cycles var breathIntensity = 0.03 + Math.random() * 0.02; // Subtle breathing intensity var breathPhase = Math.random() * Math.PI * 2; // Apply cosmic breathing to all elements for unified living background for (var i = 0; i < nebulaClouds.length; i++) { var cloud = nebulaClouds[i]; var cloudBreathIntensity = breathIntensity * (0.8 + Math.random() * 0.4); tween(cloud.children[0], { alpha: cloud.children[0].alpha * (1.0 + cloudBreathIntensity), scaleX: cloud.baseScale * (1.0 + cloudBreathIntensity), scaleY: cloud.baseScale * (1.0 + cloudBreathIntensity * 0.7) }, { duration: breathDuration * 0.5, easing: tween.easeInOut, onFinish: function onFinish() { tween(cloud.children[0], { alpha: cloud.children[0].alpha * (1.0 - cloudBreathIntensity * 0.5), scaleX: cloud.baseScale * (1.0 - cloudBreathIntensity * 0.3), scaleY: cloud.baseScale * (1.0 - cloudBreathIntensity * 0.2) }, { duration: breathDuration * 0.5, easing: tween.easeInOut }); } }); } // Apply subtle breathing to distant stars for (var i = 0; i < distantStars.length; i++) { var star = distantStars[i]; if (Math.random() < 0.4) { // 40% of stars participate in cosmic breathing var starBreathIntensity = breathIntensity * 2.0; // Stars have more pronounced breathing tween(star.children[0], { alpha: star.children[0].alpha * (1.0 + starBreathIntensity), scaleX: star.children[0].scaleX * (1.0 + starBreathIntensity * 0.5), scaleY: star.children[0].scaleY * (1.0 + starBreathIntensity * 0.5) }, { duration: breathDuration * 0.6, easing: tween.easeInOut, onFinish: function onFinish() { tween(star.children[0], { alpha: star.children[0].alpha * (1.0 - starBreathIntensity * 0.7), scaleX: star.children[0].scaleX * (1.0 - starBreathIntensity * 0.3), scaleY: star.children[0].scaleY * (1.0 - starBreathIntensity * 0.3) }, { duration: breathDuration * 0.4, easing: tween.easeInOut }); } }); } } // Continue the cosmic breathing cycle infinitely LK.setTimeout(function () { _cosmicBreathingCycle(); }, breathDuration); }; // Start the cosmic breathing cycle with initial delay LK.setTimeout(function () { _cosmicBreathingCycle(); }, 5000); // Start after 5 seconds // Initialize starfield layer cosmic flow animation var _starfieldCosmicFlow = function starfieldCosmicFlow() { var flowDuration = 60000 + Math.random() * 30000; // 60-90 second cycles var flowIntensity = 0.01 + Math.random() * 0.005; // Very subtle flow // Create slow, constant movement across entire starfield for (var i = 0; i < distantStars.length; i++) { var star = distantStars[i]; // Calculate flow direction - gentle drift across screen var flowX = Math.cos(starfieldFlowDirection) * flowIntensity; var flowY = Math.sin(starfieldFlowDirection) * flowIntensity; // Apply extremely slow cosmic flow with tween for smooth movement tween(star, { x: star.x + flowX * 200, // Very slow movement over long duration y: star.y + flowY * 150 }, { duration: flowDuration, easing: tween.linear // Constant movement speed }); } // Gradually change flow direction for organic cosmic movement var newFlowDirection = starfieldFlowDirection + (Math.random() - 0.5) * 0.2; tween({ value: starfieldFlowDirection }, { value: newFlowDirection }, { duration: flowDuration, easing: tween.linear, onFinish: function onFinish() { starfieldFlowDirection = newFlowDirection; } }); // Continue the cosmic flow cycle LK.setTimeout(function () { _starfieldCosmicFlow(); }, flowDuration); }; // Start starfield cosmic flow with initial delay LK.setTimeout(function () { _starfieldCosmicFlow(); }, 10000); // Start after 10 seconds game.update = function () { // Handle flux void spawning if (LK.ticks >= nextFluxTime) { createFluxVoid(); nextFluxTime = LK.ticks + Math.random() * 1800 + 1200; // 20-50 seconds } // Handle temporal disruptions if (LK.ticks >= nextTemporalTime) { triggerTemporalDisruption(); nextTemporalTime = LK.ticks + Math.random() * 3600 + 1800; // 30-90 seconds } // Handle low-density cosmic particle spawning if (LK.ticks >= nextCosmicParticleTime) { spawnCosmicParticle(); nextCosmicParticleTime = LK.ticks + Math.random() * 1800 + 1200; // 20-50 seconds between spawns for low density } // Handle ethereal Lumina energy wisp spawning for permeating energy effect if (LK.ticks % 180 === 0) { // Every 3 seconds - regular ethereal energy emission spawnLuminaEnergyWisp(); } // Increased energy emission during Core activity if (LK.ticks % 60 === 0 && spireNodes.length > 0) { // Every second when nodes are active if (Math.random() < 0.3) { // 30% chance for additional ethereal energy spawnLuminaEnergyWisp(); } } // Clean up expired dust particles for (var i = dustParticles.length - 1; i >= 0; i--) { var particle = dustParticles[i]; particle.timer++; if (particle.timer >= particle.maxTime) { particle.destroy(); dustParticles.splice(i, 1); } } // Handle nebula cloud boundary wrapping for (var i = 0; i < nebulaClouds.length; i++) { var cloud = nebulaClouds[i]; // Wrap around screen boundaries if (cloud.x < -400) cloud.x = 2048 + 400; if (cloud.x > 2048 + 400) cloud.x = -400; if (cloud.y < -300) cloud.y = 2732 + 300; if (cloud.y > 2732 + 300) cloud.y = -300; } // Clean up cosmic particles that have drifted too far off screen for (var i = cosmicParticles.length - 1; i >= 0; i--) { var particle = cosmicParticles[i]; if (particle.x < -200 || particle.x > 2248 || particle.y < -200 || particle.y > 2932) { particle.destroy(); cosmicParticles.splice(i, 1); } } // Clean up Lumina energy wisps that have drifted too far off screen for (var i = luminaEnergyWisps.length - 1; i >= 0; i--) { var wisp = luminaEnergyWisps[i]; if (wisp.x < -300 || wisp.x > 2348 || wisp.y < -300 || wisp.y > 3032) { wisp.destroy(); luminaEnergyWisps.splice(i, 1); } } // Clean up cosmic beams that have completed traversal or expired for (var i = cosmicBeams.length - 1; i >= 0; i--) { var beam = cosmicBeams[i]; if (beam.x < -400 || beam.x > 2448 || beam.y < -400 || beam.y > 3132) { beam.destroy(); cosmicBeams.splice(i, 1); } } // Handle very occasional cosmic ray spawning - rare, brief light beams if (LK.ticks % 1200 === 0) { // Every 20 seconds check for potential spawn if (Math.random() < 0.15) { // 15% chance - very rare occurrence spawnCosmicRay(); } } // Handle extremely rare cosmic beam spawning - ethereal light traversal if (LK.ticks % 2400 === 0) { // Every 40 seconds check for potential spawn if (Math.random() < 0.08) { // 8% chance - extremely rare occurrence spawnCosmicBeam(); } } // Enhanced cosmic ray spawning during core evolution events if (coreEvolutions > 0 && LK.ticks % 600 === 0) { // Every 10 seconds during evolutions if (Math.random() < 0.08) { // 8% chance for evolution-enhanced rays spawnCosmicRay(); } } // Core Evolution Detection - significant milestones trigger color transitions var totalNodes = spireNodes.length; var dustLevel = Math.floor(luminaDust / 1000); var coreLevel = luminaCore.coreLevel; var clickLevel = luminaCore.clickPower; // Check for significant Core Evolutions (major milestones) var evolutionThreshold = 10000 + coreEvolutions * 15000; // Increasing thresholds var transcendenceThreshold = 50000 + transcendenceLevel * 100000; if (luminaDust >= evolutionThreshold && luminaDust > lastEvolutionCheck) { coreEvolutions++; lastEvolutionCheck = luminaDust; storage.coreEvolutions = coreEvolutions; storage.lastEvolutionCheck = lastEvolutionCheck; // Trigger dramatic nebula color palette shift triggerNebulaColorEvolution(); LK.effects.flashScreen(0x9370db, 2000); // Purple evolution flash // Enhanced ethereal energy emission during evolution for (var i = 0; i < 8; i++) { // Burst of ethereal energy LK.setTimeout(function (index) { return function () { spawnLuminaEnergyWisp(); }; }(i), i * 200); // Staggered spawning over 1.6 seconds } // Enhance existing energy wisps during evolution for (var i = 0; i < luminaEnergyWisps.length; i++) { var wisp = luminaEnergyWisps[i]; tween(wisp.children[0], { alpha: 0.4, // Brighter during evolution scaleX: 1.5, scaleY: 1.5, tint: 0xffd700 // Golden energy during evolution }, { duration: 3000, easing: tween.easeInOut, onFinish: function onFinish() { tween(wisp.children[0], { alpha: 0.15, scaleX: 0.7, scaleY: 0.7, tint: 0x9370db // Return to purple }, { duration: 2000, easing: tween.easeInOut }); } }); } } // Check for Transcendence events (ultimate transformations) if (luminaDust >= transcendenceThreshold && totalNodes >= 20) { transcendenceLevel++; storage.transcendenceLevel = transcendenceLevel; // Major cosmic transformation triggerCosmicTranscendence(); LK.effects.flashScreen(0xffd700, 3000); // Golden transcendence flash } // Update cosmic color phase based on evolutions and transcendence var newColorPhase = Math.min(4, coreEvolutions + transcendenceLevel); if (newColorPhase !== currentColorPhase) { currentColorPhase = newColorPhase; storage.colorPhase = currentColorPhase; // Gradually shift background color based on Core's growing influence var backgroundColors = [0x1a0d2e, // Base: deep purple void 0x221544, // Evolution 1: slightly warmer purple 0x2a1d5a, // Evolution 2: deeper purple with warmth 0x32256f, // Evolution 3: warmer purple with golden hints 0x4a3373 // Transcendence: vibrant purple-violet ]; var targetBg = backgroundColors[currentColorPhase]; tween(game, { backgroundColor: targetBg }, { duration: 5000, // Longer transition for evolution easing: tween.easeInOut }); } // Create subtle temporal distortion waves that affect the entire universe if (LK.ticks % 2400 === 0) { // Every 40 seconds // Create temporal ripple effect that distorts space-time var temporalIntensity = 0.02 + Math.random() * 0.03; var temporalDuration = 5000 + Math.random() * 3000; // 5-8 seconds // Apply temporal distortion to all nebula clouds for (var i = 0; i < nebulaClouds.length; i++) { var cloud = nebulaClouds[i]; var distortionPhase = Math.random() * Math.PI * 2; // Create temporal wave effect tween(cloud, { scaleX: cloud.baseScale * (1.0 + temporalIntensity), scaleY: cloud.baseScale * (1.0 - temporalIntensity * 0.5), rotation: cloud.rotation + (Math.random() - 0.5) * 0.1 }, { duration: temporalDuration * 0.3, easing: tween.easeInOut, onFinish: function onFinish() { // Return to normal with slight variation tween(cloud, { scaleX: cloud.baseScale * (0.95 + Math.random() * 0.1), scaleY: cloud.baseScale * (0.95 + Math.random() * 0.1) }, { duration: temporalDuration * 0.7, easing: tween.easeInOut }); } }); } // Apply temporal distortion to distant stars for (var i = 0; i < distantStars.length; i++) { var star = distantStars[i]; if (Math.random() < 0.3) { // Only affect 30% of stars for subtle effect var originalAlpha = star.children[0].alpha; tween(star.children[0], { alpha: originalAlpha * (1.5 + Math.random()), scaleX: 1.0 + Math.random() * 0.5, scaleY: 1.0 + Math.random() * 0.5 }, { duration: temporalDuration * 0.4, easing: tween.easeInOut, onFinish: function onFinish() { tween(star.children[0], { alpha: originalAlpha, scaleX: 0.5 + Math.random() * 0.5, scaleY: 0.5 + Math.random() * 0.5 }, { duration: temporalDuration * 0.6, easing: tween.easeInOut }); } }); } } // Create subtle cosmic wind effect LK.effects.flashScreen(0x4a3373, 2000); // Very subtle purple flash } // Add cosmic energy fluctuations that create living background if (LK.ticks % 1800 === 0) { // Every 30 seconds // Create energy wave that affects all cosmic elements var energyWaveIntensity = 0.1 + Math.random() * 0.1; var energyDuration = 8000 + Math.random() * 4000; // 8-12 seconds // Apply energy fluctuation to lumina core tween(luminaCore.children[0], { tint: 0x9370db, // Brighter purple during energy wave scaleX: luminaCore.baseScale * (1.0 + energyWaveIntensity), scaleY: luminaCore.baseScale * (1.0 + energyWaveIntensity) }, { duration: energyDuration * 0.5, easing: tween.easeInOut, onFinish: function onFinish() { tween(luminaCore.children[0], { tint: 0x6a5acd, // Return to normal scaleX: luminaCore.baseScale, scaleY: luminaCore.baseScale }, { duration: energyDuration * 0.5, easing: tween.easeInOut }); } }); // Apply energy wave to spire nodes for (var i = 0; i < spireNodes.length; i++) { var node = spireNodes[i]; if (!node.isDecaying) { tween(node.children[0], { tint: 0x00ffff, // Bright cyan during energy wave scaleX: 1.2, scaleY: 1.2 }, { duration: energyDuration * 0.3, easing: tween.easeInOut, onFinish: function onFinish() { tween(node.children[0], { tint: 0xffffff, // Return to normal scaleX: 1.0, scaleY: 1.0 }, { duration: energyDuration * 0.7, easing: tween.easeInOut }); } }); } } } // Add subtle reality distortion that affects space itself if (LK.ticks % 3600 === 0) { // Every 60 seconds // Create space-time distortion effect var distortionIntensity = 0.05 + Math.random() * 0.05; var distortionDuration = 12000 + Math.random() * 6000; // 12-18 seconds // Apply reality distortion to entire game space tween(game, { scaleX: 1.0 + distortionIntensity, scaleY: 1.0 - distortionIntensity * 0.5 }, { duration: distortionDuration * 0.4, easing: tween.easeInOut, onFinish: function onFinish() { tween(game, { scaleX: 1.0 - distortionIntensity * 0.5, scaleY: 1.0 + distortionIntensity * 0.3 }, { duration: distortionDuration * 0.4, easing: tween.easeInOut, onFinish: function onFinish() { tween(game, { scaleX: 1.0, scaleY: 1.0 }, { duration: distortionDuration * 0.2, easing: tween.easeInOut }); } }); } }); } // Save game state periodically if (LK.ticks % 300 === 0) { // Every 5 seconds storage.luminaDust = luminaDust; storage.clickPower = luminaCore.clickPower; storage.spireNodeCount = spireNodes.length; storage.colorPhase = currentColorPhase; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CosmicBeam = Container.expand(function () {
var self = Container.call(this);
// Create beam using luminaDust asset as stretched light beam
var beamGraphics = self.attachAsset('luminaDust', {
anchorX: 0.0,
anchorY: 0.5
});
// Choose random traversal direction (horizontal, vertical, or diagonal)
var traversalType = Math.floor(Math.random() * 3);
var startX, startY, endX, endY;
switch (traversalType) {
case 0:
// Horizontal traversal
startX = -300;
startY = Math.random() * 2732;
endX = 2348;
endY = startY + (Math.random() - 0.5) * 200; // Slight curve
break;
case 1:
// Vertical traversal
startX = Math.random() * 2048;
startY = -300;
endX = startX + (Math.random() - 0.5) * 200;
endY = 3032;
break;
case 2:
// Diagonal traversal
if (Math.random() < 0.5) {
// Top-left to bottom-right
startX = -300;
startY = -300;
endX = 2348;
endY = 3032;
} else {
// Top-right to bottom-left
startX = 2348;
startY = -300;
endX = -300;
endY = 3032;
}
break;
}
// Calculate beam properties
var deltaX = endX - startX;
var deltaY = endY - startY;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
var angle = Math.atan2(deltaY, deltaX);
// Configure beam appearance
beamGraphics.scaleX = distance / 20; // Stretch to cover full traversal
beamGraphics.scaleY = 0.05 + Math.random() * 0.05; // Very thin beam with soft edges
beamGraphics.rotation = angle;
beamGraphics.alpha = 0.0; // Start invisible
// Very faint ethereal colors for subtle appearance
var beamColors = [0xffffff,
// Pure white
0xe6f0ff,
// Cool blue-white
0xfff4e6,
// Warm golden-white
0xf0e6ff,
// Purple-white
0xe6fff0 // Green-white
];
var colorIndex = Math.floor(Math.random() * beamColors.length);
beamGraphics.tint = beamColors[colorIndex];
// Beam lifecycle properties
self.lifeSpan = 180 + Math.random() * 240; // 3-7 seconds at 60fps
self.age = 0;
self.materializationDuration = 30 + Math.random() * 30; // 0.5-1 second materialization
self.fadeDuration = 60 + Math.random() * 60; // 1-2 second fade out
self.traversalSpeed = 0.8 + Math.random() * 0.4; // Slow traversal speed
// Position at start
self.x = startX;
self.y = startY;
// Store traversal target
self.targetX = endX;
self.targetY = endY;
self.traversalProgress = 0.0;
// Slow materialization phase
tween(beamGraphics, {
alpha: 0.03 + Math.random() * 0.05 // Very low opacity maximum
}, {
duration: self.materializationDuration * 16.67,
// Convert to milliseconds
easing: tween.easeOut
});
self.update = function () {
self.age++;
// Slow traversal across screen
if (self.age > self.materializationDuration) {
self.traversalProgress += self.traversalSpeed / distance;
self.x = startX + (endX - startX) * self.traversalProgress;
self.y = startY + (endY - startY) * self.traversalProgress;
}
// Begin fade out near end of lifespan
if (self.age > self.lifeSpan - self.fadeDuration) {
var fadeProgress = (self.lifeSpan - self.age) / self.fadeDuration;
beamGraphics.alpha *= fadeProgress;
}
// Subtle flickering during visibility for ethereal effect
if (beamGraphics.alpha > 0.01) {
var flicker = 0.85 + Math.sin(self.age * 0.2) * 0.15;
beamGraphics.alpha *= flicker;
}
// Remove when expired or off-screen
if (self.age >= self.lifeSpan || self.traversalProgress >= 1.0) {
self.destroy();
for (var i = cosmicBeams.length - 1; i >= 0; i--) {
if (cosmicBeams[i] === self) {
cosmicBeams.splice(i, 1);
break;
}
}
}
};
return self;
});
var CosmicParticle = Container.expand(function (x, y) {
var self = Container.call(this);
var particleGraphics = self.attachAsset('luminaDust', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
// Particle properties for curving movement
self.curvePhase = Math.random() * Math.PI * 2;
self.curveSpeed = 0.005 + Math.random() * 0.003; // Very slow curving motion
self.curveAmplitude = 50 + Math.random() * 100; // Gentle curve amplitude
self.driftX = (Math.random() - 0.5) * 0.3; // Slow horizontal drift
self.driftY = (Math.random() - 0.5) * 0.2; // Slow vertical drift
self.lifeSpan = 1800 + Math.random() * 1200; // 30-50 seconds at 60fps
self.age = 0;
self.fadeInDuration = 300 + Math.random() * 300; // 5-10 seconds fade in
self.fadeOutStart = self.lifeSpan - 600; // Start fading out 10 seconds before end
// Initialize with very low opacity
particleGraphics.alpha = 0.0;
particleGraphics.scaleX = 0.3 + Math.random() * 0.4; // Small, soft particles
particleGraphics.scaleY = particleGraphics.scaleX;
// Match nebula palette or slight contrast
var particleColors = [0xffd700,
// Golden (slight contrast to purple nebula)
0xe6e6ff,
// Soft blue-white (matches cool nebula tones)
0xddd4ff,
// Purple-white (matches nebula palette)
0xffd4e6,
// Warm pink-white (slight contrast)
0xb19cd9 // Violet (matches evolved nebula)
];
var colorIndex = Math.min(currentColorPhase, particleColors.length - 1);
particleGraphics.tint = particleColors[colorIndex];
self.update = function () {
self.age++;
// Gentle curving movement along curved paths
var curveOffset = Math.sin(self.age * self.curveSpeed + self.curvePhase) * self.curveAmplitude;
self.x += self.driftX + Math.cos(self.age * self.curveSpeed * 0.7) * 0.1;
self.y += self.driftY + Math.sin(self.age * self.curveSpeed * 0.5) * 0.1;
// Add gentle curve displacement
var baseX = self.x + curveOffset * 0.01;
var baseY = self.y + Math.cos(self.age * self.curveSpeed * 0.8 + self.curvePhase) * self.curveAmplitude * 0.008;
self.x = baseX;
self.y = baseY;
// Fade in/out lifecycle - no abrupt appearance/disappearance
if (self.age < self.fadeInDuration) {
// Gradual fade in
var fadeInProgress = self.age / self.fadeInDuration;
particleGraphics.alpha = (0.05 + Math.random() * 0.08) * fadeInProgress; // Very low opacity
} else if (self.age > self.fadeOutStart) {
// Gradual fade out
var fadeOutProgress = (self.lifeSpan - self.age) / (self.lifeSpan - self.fadeOutStart);
particleGraphics.alpha = (0.05 + Math.random() * 0.08) * fadeOutProgress;
} else {
// Subtle opacity fluctuation during main life
var opacityFluctuation = 0.05 + Math.sin(self.age * 0.02) * 0.03;
particleGraphics.alpha = Math.max(0.02, Math.min(0.13, opacityFluctuation));
}
// Gentle scale breathing
var scaleBreathing = 1.0 + Math.sin(self.age * 0.008) * 0.1;
particleGraphics.scaleX = (0.3 + Math.random() * 0.4) * scaleBreathing;
particleGraphics.scaleY = particleGraphics.scaleX;
// Soft rotation
particleGraphics.rotation += 0.001;
// Remove when lifespan is complete
if (self.age >= self.lifeSpan) {
self.destroy();
for (var i = cosmicParticles.length - 1; i >= 0; i--) {
if (cosmicParticles[i] === self) {
cosmicParticles.splice(i, 1);
break;
}
}
}
};
return self;
});
var CosmicRay = Container.expand(function (startX, startY, endX, endY) {
var self = Container.call(this);
// Create ray using luminaDust asset as a stretched beam
var rayGraphics = self.attachAsset('luminaDust', {
anchorX: 0.0,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
// Calculate ray properties
var deltaX = endX - startX;
var deltaY = endY - startY;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
var angle = Math.atan2(deltaY, deltaX);
// Configure ray appearance
rayGraphics.scaleX = distance / 20; // Stretch to cover distance
rayGraphics.scaleY = 0.1 + Math.random() * 0.1; // Very thin beam
rayGraphics.rotation = angle;
rayGraphics.alpha = 0.0; // Start invisible
// Very faint cosmic colors
var rayColors = [0xffffff,
// Pure white
0xe6e6ff,
// Cool blue-white
0xffd4e6,
// Warm pink-white
0xddd4ff,
// Purple-white
0xfff4d4 // Golden-white
];
var colorIndex = Math.floor(Math.random() * rayColors.length);
rayGraphics.tint = rayColors[colorIndex];
self.lifeSpan = 120 + Math.random() * 180; // 2-5 seconds at 60fps
self.age = 0;
self.fadeInDuration = 20 + Math.random() * 20; // Quick fade in
self.fadeOutStart = self.lifeSpan - 30; // Start fading out early
// Animate ray appearance - brief flash effect
tween(rayGraphics, {
alpha: 0.08 + Math.random() * 0.12 // Very faint maximum opacity
}, {
duration: 300 + Math.random() * 200,
// Quick appearance
easing: tween.easeOut,
onFinish: function onFinish() {
// Hold briefly then fade out
LK.setTimeout(function () {
tween(rayGraphics, {
alpha: 0.0
}, {
duration: 500 + Math.random() * 300,
// Slow fade out
easing: tween.easeIn
});
}, 200 + Math.random() * 400);
}
});
self.update = function () {
self.age++;
// Subtle flickering during visibility
if (rayGraphics.alpha > 0.02) {
var flicker = 0.9 + Math.sin(self.age * 0.3) * 0.1;
rayGraphics.alpha *= flicker;
}
// Remove when expired
if (self.age >= self.lifeSpan) {
self.destroy();
for (var i = cosmicRays.length - 1; i >= 0; i--) {
if (cosmicRays[i] === self) {
cosmicRays.splice(i, 1);
break;
}
}
}
};
return self;
});
var DistantStar = Container.expand(function (x, y) {
var self = Container.call(this);
var starGraphics = self.attachAsset('distantStar', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.driftSpeedX = (Math.random() - 0.5) * 0.1;
self.driftSpeedY = (Math.random() - 0.5) * 0.1;
self.shimmerPhase = Math.random() * Math.PI * 2;
self.shimmerSpeed = 0.01 + Math.random() * 0.02;
// Extremely slow cosmic flow movement - barely perceptible
self.cosmicFlowX = (Math.random() - 0.5) * 0.02; // Very slow horizontal flow
self.cosmicFlowY = (Math.random() - 0.5) * 0.015; // Very slow vertical flow
self.spiralAngle = Math.random() * Math.PI * 2; // Initial spiral position
self.spiralSpeed = 0.0001 + Math.random() * 0.0001; // Extremely slow spiral
self.spiralRadius = Math.random() * 0.5; // Spiral influence radius
starGraphics.alpha = 0.2 + Math.random() * 0.4;
starGraphics.scaleX = 0.5 + Math.random() * 0.5;
starGraphics.scaleY = starGraphics.scaleX;
// Star twinkling properties for independent brightness fluctuations
self.twinkleChance = 0.003 + Math.random() * 0.002; // Small percentage chance per frame
self.isTwinkling = false;
self.baseBrightness = starGraphics.alpha;
self.twinkleIntensity = 0.3 + Math.random() * 0.5; // Random twinkling intensity
self.update = function () {
// Very slow drift movement
self.x += self.driftSpeedX;
self.y += self.driftSpeedY;
// Extremely slow cosmic flow - creates impression of vast cosmic distances
// Only noticeable after several seconds of observation
self.x += self.cosmicFlowX;
self.y += self.cosmicFlowY;
// Add subtle spiral movement flowing outward from center
var centerX = 1024;
var centerY = 1366;
var spiralX = Math.cos(self.spiralAngle) * self.spiralRadius;
var spiralY = Math.sin(self.spiralAngle) * self.spiralRadius;
self.x += spiralX;
self.y += spiralY;
self.spiralAngle += self.spiralSpeed;
// Subtle shimmer animation
var shimmer = 0.8 + Math.sin(LK.ticks * self.shimmerSpeed + self.shimmerPhase) * 0.3;
starGraphics.alpha = (0.2 + Math.random() * 0.4) * shimmer;
// Independent star twinkling system - asynchronous brightness fluctuations
if (!self.isTwinkling && Math.random() < self.twinkleChance) {
// Start twinkling animation
self.isTwinkling = true;
// Create random twinkling pattern with varying durations
var twinkleDuration = 200 + Math.random() * 400; // 200-600ms
var targetBrightness = self.baseBrightness * (1.0 + self.twinkleIntensity);
// Brightness increase phase
tween(starGraphics, {
alpha: targetBrightness,
scaleX: starGraphics.scaleX * (1.0 + self.twinkleIntensity * 0.3),
scaleY: starGraphics.scaleY * (1.0 + self.twinkleIntensity * 0.3)
}, {
duration: twinkleDuration * 0.3,
easing: tween.easeOut,
onFinish: function onFinish() {
// Brightness decrease phase
tween(starGraphics, {
alpha: self.baseBrightness * (0.7 + Math.random() * 0.3),
scaleX: starGraphics.scaleX * (0.8 + Math.random() * 0.2),
scaleY: starGraphics.scaleY * (0.8 + Math.random() * 0.2)
}, {
duration: twinkleDuration * 0.7,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Reset twinkling state
self.isTwinkling = false;
// Occasionally create a double-twinkle effect
if (Math.random() < 0.2) {
// Quick second twinkle after short delay
LK.setTimeout(function () {
if (!self.isTwinkling) {
self.isTwinkling = true;
tween(starGraphics, {
alpha: targetBrightness * 0.6,
scaleX: starGraphics.scaleX * 1.1,
scaleY: starGraphics.scaleY * 1.1
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isTwinkling = false;
}
});
}
}, 100 + Math.random() * 200);
}
}
});
}
});
}
// Dynamic color tinting based on cosmic progression
var starTints = [0xffffff,
// Base: pure white
0xe6e6ff,
// Phase 1: cool blue-white
0xddd4ff,
// Phase 2: purple-white
0xffd4e6 // Phase 3: warm purple-pink
];
var currentTint = starTints[Math.min(currentColorPhase, starTints.length - 1)];
starGraphics.tint = currentTint;
// Wrap around screen boundaries
if (self.x < -10) self.x = 2058;
if (self.x > 2058) self.x = -10;
if (self.y < -10) self.y = 2742;
if (self.y > 2742) self.y = -10;
};
return self;
});
var FluxVoid = Container.expand(function () {
var self = Container.call(this);
var voidGraphics = self.attachAsset('fluxVoid', {
anchorX: 0.5,
anchorY: 0.5
});
self.duration = 300; // 5 seconds
self.timer = 0;
self.x = Math.random() * 1500 + 274;
self.y = Math.random() * 2000 + 366;
self.down = function (x, y, obj) {
// 70% chance for reward, 30% for penalty
var isReward = Math.random() < 0.7;
var amount = Math.floor(luminaDust * 0.2); // 20% of current dust
if (isReward) {
luminaDust += amount;
LK.effects.flashObject(self, 0x00ff00, 500);
} else {
luminaDust = Math.max(0, luminaDust - amount);
LK.effects.flashObject(self, 0xff0000, 500);
}
storage.luminaDust = luminaDust;
updateDustDisplay();
LK.getSound('fluxEvent').play();
// Remove this void
self.destroy();
for (var i = fluxVoids.length - 1; i >= 0; i--) {
if (fluxVoids[i] === self) {
fluxVoids.splice(i, 1);
break;
}
}
};
self.update = function () {
self.timer++;
// Pulsing effect
var pulse = 1.0 + Math.sin(LK.ticks * 0.1) * 0.3;
voidGraphics.scaleX = pulse;
voidGraphics.scaleY = pulse;
// Fade out near end
if (self.timer > self.duration - 60) {
voidGraphics.alpha = (self.duration - self.timer) / 60;
}
// Remove when expired
if (self.timer >= self.duration) {
self.destroy();
for (var i = fluxVoids.length - 1; i >= 0; i--) {
if (fluxVoids[i] === self) {
fluxVoids.splice(i, 1);
break;
}
}
}
};
return self;
});
var LuminaCore = Container.expand(function () {
var self = Container.call(this);
var coreGraphics = self.attachAsset('luminaCore', {
anchorX: 0.5,
anchorY: 0.5
});
self.baseScale = 1.0;
self.clickPower = storage.clickPower || 1;
self.coreLevel = storage.coreLevel || 1;
self.down = function (x, y, obj) {
// Click effect
tween(coreGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100
});
tween(coreGraphics, {
scaleX: self.baseScale,
scaleY: self.baseScale
}, {
duration: 100
});
// Generate lumina dust
var dustGenerated = self.clickPower * temporalMultiplier;
luminaDust += dustGenerated;
storage.luminaDust = luminaDust;
// Spawn visual dust particle
spawnDustParticle(self.x, self.y);
LK.getSound('coreClick').play();
// Update displays
updateDustDisplay();
};
self.update = function () {
// Gentle pulsing animation
var pulseScale = 1.0 + Math.sin(LK.ticks * 0.05) * 0.1;
coreGraphics.scaleX = self.baseScale * pulseScale;
coreGraphics.scaleY = self.baseScale * pulseScale;
// Color shifting based on core level
var colorShift = Math.sin(LK.ticks * 0.02) * 0.3;
coreGraphics.tint = 0x6a5acd + colorShift * 0x101010;
};
return self;
});
var LuminaEnergyWisp = Container.expand(function (x, y) {
var self = Container.call(this);
var wispGraphics = self.attachAsset('luminaDust', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
// Ethereal movement properties
self.flowSpeed = 0.3 + Math.random() * 0.5; // Gentle flowing speed
self.flowDirection = Math.random() * Math.PI * 2; // Random initial direction
self.flowPhase = Math.random() * Math.PI * 2;
self.waveAmplitude = 30 + Math.random() * 40; // Sine wave amplitude for ethereal movement
self.waveFrequency = 0.008 + Math.random() * 0.004; // Wave frequency for organic flow
self.lifeSpan = 1800 + Math.random() * 1800; // 30-60 seconds at 60fps
self.age = 0;
// Energy attraction to Lumina Core for permeating effect
self.coreAttraction = 0.02 + Math.random() * 0.01; // Subtle attraction force
self.orbitRadius = 150 + Math.random() * 200; // Preferred orbit distance
self.spiralTendency = (Math.random() - 0.5) * 0.003; // Slight spiral movement
// Visual properties for ethereal appearance
wispGraphics.alpha = 0.0; // Start invisible
wispGraphics.scaleX = 0.4 + Math.random() * 0.3; // Small ethereal particles
wispGraphics.scaleY = wispGraphics.scaleX;
wispGraphics.tint = 0x9370db; // Lumina purple energy color
// Fade in effect
tween(wispGraphics, {
alpha: 0.15 + Math.random() * 0.15 // Subtle ethereal visibility
}, {
duration: 1000 + Math.random() * 1000,
easing: tween.easeOut
});
self.update = function () {
self.age++;
// Ethereal flowing movement with wave patterns
var waveOffsetX = Math.sin(self.age * self.waveFrequency + self.flowPhase) * self.waveAmplitude;
var waveOffsetY = Math.cos(self.age * self.waveFrequency * 0.7 + self.flowPhase) * self.waveAmplitude * 0.6;
// Flow in direction with ethereal wave motion
self.x += Math.cos(self.flowDirection) * self.flowSpeed + waveOffsetX * 0.01;
self.y += Math.sin(self.flowDirection) * self.flowSpeed + waveOffsetY * 0.01;
// Subtle attraction to Lumina Core for energy permeation effect
var coreX = 1024;
var coreY = 1366;
var distanceToCore = Math.sqrt((self.x - coreX) * (self.x - coreX) + (self.y - coreY) * (self.y - coreY));
// Apply gentle attraction when not too close
if (distanceToCore > self.orbitRadius) {
var attractionX = (coreX - self.x) / distanceToCore * self.coreAttraction;
var attractionY = (coreY - self.y) / distanceToCore * self.coreAttraction;
self.x += attractionX;
self.y += attractionY;
}
// Add subtle spiral movement around core
var angleToCore = Math.atan2(self.y - coreY, self.x - coreX);
angleToCore += self.spiralTendency;
var spiralX = coreX + Math.cos(angleToCore) * distanceToCore;
var spiralY = coreY + Math.sin(angleToCore) * distanceToCore;
self.x += (spiralX - self.x) * 0.01; // Very subtle spiral influence
self.y += (spiralY - self.y) * 0.01;
// Ethereal pulsing and energy fluctuation
var energyPulse = 0.7 + Math.sin(self.age * 0.03 + self.flowPhase) * 0.3;
var energyFlicker = 0.8 + Math.sin(self.age * 0.08) * 0.2;
wispGraphics.alpha *= energyPulse * energyFlicker;
// Subtle scale breathing for ethereal effect
var scaleBreathing = 1.0 + Math.sin(self.age * 0.02 + self.flowPhase) * 0.15;
wispGraphics.scaleX = (0.4 + Math.random() * 0.3) * scaleBreathing;
wispGraphics.scaleY = wispGraphics.scaleX;
// Gentle rotation to enhance ethereal movement
wispGraphics.rotation += 0.005 + Math.sin(self.age * 0.01) * 0.003;
// Color shifting for energy effect - hints at Lumina Core's influence
var colorShift = Math.sin(self.age * 0.015) * 0.1;
var r = 0.58 + colorShift; // Purple base with shifting
var g = 0.44 + colorShift * 0.5;
var b = 0.86 + colorShift * 0.3;
var shiftedColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255);
wispGraphics.tint = shiftedColor;
// Fade out near end of lifespan
if (self.age > self.lifeSpan - 600) {
// Last 10 seconds
var fadeProgress = (self.lifeSpan - self.age) / 600;
wispGraphics.alpha *= fadeProgress;
}
// Remove when expired
if (self.age >= self.lifeSpan) {
self.destroy();
for (var i = luminaEnergyWisps.length - 1; i >= 0; i--) {
if (luminaEnergyWisps[i] === self) {
luminaEnergyWisps.splice(i, 1);
break;
}
}
}
};
return self;
});
var NebulaCloud = Container.expand(function (x, y, scale, speed) {
var self = Container.call(this);
var cloudGraphics = self.attachAsset('nebulaCloud', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.baseScale = scale || 1.0;
self.speed = speed || 0.001;
self.phaseOffset = Math.random() * Math.PI * 2;
cloudGraphics.scaleX = self.baseScale;
cloudGraphics.scaleY = self.baseScale;
cloudGraphics.alpha = 0.3;
// Undulation properties for organic texture shifting
self.undulationPhaseX = Math.random() * Math.PI * 2;
self.undulationPhaseY = Math.random() * Math.PI * 2;
self.undulationSpeedX = 0.003 + Math.random() * 0.002; // Very slow undulation
self.undulationSpeedY = 0.002 + Math.random() * 0.003;
self.undulationIntensity = 0.15 + Math.random() * 0.1; // Subtle intensity variation
self.colorShiftPhase = Math.random() * Math.PI * 2;
self.colorShiftSpeed = 0.001 + Math.random() * 0.0005; // Very slow color blending
self.expansionPhase = Math.random() * Math.PI * 2;
self.expansionSpeed = 0.0008 + Math.random() * 0.0004; // Slow expansion/contraction
// Initialize very slow breathing/swirling tween animation
self.breathingCycle = function () {
// Slow breathing scale animation (8-12 second cycles)
var breathDuration = 8000 + Math.random() * 4000; // 8-12 seconds
var breathScale = 0.95 + Math.random() * 0.1; // Subtle scale variation
tween(cloudGraphics, {
scaleX: self.baseScale * breathScale,
scaleY: self.baseScale * breathScale * 0.8
}, {
duration: breathDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Breathe back out
tween(cloudGraphics, {
scaleX: self.baseScale,
scaleY: self.baseScale * 0.8
}, {
duration: breathDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue the breathing cycle
self.breathingCycle();
}
});
}
});
};
// Start the breathing cycle
self.breathingCycle();
// Initialize continuous undulation animation system
self.undulationCycle = function () {
// Create continuous, non-looping undulation with varying parameters
var undulationDuration = 45000 + Math.random() * 30000; // 45-75 seconds for very slow movement
var targetScaleX = self.baseScale * (0.7 + Math.random() * 0.6); // Wide range of scale variation
var targetScaleY = self.baseScale * (0.8 + Math.random() * 0.4); // Different Y scaling for organic feel
var targetAlpha = 0.2 + Math.random() * 0.3; // Subtle alpha variation
// Create organic, flowing undulation with easing
tween(cloudGraphics, {
scaleX: targetScaleX,
scaleY: targetScaleY,
alpha: targetAlpha
}, {
duration: undulationDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue with new random parameters for infinite variation
self.undulationCycle();
}
});
// Add secondary undulation layer for more complex movement
LK.setTimeout(function () {
var secondaryDuration = 35000 + Math.random() * 25000; // Slightly different timing
var secondaryScaleX = self.baseScale * (0.8 + Math.random() * 0.4);
var secondarySkew = (Math.random() - 0.5) * 0.3; // Add subtle skewing effect
tween(cloudGraphics, {
scaleX: secondaryScaleX,
rotation: cloudGraphics.rotation + secondarySkew
}, {
duration: secondaryDuration,
easing: tween.easeInOut
});
}, undulationDuration * 0.3); // Offset timing for layered effect
};
// Start undulation cycle with random delay
LK.setTimeout(function () {
self.undulationCycle();
}, Math.random() * 10000);
// Add subtle swirling motion with tween
self.swirlingCycle = function () {
var swirlingDuration = 15000 + Math.random() * 10000; // 15-25 seconds
var swirlingIntensity = 20 + Math.random() * 30; // Subtle movement range
var targetX = self.x + (Math.random() - 0.5) * swirlingIntensity;
var targetY = self.y + (Math.random() - 0.5) * swirlingIntensity;
tween(self, {
x: targetX,
y: targetY
}, {
duration: swirlingDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue the swirling cycle
self.swirlingCycle();
}
});
};
// Start the swirling cycle with a random delay
LK.setTimeout(function () {
self.swirlingCycle();
}, Math.random() * 5000);
self.update = function () {
// Gentle floating movement
self.x += Math.sin(LK.ticks * self.speed + self.phaseOffset) * 0.2;
self.y += Math.cos(LK.ticks * self.speed * 0.7 + self.phaseOffset) * 0.15;
// Continuous organic undulation - creates flowing, shifting texture effect
var undulationX = Math.sin(LK.ticks * self.undulationSpeedX + self.undulationPhaseX) * self.undulationIntensity;
var undulationY = Math.cos(LK.ticks * self.undulationSpeedY + self.undulationPhaseY) * self.undulationIntensity;
var undulationScale = 1.0 + Math.sin(LK.ticks * self.undulationSpeedX * 0.5 + self.undulationPhaseX) * 0.08;
// Apply undulation to create organic texture shifting
cloudGraphics.scaleX *= (1.0 + undulationX) * undulationScale;
cloudGraphics.scaleY *= (1.0 + undulationY) * undulationScale * 0.8;
// Slow expansion/contraction cycles - simulates breathing nebula
var expansionCycle = Math.sin(LK.ticks * self.expansionSpeed + self.expansionPhase) * 0.12;
cloudGraphics.scaleX *= 1.0 + expansionCycle;
cloudGraphics.scaleY *= 1.0 + expansionCycle * 0.7;
// Continuous color blending and shifting for internal wisps effect
var colorWaveR = Math.sin(LK.ticks * self.colorShiftSpeed + self.colorShiftPhase) * 0.15;
var colorWaveG = Math.cos(LK.ticks * self.colorShiftSpeed * 1.3 + self.colorShiftPhase) * 0.1;
var colorWaveB = Math.sin(LK.ticks * self.colorShiftSpeed * 0.8 + self.colorShiftPhase + Math.PI) * 0.2;
// Progressive color palette with Core evolution-based transitions
var progressiveColors = [0x2c1b47,
// Base: dark purple-blue
0x3d2b5d,
// Evolution 1: deeper purple
0x4a3373,
// Evolution 2: warmer purple
0x6b4ba6,
// Evolution 3: vibrant violet
0x8a6bc4 // Transcendence: warm violet with energy
];
var baseColor = progressiveColors[Math.min(currentColorPhase, progressiveColors.length - 1)];
// Enhanced color blending for evolution phases
if (coreEvolutions > 0) {
// Add golden hints during advanced evolutions
var goldenInfluence = Math.min(coreEvolutions * 0.1, 0.3);
var r = (baseColor >> 16 & 0xFF) / 255.0;
var g = (baseColor >> 8 & 0xFF) / 255.0;
var b = (baseColor & 0xFF) / 255.0;
// Blend in golden warmth
r = Math.min(1.0, r + goldenInfluence * 0.2);
g = Math.min(1.0, g + goldenInfluence * 0.15);
baseColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255);
}
// Extract RGB components and apply organic color shifting
var r = (baseColor >> 16 & 0xFF) / 255.0;
var g = (baseColor >> 8 & 0xFF) / 255.0;
var b = (baseColor & 0xFF) / 255.0;
// Apply continuous color waves for internal wisp blending
r = Math.max(0, Math.min(1, r + colorWaveR));
g = Math.max(0, Math.min(1, g + colorWaveG));
b = Math.max(0, Math.min(1, b + colorWaveB));
// Reconstruct color with organic shifting
var shiftedColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255);
cloudGraphics.tint = shiftedColor;
// Gentle alpha breathing with undulation
var alphaPulse = 0.3 + Math.sin(LK.ticks * self.speed * 1.5 + self.phaseOffset) * 0.1;
var alphaUndulation = Math.cos(LK.ticks * self.undulationSpeedY + self.undulationPhaseY) * 0.05;
cloudGraphics.alpha = Math.max(0.1, Math.min(0.6, alphaPulse + alphaUndulation));
// Very slow rotation with slight variation
var rotationVariation = Math.sin(LK.ticks * self.undulationSpeedX * 0.3) * 0.002;
cloudGraphics.rotation += self.speed * 0.5 + rotationVariation;
};
return self;
});
var SpireNode = Container.expand(function (angle, distance) {
var self = Container.call(this);
var nodeGraphics = self.attachAsset('spireNode', {
anchorX: 0.5,
anchorY: 0.5
});
self.angle = angle;
self.distance = distance;
self.dustPerSecond = 0.5;
self.lastDustTime = LK.ticks;
self.decayTimer = 0;
self.isDecaying = false;
self.update = function () {
// Orbital movement
self.x = 1024 + Math.cos(self.angle + LK.ticks * 0.01) * self.distance;
self.y = 1366 + Math.sin(self.angle + LK.ticks * 0.01) * self.distance;
// Generate dust automatically
if (LK.ticks - self.lastDustTime >= 60) {
// Every second at 60fps
if (!self.isDecaying) {
luminaDust += self.dustPerSecond;
storage.luminaDust = luminaDust;
updateDustDisplay();
spawnDustParticle(self.x, self.y);
}
self.lastDustTime = LK.ticks;
}
// Handle decay system
self.decayTimer++;
if (self.decayTimer > 1800) {
// 30 seconds at 60fps
self.isDecaying = true;
nodeGraphics.tint = 0xff4444;
}
// Gentle rotation
nodeGraphics.rotation += 0.02;
};
self.repair = function () {
self.isDecaying = false;
self.decayTimer = 0;
nodeGraphics.tint = 0xffffff;
// Repair cost
var repairCost = 10;
if (luminaDust >= repairCost) {
luminaDust -= repairCost;
storage.luminaDust = luminaDust;
updateDustDisplay();
}
};
self.down = function (x, y, obj) {
if (self.isDecaying) {
self.repair();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a0d2e
});
/****
* Game Code
****/
// Game state variables
var luminaDust = storage.luminaDust || 0;
var spireNodes = [];
var fluxVoids = [];
var dustParticles = [];
var nebulaClouds = [];
var distantStars = [];
var cosmicParticles = []; // Track low-density cosmic particles
var luminaEnergyWisps = []; // Track ethereal Lumina energy wisps
var cosmicRays = []; // Track faint cosmic ray beams
var cosmicBeams = []; // Track ethereal traversing light beams
var temporalMultiplier = 1.0;
var nextFluxTime = LK.ticks + Math.random() * 1800 + 1200; // 20-50 seconds
var nextTemporalTime = LK.ticks + Math.random() * 3600 + 1800; // 30-90 seconds
var nextCosmicParticleTime = LK.ticks + Math.random() * 900 + 600; // 10-25 seconds between spawns
// Color palette for cosmic atmosphere progression
var colorPalette = {
baseBackground: 0x1a0d2e,
// Deep purple void
earlyNebula: 0x2c1b47,
// Dark purple-blue
midNebula: 0x3d2b5d,
// Deeper purple
lateNebula: 0x4a3373,
// Warmer purple
advancedNebula: 0x5d4088 // Purple with golden hints
};
var currentColorPhase = storage.colorPhase || 0; // 0-4 representing progression through color phases
// Core evolution tracking for significant transformations
var coreEvolutions = storage.coreEvolutions || 0;
var lastEvolutionCheck = storage.lastEvolutionCheck || 0;
var transcendenceLevel = storage.transcendenceLevel || 0;
// UI Elements
var dustDisplay = new Text2('Lumina Dust: 0', {
size: 80,
fill: 0xFFD700
});
dustDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(dustDisplay);
var clickPowerDisplay = new Text2('Click Power: 1x', {
size: 60,
fill: 0xFFFFFF
});
clickPowerDisplay.anchor.set(0, 0);
clickPowerDisplay.x = 50;
clickPowerDisplay.y = 150;
LK.gui.topLeft.addChild(clickPowerDisplay);
var nodeCountDisplay = new Text2('Spire Nodes: 0', {
size: 60,
fill: 0x40E0D0
});
nodeCountDisplay.anchor.set(0, 0);
nodeCountDisplay.x = 50;
nodeCountDisplay.y = 220;
LK.gui.topLeft.addChild(nodeCountDisplay);
var temporalDisplay = new Text2('Temporal: 1.0x', {
size: 50,
fill: 0xFF69B4
});
temporalDisplay.anchor.set(1, 0);
LK.gui.topRight.addChild(temporalDisplay);
// Purchase buttons
var buyNodeButton = new Text2('Buy Spire Node\nCost: 50 Dust', {
size: 50,
fill: 0x40E0D0
});
buyNodeButton.anchor.set(0.5, 1);
LK.gui.bottom.addChild(buyNodeButton);
var upgradeClickButton = new Text2('Upgrade Click\nCost: 100 Dust', {
size: 50,
fill: 0xFFD700
});
upgradeClickButton.anchor.set(0.5, 1);
upgradeClickButton.y = -120;
LK.gui.bottom.addChild(upgradeClickButton);
// Create nebulous gas clouds for atmospheric depth
for (var i = 0; i < 6; i++) {
var cloudX = Math.random() * 2048;
var cloudY = Math.random() * 2732;
var cloudScale = 0.8 + Math.random() * 0.6;
var cloudSpeed = 0.0005 + Math.random() * 0.001;
var cloud = game.addChild(new NebulaCloud(cloudX, cloudY, cloudScale, cloudSpeed));
nebulaClouds.push(cloud);
}
// Create scattered distant stars for ambient particle drift
for (var i = 0; i < 150; i++) {
var starX = Math.random() * 2048;
var starY = Math.random() * 2732;
var star = game.addChild(new DistantStar(starX, starY));
distantStars.push(star);
}
// Initialize starfield layer movement for cosmic flow
var starfieldFlowDirection = Math.random() * Math.PI * 2; // Random flow direction
var starfieldFlowSpeed = 0.008 + Math.random() * 0.004; // Extremely slow flow speed
var starfieldSpiralCenter = {
x: 1024,
y: 1366
}; // Spiral center point
// Create the main Lumina Core
var luminaCore = game.addChild(new LuminaCore());
luminaCore.x = 1024;
luminaCore.y = 1366;
// Load existing spire nodes
var savedNodeCount = storage.spireNodeCount || 0;
for (var i = 0; i < savedNodeCount; i++) {
var angle = i / savedNodeCount * Math.PI * 2;
var distance = 200 + i * 30;
var node = game.addChild(new SpireNode(angle, distance));
spireNodes.push(node);
}
function updateDustDisplay() {
dustDisplay.setText('Lumina Dust: ' + Math.floor(luminaDust));
}
function updateClickPowerDisplay() {
clickPowerDisplay.setText('Click Power: ' + luminaCore.clickPower + 'x');
}
function updateNodeCountDisplay() {
nodeCountDisplay.setText('Spire Nodes: ' + spireNodes.length);
}
function updateTemporalDisplay() {
temporalDisplay.setText('Temporal: ' + temporalMultiplier.toFixed(1) + 'x');
}
function spawnDustParticle(x, y) {
var particle = LK.getAsset('luminaDust', {
anchorX: 0.5,
anchorY: 0.5
});
particle.x = x + (Math.random() - 0.5) * 100;
particle.y = y + (Math.random() - 0.5) * 100;
particle.alpha = 1.0;
particle.timer = 0;
particle.maxTime = 60; // 1 second
game.addChild(particle);
dustParticles.push(particle);
// Animate particle
var targetY = particle.y - 100;
tween(particle, {
y: targetY,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
particle.destroy();
for (var i = dustParticles.length - 1; i >= 0; i--) {
if (dustParticles[i] === particle) {
dustParticles.splice(i, 1);
break;
}
}
}
});
}
function createFluxVoid() {
var fluxVoid = game.addChild(new FluxVoid());
fluxVoids.push(fluxVoid);
}
function spawnCosmicParticle() {
// Low-density spawning - only spawn if particle count is low
if (cosmicParticles.length < 8) {
// Maximum 8 particles at once for low density
// Spawn near edges of screen for natural drift across view
var spawnSide = Math.floor(Math.random() * 4);
var x, y;
switch (spawnSide) {
case 0:
// Top edge
x = Math.random() * 2048;
y = -100;
break;
case 1:
// Right edge
x = 2148;
y = Math.random() * 2732;
break;
case 2:
// Bottom edge
x = Math.random() * 2048;
y = 2832;
break;
case 3:
// Left edge
x = -100;
y = Math.random() * 2732;
break;
}
var particle = game.addChild(new CosmicParticle(x, y));
cosmicParticles.push(particle);
}
}
function spawnLuminaEnergyWisp() {
// Moderate density spawning - maintain ethereal energy presence
if (luminaEnergyWisps.length < 12) {
// Maximum 12 wisps for ethereal atmosphere
// Spawn in various patterns around the environment
var spawnPattern = Math.floor(Math.random() * 3);
var x, y;
switch (spawnPattern) {
case 0:
// Spawn around Lumina Core area for energy emission effect
var angle = Math.random() * Math.PI * 2;
var distance = 300 + Math.random() * 200;
x = 1024 + Math.cos(angle) * distance;
y = 1366 + Math.sin(angle) * distance;
break;
case 1:
// Spawn from screen edges flowing inward
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
x = Math.random() * 2048;
y = -50;
break;
// Top
case 1:
x = 2098;
y = Math.random() * 2732;
break;
// Right
case 2:
x = Math.random() * 2048;
y = 2782;
break;
// Bottom
case 3:
x = -50;
y = Math.random() * 2732;
break;
// Left
}
break;
case 2:
// Spawn randomly throughout environment for permeating effect
x = Math.random() * 2048;
y = Math.random() * 2732;
break;
}
var wisp = game.addChild(new LuminaEnergyWisp(x, y));
luminaEnergyWisps.push(wisp);
}
}
function spawnCosmicRay() {
// Very low frequency spawning - only spawn occasionally
if (cosmicRays.length < 3) {
// Maximum 3 rays at once for subtlety
// Choose ray path type
var rayType = Math.floor(Math.random() * 4);
var startX, startY, endX, endY;
switch (rayType) {
case 0:
// Diagonal from top-left to bottom-right
startX = -100 + Math.random() * 500;
startY = -100 + Math.random() * 300;
endX = 1548 + Math.random() * 500;
endY = 2432 + Math.random() * 300;
break;
case 1:
// Diagonal from top-right to bottom-left
startX = 1548 + Math.random() * 500;
startY = -100 + Math.random() * 300;
endX = -100 + Math.random() * 500;
endY = 2432 + Math.random() * 300;
break;
case 2:
// Horizontal across screen
startX = -200;
startY = Math.random() * 2732;
endX = 2248;
endY = startY + (Math.random() - 0.5) * 400; // Slight curve
break;
case 3:
// Vertical or steep diagonal
startX = Math.random() * 2048;
startY = -200;
endX = startX + (Math.random() - 0.5) * 800;
endY = 2932;
break;
}
var ray = game.addChild(new CosmicRay(startX, startY, endX, endY));
cosmicRays.push(ray);
}
}
function spawnCosmicBeam() {
// Rare spawning - very infrequent ethereal light beams
if (cosmicBeams.length < 2) {
// Maximum 2 beams at once for rarity
var beam = game.addChild(new CosmicBeam());
cosmicBeams.push(beam);
}
}
function triggerTemporalDisruption() {
// Random multiplier between 0.5x and 1.5x
temporalMultiplier = 0.5 + Math.random();
updateTemporalDisplay();
// Effect lasts 10 seconds
LK.setTimeout(function () {
temporalMultiplier = 1.0;
updateTemporalDisplay();
}, 10000);
LK.effects.flashScreen(0x4169e1, 1000);
}
function triggerNebulaColorEvolution() {
// Dramatic color palette shift for all nebula clouds
var evolutionColors = [[0x2c1b47, 0x3d2b5d],
// Early: cool blues and purples
[0x4a3373, 0x5d4088],
// Mid: warmer purples
[0x6b4ba6, 0x7b5bb6],
// Advanced: vibrant violets
[0x8a6bc4, 0x9370db],
// Transcendent: warm violets with energy
[0xa478d4, 0xb19cd9] // Ultimate: violet-green with golden hints
];
var currentColors = evolutionColors[Math.min(coreEvolutions, evolutionColors.length - 1)];
// Apply evolution to all nebula clouds with staggered timing
for (var i = 0; i < nebulaClouds.length; i++) {
var cloud = nebulaClouds[i];
var evolutionDelay = i * 500; // Stagger each cloud by 500ms
var targetColor = currentColors[i % currentColors.length];
LK.setTimeout(function (cloudRef, color) {
return function () {
// Dramatic color transition
tween(cloudRef.children[0], {
tint: color
}, {
duration: 8000,
// 8 second evolution
easing: tween.easeInOut
});
// Temporary scale pulse during evolution
tween(cloudRef.children[0], {
scaleX: cloudRef.baseScale * 1.3,
scaleY: cloudRef.baseScale * 1.3
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(cloudRef.children[0], {
scaleX: cloudRef.baseScale,
scaleY: cloudRef.baseScale
}, {
duration: 6000,
easing: tween.easeInOut
});
}
});
};
}(cloud, targetColor), evolutionDelay);
}
}
function triggerCosmicTranscendence() {
// Ultimate transformation - shift to warm violets and green hints
var transcendentColors = [0xa478d4, 0xb19cd9, 0x98d982]; // Violet-green palette
// Transform all cosmic elements
for (var i = 0; i < nebulaClouds.length; i++) {
var cloud = nebulaClouds[i];
var transcendentColor = transcendentColors[i % transcendentColors.length];
// Ultimate color transformation
tween(cloud.children[0], {
tint: transcendentColor
}, {
duration: 12000,
// 12 second transcendence
easing: tween.easeInOut
});
// Cosmic energy surge effect
tween(cloud.children[0], {
alpha: 0.8,
// Brighter during transcendence
scaleX: cloud.baseScale * 1.5,
scaleY: cloud.baseScale * 1.5
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(cloud.children[0], {
alpha: 0.4,
scaleX: cloud.baseScale * 1.1,
scaleY: cloud.baseScale * 1.1
}, {
duration: 9000,
easing: tween.easeInOut
});
}
});
}
// Transform distant stars to match transcendent energy
for (var i = 0; i < distantStars.length; i++) {
var star = distantStars[i];
if (Math.random() < 0.6) {
// 60% of stars participate
tween(star.children[0], {
tint: 0xffd700,
// Golden energy
alpha: 0.8,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 6000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(star.children[0], {
alpha: 0.4,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 6000,
easing: tween.easeInOut
});
}
});
}
}
}
// Button handlers
buyNodeButton.down = function (x, y, obj) {
var cost = 50 + spireNodes.length * 25;
if (luminaDust >= cost) {
luminaDust -= cost;
storage.luminaDust = luminaDust;
var angle = spireNodes.length / (spireNodes.length + 1) * Math.PI * 2;
var distance = 200 + spireNodes.length * 30;
var node = game.addChild(new SpireNode(angle, distance));
spireNodes.push(node);
storage.spireNodeCount = spireNodes.length;
updateDustDisplay();
updateNodeCountDisplay();
LK.getSound('purchase').play();
// Update button cost display
var newCost = 50 + spireNodes.length * 25;
buyNodeButton.setText('Buy Spire Node\nCost: ' + newCost + ' Dust');
}
};
upgradeClickButton.down = function (x, y, obj) {
var cost = 100 * luminaCore.clickPower;
if (luminaDust >= cost) {
luminaDust -= cost;
storage.luminaDust = luminaDust;
luminaCore.clickPower++;
storage.clickPower = luminaCore.clickPower;
updateDustDisplay();
updateClickPowerDisplay();
LK.getSound('purchase').play();
// Update button cost display
var newCost = 100 * luminaCore.clickPower;
upgradeClickButton.setText('Upgrade Click\nCost: ' + newCost + ' Dust');
}
};
// Initialize displays
updateDustDisplay();
updateClickPowerDisplay();
updateNodeCountDisplay();
updateTemporalDisplay();
// Update button costs
var nodeCost = 50 + spireNodes.length * 25;
buyNodeButton.setText('Buy Spire Node\nCost: ' + nodeCost + ' Dust');
var clickCost = 100 * luminaCore.clickPower;
upgradeClickButton.setText('Upgrade Click\nCost: ' + clickCost + ' Dust');
// Play ambient music
LK.playMusic('cosmicAmbient');
// Initialize cosmic breathing cycle - creates universe-wide living rhythm
var _cosmicBreathingCycle = function cosmicBreathingCycle() {
var breathDuration = 25000 + Math.random() * 15000; // 25-40 second cycles
var breathIntensity = 0.03 + Math.random() * 0.02; // Subtle breathing intensity
var breathPhase = Math.random() * Math.PI * 2;
// Apply cosmic breathing to all elements for unified living background
for (var i = 0; i < nebulaClouds.length; i++) {
var cloud = nebulaClouds[i];
var cloudBreathIntensity = breathIntensity * (0.8 + Math.random() * 0.4);
tween(cloud.children[0], {
alpha: cloud.children[0].alpha * (1.0 + cloudBreathIntensity),
scaleX: cloud.baseScale * (1.0 + cloudBreathIntensity),
scaleY: cloud.baseScale * (1.0 + cloudBreathIntensity * 0.7)
}, {
duration: breathDuration * 0.5,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(cloud.children[0], {
alpha: cloud.children[0].alpha * (1.0 - cloudBreathIntensity * 0.5),
scaleX: cloud.baseScale * (1.0 - cloudBreathIntensity * 0.3),
scaleY: cloud.baseScale * (1.0 - cloudBreathIntensity * 0.2)
}, {
duration: breathDuration * 0.5,
easing: tween.easeInOut
});
}
});
}
// Apply subtle breathing to distant stars
for (var i = 0; i < distantStars.length; i++) {
var star = distantStars[i];
if (Math.random() < 0.4) {
// 40% of stars participate in cosmic breathing
var starBreathIntensity = breathIntensity * 2.0; // Stars have more pronounced breathing
tween(star.children[0], {
alpha: star.children[0].alpha * (1.0 + starBreathIntensity),
scaleX: star.children[0].scaleX * (1.0 + starBreathIntensity * 0.5),
scaleY: star.children[0].scaleY * (1.0 + starBreathIntensity * 0.5)
}, {
duration: breathDuration * 0.6,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(star.children[0], {
alpha: star.children[0].alpha * (1.0 - starBreathIntensity * 0.7),
scaleX: star.children[0].scaleX * (1.0 - starBreathIntensity * 0.3),
scaleY: star.children[0].scaleY * (1.0 - starBreathIntensity * 0.3)
}, {
duration: breathDuration * 0.4,
easing: tween.easeInOut
});
}
});
}
}
// Continue the cosmic breathing cycle infinitely
LK.setTimeout(function () {
_cosmicBreathingCycle();
}, breathDuration);
};
// Start the cosmic breathing cycle with initial delay
LK.setTimeout(function () {
_cosmicBreathingCycle();
}, 5000); // Start after 5 seconds
// Initialize starfield layer cosmic flow animation
var _starfieldCosmicFlow = function starfieldCosmicFlow() {
var flowDuration = 60000 + Math.random() * 30000; // 60-90 second cycles
var flowIntensity = 0.01 + Math.random() * 0.005; // Very subtle flow
// Create slow, constant movement across entire starfield
for (var i = 0; i < distantStars.length; i++) {
var star = distantStars[i];
// Calculate flow direction - gentle drift across screen
var flowX = Math.cos(starfieldFlowDirection) * flowIntensity;
var flowY = Math.sin(starfieldFlowDirection) * flowIntensity;
// Apply extremely slow cosmic flow with tween for smooth movement
tween(star, {
x: star.x + flowX * 200,
// Very slow movement over long duration
y: star.y + flowY * 150
}, {
duration: flowDuration,
easing: tween.linear // Constant movement speed
});
}
// Gradually change flow direction for organic cosmic movement
var newFlowDirection = starfieldFlowDirection + (Math.random() - 0.5) * 0.2;
tween({
value: starfieldFlowDirection
}, {
value: newFlowDirection
}, {
duration: flowDuration,
easing: tween.linear,
onFinish: function onFinish() {
starfieldFlowDirection = newFlowDirection;
}
});
// Continue the cosmic flow cycle
LK.setTimeout(function () {
_starfieldCosmicFlow();
}, flowDuration);
};
// Start starfield cosmic flow with initial delay
LK.setTimeout(function () {
_starfieldCosmicFlow();
}, 10000); // Start after 10 seconds
game.update = function () {
// Handle flux void spawning
if (LK.ticks >= nextFluxTime) {
createFluxVoid();
nextFluxTime = LK.ticks + Math.random() * 1800 + 1200; // 20-50 seconds
}
// Handle temporal disruptions
if (LK.ticks >= nextTemporalTime) {
triggerTemporalDisruption();
nextTemporalTime = LK.ticks + Math.random() * 3600 + 1800; // 30-90 seconds
}
// Handle low-density cosmic particle spawning
if (LK.ticks >= nextCosmicParticleTime) {
spawnCosmicParticle();
nextCosmicParticleTime = LK.ticks + Math.random() * 1800 + 1200; // 20-50 seconds between spawns for low density
}
// Handle ethereal Lumina energy wisp spawning for permeating energy effect
if (LK.ticks % 180 === 0) {
// Every 3 seconds - regular ethereal energy emission
spawnLuminaEnergyWisp();
}
// Increased energy emission during Core activity
if (LK.ticks % 60 === 0 && spireNodes.length > 0) {
// Every second when nodes are active
if (Math.random() < 0.3) {
// 30% chance for additional ethereal energy
spawnLuminaEnergyWisp();
}
}
// Clean up expired dust particles
for (var i = dustParticles.length - 1; i >= 0; i--) {
var particle = dustParticles[i];
particle.timer++;
if (particle.timer >= particle.maxTime) {
particle.destroy();
dustParticles.splice(i, 1);
}
}
// Handle nebula cloud boundary wrapping
for (var i = 0; i < nebulaClouds.length; i++) {
var cloud = nebulaClouds[i];
// Wrap around screen boundaries
if (cloud.x < -400) cloud.x = 2048 + 400;
if (cloud.x > 2048 + 400) cloud.x = -400;
if (cloud.y < -300) cloud.y = 2732 + 300;
if (cloud.y > 2732 + 300) cloud.y = -300;
}
// Clean up cosmic particles that have drifted too far off screen
for (var i = cosmicParticles.length - 1; i >= 0; i--) {
var particle = cosmicParticles[i];
if (particle.x < -200 || particle.x > 2248 || particle.y < -200 || particle.y > 2932) {
particle.destroy();
cosmicParticles.splice(i, 1);
}
}
// Clean up Lumina energy wisps that have drifted too far off screen
for (var i = luminaEnergyWisps.length - 1; i >= 0; i--) {
var wisp = luminaEnergyWisps[i];
if (wisp.x < -300 || wisp.x > 2348 || wisp.y < -300 || wisp.y > 3032) {
wisp.destroy();
luminaEnergyWisps.splice(i, 1);
}
}
// Clean up cosmic beams that have completed traversal or expired
for (var i = cosmicBeams.length - 1; i >= 0; i--) {
var beam = cosmicBeams[i];
if (beam.x < -400 || beam.x > 2448 || beam.y < -400 || beam.y > 3132) {
beam.destroy();
cosmicBeams.splice(i, 1);
}
}
// Handle very occasional cosmic ray spawning - rare, brief light beams
if (LK.ticks % 1200 === 0) {
// Every 20 seconds check for potential spawn
if (Math.random() < 0.15) {
// 15% chance - very rare occurrence
spawnCosmicRay();
}
}
// Handle extremely rare cosmic beam spawning - ethereal light traversal
if (LK.ticks % 2400 === 0) {
// Every 40 seconds check for potential spawn
if (Math.random() < 0.08) {
// 8% chance - extremely rare occurrence
spawnCosmicBeam();
}
}
// Enhanced cosmic ray spawning during core evolution events
if (coreEvolutions > 0 && LK.ticks % 600 === 0) {
// Every 10 seconds during evolutions
if (Math.random() < 0.08) {
// 8% chance for evolution-enhanced rays
spawnCosmicRay();
}
}
// Core Evolution Detection - significant milestones trigger color transitions
var totalNodes = spireNodes.length;
var dustLevel = Math.floor(luminaDust / 1000);
var coreLevel = luminaCore.coreLevel;
var clickLevel = luminaCore.clickPower;
// Check for significant Core Evolutions (major milestones)
var evolutionThreshold = 10000 + coreEvolutions * 15000; // Increasing thresholds
var transcendenceThreshold = 50000 + transcendenceLevel * 100000;
if (luminaDust >= evolutionThreshold && luminaDust > lastEvolutionCheck) {
coreEvolutions++;
lastEvolutionCheck = luminaDust;
storage.coreEvolutions = coreEvolutions;
storage.lastEvolutionCheck = lastEvolutionCheck;
// Trigger dramatic nebula color palette shift
triggerNebulaColorEvolution();
LK.effects.flashScreen(0x9370db, 2000); // Purple evolution flash
// Enhanced ethereal energy emission during evolution
for (var i = 0; i < 8; i++) {
// Burst of ethereal energy
LK.setTimeout(function (index) {
return function () {
spawnLuminaEnergyWisp();
};
}(i), i * 200); // Staggered spawning over 1.6 seconds
}
// Enhance existing energy wisps during evolution
for (var i = 0; i < luminaEnergyWisps.length; i++) {
var wisp = luminaEnergyWisps[i];
tween(wisp.children[0], {
alpha: 0.4,
// Brighter during evolution
scaleX: 1.5,
scaleY: 1.5,
tint: 0xffd700 // Golden energy during evolution
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(wisp.children[0], {
alpha: 0.15,
scaleX: 0.7,
scaleY: 0.7,
tint: 0x9370db // Return to purple
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
}
}
// Check for Transcendence events (ultimate transformations)
if (luminaDust >= transcendenceThreshold && totalNodes >= 20) {
transcendenceLevel++;
storage.transcendenceLevel = transcendenceLevel;
// Major cosmic transformation
triggerCosmicTranscendence();
LK.effects.flashScreen(0xffd700, 3000); // Golden transcendence flash
}
// Update cosmic color phase based on evolutions and transcendence
var newColorPhase = Math.min(4, coreEvolutions + transcendenceLevel);
if (newColorPhase !== currentColorPhase) {
currentColorPhase = newColorPhase;
storage.colorPhase = currentColorPhase;
// Gradually shift background color based on Core's growing influence
var backgroundColors = [0x1a0d2e,
// Base: deep purple void
0x221544,
// Evolution 1: slightly warmer purple
0x2a1d5a,
// Evolution 2: deeper purple with warmth
0x32256f,
// Evolution 3: warmer purple with golden hints
0x4a3373 // Transcendence: vibrant purple-violet
];
var targetBg = backgroundColors[currentColorPhase];
tween(game, {
backgroundColor: targetBg
}, {
duration: 5000,
// Longer transition for evolution
easing: tween.easeInOut
});
}
// Create subtle temporal distortion waves that affect the entire universe
if (LK.ticks % 2400 === 0) {
// Every 40 seconds
// Create temporal ripple effect that distorts space-time
var temporalIntensity = 0.02 + Math.random() * 0.03;
var temporalDuration = 5000 + Math.random() * 3000; // 5-8 seconds
// Apply temporal distortion to all nebula clouds
for (var i = 0; i < nebulaClouds.length; i++) {
var cloud = nebulaClouds[i];
var distortionPhase = Math.random() * Math.PI * 2;
// Create temporal wave effect
tween(cloud, {
scaleX: cloud.baseScale * (1.0 + temporalIntensity),
scaleY: cloud.baseScale * (1.0 - temporalIntensity * 0.5),
rotation: cloud.rotation + (Math.random() - 0.5) * 0.1
}, {
duration: temporalDuration * 0.3,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Return to normal with slight variation
tween(cloud, {
scaleX: cloud.baseScale * (0.95 + Math.random() * 0.1),
scaleY: cloud.baseScale * (0.95 + Math.random() * 0.1)
}, {
duration: temporalDuration * 0.7,
easing: tween.easeInOut
});
}
});
}
// Apply temporal distortion to distant stars
for (var i = 0; i < distantStars.length; i++) {
var star = distantStars[i];
if (Math.random() < 0.3) {
// Only affect 30% of stars for subtle effect
var originalAlpha = star.children[0].alpha;
tween(star.children[0], {
alpha: originalAlpha * (1.5 + Math.random()),
scaleX: 1.0 + Math.random() * 0.5,
scaleY: 1.0 + Math.random() * 0.5
}, {
duration: temporalDuration * 0.4,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(star.children[0], {
alpha: originalAlpha,
scaleX: 0.5 + Math.random() * 0.5,
scaleY: 0.5 + Math.random() * 0.5
}, {
duration: temporalDuration * 0.6,
easing: tween.easeInOut
});
}
});
}
}
// Create subtle cosmic wind effect
LK.effects.flashScreen(0x4a3373, 2000); // Very subtle purple flash
}
// Add cosmic energy fluctuations that create living background
if (LK.ticks % 1800 === 0) {
// Every 30 seconds
// Create energy wave that affects all cosmic elements
var energyWaveIntensity = 0.1 + Math.random() * 0.1;
var energyDuration = 8000 + Math.random() * 4000; // 8-12 seconds
// Apply energy fluctuation to lumina core
tween(luminaCore.children[0], {
tint: 0x9370db,
// Brighter purple during energy wave
scaleX: luminaCore.baseScale * (1.0 + energyWaveIntensity),
scaleY: luminaCore.baseScale * (1.0 + energyWaveIntensity)
}, {
duration: energyDuration * 0.5,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(luminaCore.children[0], {
tint: 0x6a5acd,
// Return to normal
scaleX: luminaCore.baseScale,
scaleY: luminaCore.baseScale
}, {
duration: energyDuration * 0.5,
easing: tween.easeInOut
});
}
});
// Apply energy wave to spire nodes
for (var i = 0; i < spireNodes.length; i++) {
var node = spireNodes[i];
if (!node.isDecaying) {
tween(node.children[0], {
tint: 0x00ffff,
// Bright cyan during energy wave
scaleX: 1.2,
scaleY: 1.2
}, {
duration: energyDuration * 0.3,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(node.children[0], {
tint: 0xffffff,
// Return to normal
scaleX: 1.0,
scaleY: 1.0
}, {
duration: energyDuration * 0.7,
easing: tween.easeInOut
});
}
});
}
}
}
// Add subtle reality distortion that affects space itself
if (LK.ticks % 3600 === 0) {
// Every 60 seconds
// Create space-time distortion effect
var distortionIntensity = 0.05 + Math.random() * 0.05;
var distortionDuration = 12000 + Math.random() * 6000; // 12-18 seconds
// Apply reality distortion to entire game space
tween(game, {
scaleX: 1.0 + distortionIntensity,
scaleY: 1.0 - distortionIntensity * 0.5
}, {
duration: distortionDuration * 0.4,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(game, {
scaleX: 1.0 - distortionIntensity * 0.5,
scaleY: 1.0 + distortionIntensity * 0.3
}, {
duration: distortionDuration * 0.4,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(game, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: distortionDuration * 0.2,
easing: tween.easeInOut
});
}
});
}
});
}
// Save game state periodically
if (LK.ticks % 300 === 0) {
// Every 5 seconds
storage.luminaDust = luminaDust;
storage.clickPower = luminaCore.clickPower;
storage.spireNodeCount = spireNodes.length;
storage.colorPhase = currentColorPhase;
}
};
realistic distant detailed dust star. In-Game asset. 2d. High contrast. No shadows
realistic distant detailed dust star
realistic distant detailed dust purple star. In-Game asset. 2d. High contrast. No shadows
realistic distant detailed dust yellow star. In-Game asset. 2d. High contrast. No shadows
realistic distant detailed dust pink purple nebula star. In-Game asset. 2d. High contrast. No shadows