User prompt
This will be a rare, short-duration effect. A faint, glowing "beam" with soft edges will slowly materialize from one side of the screen, traverse it, and then fade out on the other side. Its opacity will be very low so it doesn't obstruct gameplay elements. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Occasionally, very faint and subtle beams of light or cosmic rays will briefly cut across the background. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Adds a layer of ethereal movement and reinforces the idea of Lumina energy permeating the environment, subtly hinting at the game's core resource. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Utilize a low-density particle emitter that generates small, soft-edged particles with a very low opacity. These particles will move slowly along gentle, curving paths, fading in and out of existence rather than abruptly appearing or disappearing. Their color can match the overall nebula palette or slightly contrast. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
The entire starfield layer (or individual star particles) will have an extremely slow, constant movement, perhaps flowing gently from one side of the screen to the other, or spiraling outwards from a central point off-screen. This motion should be so slow that it's only noticeable after several seconds of observation, giving the impression of vast cosmic distances. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Implement a simple opacity or brightness fluctuation for a small percentage of the stars at any given time. This should be asynchronous, so stars twinkle independently. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
With significant Core Evolutions or Transcendences, the overall color palette of the nebula can subtly shift (e.g., from cooler blues and purples to warmer violets and hints of green), signifying the Lumina Core's growing influence and transformation of its surrounding cosmic energy. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
This creates a living background, reinforcing the idea of a dynamic universe around the Lumina Core. It ensures the scene never feels static. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mechanics: Implement a shader or particle system that causes the nebula textures to gently undulate and shift. Sections of the nebula might slowly expand or contract, and their internal wisps of color will subtly blend and drift. This should be a continuous, non-looping animation that creates a sense of infinite, organic movement, possibly taking several minutes for a full, distinct shift. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Concept: The large, ethereal gas clouds in the background will exhibit a very slow, almost imperceptible "breathing" or "swirling" motion. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Color Palette: The dominant colors are cool blues, deep purples, and hints of dark greens. This palette evokes a sense of mystery, ancient energy, and the vastness of space. As the player progresses and the Lumina Core evolves, the game can subtly shift the hue and intensity of these background colors, indicating the Core's increasing influence over its cosmic environment and the player's advancement through different "eras" or "realms" of Lumina. For example, later stages might introduce warmer, more vibrant purples or even hints of golden light, signifying a more powerful and active Core. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Subtle Ambient Particle Drift (Tiny, Distant Stars): Scattered throughout the background are countless tiny, faint points of light representing distant stars. These are not prominent but contribute to the sense of scale and depth. Some of these particles can have a very slow, almost imperceptible drift or shimmer animation to add to the visual richness without distracting from the gameplay. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Shifting Nebulous Gas Clouds: Within the void, there are large, ethereal clouds of gas and dust. These are not static; they are designed to subtly shift and flow, creating a sense of gentle movement and a living, breathing universe. Their forms are organic and flowing, avoiding sharp edges to maintain a serene, mystical atmosphere. โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Deep Cosmic Void: The primary visual is a seemingly infinite darkness, which provides a strong contrast for the glowing Lumina Core and its elements, making them stand out.
Code edit (1 edits merged)
Please save this source code
User prompt
Chroma Tap: The Lumina Spire
Initial prompt
Project: Chroma Tap: The Lumina Spire - Enhanced Protocol & Narrative Integration To the Artificial Intelligence Core: This directive outlines the advanced gameplay mechanics, visual specifications, and narrative context for "Chroma Tap: The Lumina Spire." The existing clicker mechanics serve as the foundation, upon which we will layer dynamic uncertainty and timed events, ensuring a deeply engaging and visually spectacular experience. 1. Narrative Foundation: The Genesis Echo The game is set in a universe where the fabric of reality is woven from "Lumina," a pure, sentient energy. Long ago, the "Prime Lumina" fractured, scattering its essence across dimensions. Our "Lumina Core" is a shard of this Prime Lumina, found adrift in the cosmic void. It is weak, unstable, and yearning for reunification. Lumina Dust: Not just a currency, but condensed "Echoes of Creation" โ fragments of the Prime Lumina's scattered consciousness. Every click on the Core helps it recall and gather these echoes. Spire Nodes: These are "Resonance Conduits," crystalline structures that we construct around the Lumina Core. They act as focusing lenses, amplifying the Core's natural resonance to passively attract more Lumina Dust from the surrounding void. As more nodes are activated, they establish a harmonious network, increasing the Core's stability and reach. Core Evolution: The Core isn't merely growing; it's undergoing "Metamorphosis." With enough Echoes, it reshapes itself, recalling ancient forms and reclaiming its innate power. Each evolution marks a significant step towards its true, primeval state. Its changing colors reflect the awakening of dormant Lumina spectrums. Transcendence: This is the "Temporal Re-Weaving" protocol. When the Core reaches a critical mass of Echoes, it can briefly collapse and then re-form itself across the cosmic timeline, retaining its fundamental memories (Essence) while discarding the transient energy (Lumina Dust). This allows it to initiate a new, more powerful genesis, accelerating the gathering of echoes in its next iteration. It's not a reset, but a controlled, strategic jump forward in its evolution, fueled by the accumulation of "Essence Shards" โ concentrated memories of its past power. 2. Uncertainty Mechanics & Visuals (The Cosmic Flux) The universe is chaotic, and the Lumina Core, as a fractured entity, is susceptible to its vagaries. These elements introduce risk, reward, and reactive gameplay. 2.1. Flux Voids (Reworked Energy Wells) Mechanics: These are localized tears in the cosmic fabric, appearing randomly on screen. Appearance: They manifest as swirling, darker vortices, subtly pulling background particles towards their center. A faint, unsettling hum accompanies their presence. Interaction: Clicking a Flux Void before it dissipates (5 seconds) triggers a "Flux Resonance." Positive Resonance (70% chance): The Void destabilizes into a burst of concentrated Lumina Dust (5-15x current click power), accompanied by a bright, expanding ripple effect and a satisfying chime. Negative Resonance (30% chance): The Void absorbs a small amount of Lumina Dust (equivalent to 1-3 average clicks), represented by a brief, sucking sound and particles rushing into the void before it collapses silently. A faint, red "ERROR" particle burst might appear. Limit: Still limited to 3 on screen at once. Time Distribution: Appear every 15-30 seconds, with a slight bias for appearing more frequently during "Temporal Disruption" events (see below). 2.2. Temporal Disruptions (Click Power Fluctuations) Mechanics: The fabric of time around the Lumina Core occasionally wavers, causing unpredictable shifts in its energy output. Appearance: The screen briefly distorts with a subtle "ripple" or "heat haze" effect, and the Lumina Core's aura flickers erratically, changing intensity. A low, pulsing drone sound accompanies the shift. Effect: For a duration of 10-15 seconds: "Surge" (60% chance): Click power temporarily increases by 20-50%. The Core glows brighter, and click particles are more numerous and vibrant. "Dampen" (40% chance): Click power temporarily decreases by 10-25%. The Core's glow dims slightly, and click particles are fewer and less intense. Visual Feedback: A small, temporary icon appears near the Lumina Dust counter, indicating "Surge" (up arrow, glowing green) or "Dampen" (down arrow, dull red). Time Distribution: Occur randomly every 2-5 minutes of active gameplay. 2.3. Node Decay (Spire Node Malfunctions) Mechanics: Individual Spire Nodes, being complex constructs, can occasionally experience instability, reducing their efficiency. Appearance: One of the active Spire Nodes will begin to visibly "flicker," dim, or show small cracks/sparks along its structure. Its orbital path might become slightly erratic. A faint, crackling sound emanates from the affected node. Effect: The affected Spire Node's auto-generation rate is reduced by 50% for 30 seconds. Interaction: Players can "Re-calibrate" the node by clicking it once. This immediately restores its full function and makes it immune to Node Decay for 60 seconds. A successful recalibration is met with a bright flash from the node and a satisfying "snap" sound. Time Distribution: Occur randomly every 3-7 minutes once at least 2 Spire Nodes are active. Only one node can be affected at a time. 3. Event Mechanics & Visuals (Cosmic Alignments & Prophecies) These are scheduled or progress-triggered moments that offer unique challenges, significant rewards, or advance the narrative. They provide milestones and a sense of unfolding destiny. 3.1. Whispers of Genesis (Early Game Tutorial/Lore Events) Mechanics: These are guided events that occur at specific Lumina Dust thresholds, easing the player into new mechanics and revealing lore. Visuals: A gentle, glowing text box appears overlaying the background (non-intrusive) with a soft, ethereal chime. The Lumina Core might subtly pulse in response. Examples & Time Distribution: Threshold 50 Lumina Dust: "Whispers from the Void: The Core yearns for a conduit. Seek its form." (Hints at Spire Node unlock). A new UI element, "Spire Node Construction," subtly highlights. Threshold 500 Lumina Dust: "Echoes of Ages Past: The Core's form shifts, recalling forgotten patterns. Witness its Metamorphosis." (Hints at Core Evolution). The "Core Evolution" UI element pulses. Threshold 5,000 Lumina Dust: "The Great Weaving: The fabric of existence hums with potential. Prepare to Transcend." (Prepares player for Transcendence). The Transcend button glows. 3.2. Astral Conjunctions (Mid-Game Challenges) Mechanics: Timed events that offer significant rewards but require active participation or strategic preparation. They occur at intervals, growing in complexity. Visuals: The background nebula shifts into a distinct, vibrant celestial alignment (e.g., planets aligning, a new nebula forming). A grand, sweeping orchestral swell plays. A prominent event timer appears. Examples & Time Distribution: "The Resonance Cascade" (Available after 3 Spire Nodes unlocked, lasts 60 seconds): Mechanic: For 60 seconds, all Lumina Dust generation (clicks + auto) is doubled. However, Flux Voids appear every 5 seconds (more frequently), with an increased Negative Resonance chance (40%). Visuals: The Lumina Core emits rapid, bright pulses. Lumina Dust particles are visibly larger and more numerous. Flux Voids are more active, swirling intensely. Strategy: Players must balance rapid clicking with careful avoidance or calculated risk-taking on Flux Voids. "Cosmic Bloom" (Available after 1st Core Evolution, lasts 90 seconds): Mechanic: A special, large "Bloom Bud" appears on screen. Players must click it repeatedly to "nurture" it. Each click on the Bloom Bud generates Lumina Dust and contributes to its growth. If fully bloomed before time runs out, it awards a massive Lumina Dust bonus (e.g., 5-10x current auto-generation rate). Visuals: The Bloom Bud starts as a tightly closed, glowing seed, slowly expanding and revealing intricate petals with each click. Its final bloom is a spectacular explosion of light and particles. Strategy: Prioritize clicking the Bloom Bud over the Lumina Core, or strategically upgrade click power before the event. Time Distribution: These events trigger roughly every 15-30 minutes of active gameplay, cycling through different types. A 5-second countdown "pre-announcement" appears before the event starts. 3.3. Echoes of Eternity (Late Game/Transcendence Events) Mechanics: Complex, multi-stage events that activate post-Transcendence, offering unique Essence gains and profound lore progression. These are less about rapid clicking and more about managing sustained production and making strategic decisions. Visuals: The Lumina Core undergoes a profound, temporary visual transformation (e.g., gaining ethereal wings, radiating complex holographic patterns). The background shifts into a nebula of swirling, high-energy colors. Sound design emphasizes cosmic grandeur. Examples & Time Distribution: "The Grand Convergence" (Available after 1st Transcendence, triggers every 3rd Transcendence): Mechanic: The Core temporarily requires "Essence Infusions" (small amounts of Lumina Dust based on current total, but the actual cost is deducted from Essence Shards). Each infusion unlocks a new facet of the Core's advanced form and awards a significant bonus to Essence for the next Transcendence. This is a choice: invest more now for greater future gain. Visuals: New, intricate geometric patterns appear on the Core with each infusion. The Essence Shard counter will show a temporary "flux" animation. Strategy: Decide how much Essence to invest from your current pool for future Transcendence benefits. "Temporal Feedback Loop" (Available after 3rd Transcendence, random chance with active play): Mechanic: Triggers a 5-minute period where all auto-generation is reduced by 75%, but every click on the Lumina Core has a 10% chance to generate "Ephemeral Essence" โ temporary Essence that lasts until the event ends, which then converts into a small amount of permanent Essence. Visuals: The background briefly shows "ghost" images of previous Lumina Cores. Auto-generating Spire Nodes dim significantly. Click particles are rare but distinct when Ephemeral Essence is generated. Strategy: Shift focus from idle to intense manual clicking. 3.4. Global Resonance (Rare, Powerful Events) Mechanics: Extremely rare, high-impact events that temporarily shift fundamental game rules, offering immense, but often challenging, rewards. Visuals: A full-screen cosmic spectacle, unique background, and a dedicated, short musical theme. The entire UI might receive a temporary thematic overlay. Example & Time Distribution: "The Singularity Bloom" (Extremely rare, e.g., 0.1% chance per hour of active play): Mechanic: For 2 minutes, the Lumina Core becomes a "Singularity." All clicks instantly generate the equivalent of 10 seconds of your current auto-generation rate. Spire Nodes temporarily glow with immense power, generating dust at 5x their normal rate. Flux Voids appear every 2 seconds, but always grant positive Resonance. Node Decay is suppressed. Visuals: The Lumina Core collapses into a tiny, intensely bright point, surrounded by a massive, swirling accretion disk of light. The entire screen is bathed in a glorious, shifting spectrum of colors. Sound effects are deep and resonant. Strategy: Click as fast as humanly possible. This is a burst reward moment. Time Distribution: Designed to be extremely rare, rewarding players for long-term engagement. 4. Visuals, Animations, and Time Distribution: A Planned Delivery This section outlines how the UI and visual elements will support the enhanced mechanics and narrative. 4.1. Core Visuals & Animations: Lumina Core: Idle: Slow, rhythmic pulse. Subtle light refraction. Click: Immediate, intense flash from click point, expanding outward ripple, burst of Lumina Dust particles that float towards the counter. Satisfying "chime" or "thrum" sound. Evolution: A multi-second, dramatic transformation. The core visually disassembles into light particles, reforms into its new shape, and then expands with a burst of color. Accompanied by a "re-forging" sound effect. Temporal Disruption (Surge/Dampen): Core aura rapidly expands/contracts and brightens/dims, with subtle color shifts. Transcendence: The Core rapidly implodes into a single, blinding point of light, then explodes outward into a nebula of Lumina, which then gracefully forms the new, initial state Core. Accompanied by a grand, climactic sound effect. Lumina Dust: Generated as ethereal, shimmering particles (e.g., tiny stars, wisps of light) that flow smoothly towards the Lumina Dust counter. Quantity of particles reflects amount generated. Background: A deep, cosmic void with slowly shifting, nebulous gas clouds. Subtle, ambient particle drift (tiny, distant stars). Changes slightly in color palette and nebula density with Core Evolutions, indicating progression through cosmic realms. Event/Uncertainty Overlays: As described above, full-screen effects like ripples, color shifts, or new celestial alignments. Spire Nodes: Unlocked/Active: Intricate, crystalline structures orbiting the Core on smooth, elliptical paths. Each node has its own subtle internal glow and energy flow animations. Node Decay: Affected node darkens, flickers erratically, emits small, visible sparks/cracks, and its internal energy flow becomes chaotic. Sound effect: faint crackling/hissing. Recalibration: Clicking the decaying node causes it to flash brightly, stabilizing its glow and resuming smooth animation. Sound effect: sharp "snap" or "click." Purchase/Activation: Node materializes from light, expands to its full size, and smoothly transitions into its orbital path. 4.2. UI Elements & Animations: Lumina Dust Counter: Numbers gracefully animate upwards when dust is gained. Glows briefly upon significant gains. Upgrade Buttons: Affordable: Button border glows, slight pulsating animation. "Click" animation: button depresses, brief light flash. Unaffordable: Dull, desaturated. Event Timers: Clear, visible countdown with progress bar. Pulsates near critical time. Event Notifications: Non-intrusive banners or pop-ups that fade in and out gracefully, often accompanied by thematic icons. Essence Shard Counter: Displays Essence visually as radiant, crystalline shards that add up after Transcendence, flowing into the counter. 4.3. Time Distribution (Summary & Planning for AI): The AI should manage the timing of events and uncertainty based on active playtime and player progress. Constant: Lumina Core clicks, auto-generation. Randomized Reactive (Short Cooldowns, Player Reaction Focus): Flux Voids: Every 15-30 seconds (active play). Increased frequency during "Resonance Cascade." Temporal Disruptions: Every 2-5 minutes (active play). Node Decay: Every 3-7 minutes (active play, once 2+ nodes are active). Progress-Triggered (Narrative & Tutorial): Whispers of Genesis: At specific Lumina Dust thresholds (50, 500, 5000). One-time per Transcendence cycle. Timed/Interval-Based (Mid-Game Challenges, Encourages Return): Astral Conjunctions: Every 15-30 minutes of active play, cycling through types. Pre-announced by 5-second countdown. Post-Transcendence (Late Game Depth): Echoes of Eternity: Triggered after specific Transcendence counts (e.g., 1st, 3rd) or at random intervals post-Transcendence. Extremely Rare Global (Engagement Hook): The Singularity Bloom: 0.1% chance per hour of active play.
/**** * 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; } };
===================================================================
--- original.js
+++ change.js
@@ -6,8 +6,125 @@
/****
* 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,
@@ -725,8 +842,9 @@
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
@@ -970,9 +1088,9 @@
endX = 1548 + Math.random() * 500;
endY = 2432 + Math.random() * 300;
break;
case 1:
- // Diagonal from top-right to bottom-left
+ // 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;
@@ -995,8 +1113,16 @@
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();
@@ -1333,16 +1459,32 @@
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) {
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