OpenAI GPT-5.3 Spark (xhigh)
OpenAIFebruary 2026
What it wrote
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Neon Pulse Engine</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="aurora" aria-hidden="true"></div>
<main class="shell">
<header class="title-card">
<p class="kicker">Incremental Console</p>
<h1>Neon Pulse Engine</h1>
<p class="subtitle">
Build a glowing production empire. Tap, automate, upgrade, and ascend.
</p>
</header>
<section class="layout">
<section class="panel primary">
<div class="stats-grid">
<article class="stat">
<p>Pulse</p>
<h2 id="energyAmount">0</h2>
</article>
<article class="stat">
<p>All-Time Pulse</p>
<h2 id="totalEnergyAmount">0</h2>
</article>
<article class="stat">
<p>Clicks</p>
<h2 id="clickAmount">0</h2>
</article>
<article class="stat">
<p>Stars</p>
<h2 id="starAmount">0</h2>
</article>
<article class="stat">
<p>Per Click</p>
<h2 id="perClickAmount">1.00</h2>
</article>
<article class="stat">
<p>Per Second</p>
<h2 id="perSecondAmount">0.00</h2>
</article>
</div>
<div class="click-zone">
<button id="pulseButton" class="pulse-button" aria-label="Generate pulse energy">
<span id="pulseValue">+1</span>
<span>PULSE!</span>
</button>
<p id="nextPulse">Click to convert energy</p>
</div>
<div id="floatLayer" aria-hidden="true"></div>
<div class="action-row">
<button id="ascendButton" class="action-button">Ascend</button>
<button id="saveButton" class="action-button">Save</button>
<button id="resetButton" class="action-button danger">New Universe</button>
</div>
<p id="ascendHint" class="hint"></p>
</section>
<section class="panel generators">
<h2>Generators</h2>
<div id="generators" class="list"></div>
</section>
<section class="panel upgrades">
<h2>Upgrades</h2>
<div id="upgrades" class="list"></div>
</section>
<section class="panel achievement-list">
<h2>Achievements</h2>
<div id="achievements" class="list achievement-list"></div>
</section>
</section>
</main>
<div id="toastZone" aria-live="polite"></div>
<script src="script.js" defer></script>
</body>
</html>:root {
--bg-deep: #090c1a;
--bg-mid: #111632;
--card: rgba(13, 19, 46, 0.74);
--card-border: rgba(126, 214, 255, 0.35);
--text-main: #ecf2ff;
--text-soft: #9fb4ff;
--accent-a: #89d6ff;
--accent-b: #a35cf7;
--danger: #ff6a7d;
--shadow: 0 26px 60px rgba(4, 10, 31, 0.55);
}
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
min-height: 100%;
background: radial-gradient(circle at 20% 15%, #1d2451 0%, transparent 42%),
radial-gradient(circle at 80% 85%, #2f1348 0%, transparent 35%),
linear-gradient(145deg, var(--bg-deep), var(--bg-mid));
color: var(--text-main);
font-family: 'Trebuchet MS', 'Gill Sans', 'Segoe UI', 'Verdana', sans-serif;
letter-spacing: 0.02em;
}
body {
padding: 2rem;
}
.aurora {
position: fixed;
inset: 0;
pointer-events: none;
background:
radial-gradient(circle at 20% 10%, rgba(135, 206, 255, 0.32), transparent 35%),
radial-gradient(circle at 80% 90%, rgba(171, 79, 255, 0.26), transparent 35%),
repeating-radial-gradient(circle at 40% 50%, rgba(255, 255, 255, 0.06) 0 2px, transparent 2px 80px);
filter: blur(10px);
animation: auroraPulse 14s linear infinite alternate;
opacity: 0.75;
}
@keyframes auroraPulse {
0% {
transform: translateX(-2%) translateY(0);
}
50% {
transform: translateX(2%) translateY(-1%);
}
100% {
transform: translateX(-1.5%) translateY(1.5%);
}
}
.shell {
position: relative;
z-index: 1;
margin: 0 auto;
max-width: 1200px;
display: grid;
gap: 1rem;
}
.title-card {
padding: 1rem 1.25rem;
border-radius: 16px;
background: linear-gradient(140deg, rgba(14, 21, 51, 0.82), rgba(20, 27, 59, 0.5));
border: 1px solid var(--card-border);
box-shadow: var(--shadow);
backdrop-filter: blur(10px);
}
.kicker {
margin: 0;
text-transform: uppercase;
color: var(--accent-a);
font-weight: 700;
letter-spacing: 0.14em;
font-size: 0.7rem;
}
h1 {
margin: 0.2rem 0 0.5rem;
font-size: clamp(1.7rem, 3.5vw, 2.4rem);
}
.subtitle {
margin: 0;
color: var(--text-soft);
}
.layout {
display: grid;
gap: 1rem;
grid-template-columns: 1.2fr 1fr 1fr 0.95fr;
grid-template-areas:
"primary primary primary primary"
"generators upgrades achievements achievements";
}
.panel {
border-radius: 14px;
background: var(--card);
border: 1px solid var(--card-border);
box-shadow: var(--shadow);
padding: 1rem;
min-height: 130px;
backdrop-filter: blur(5px);
}
.primary {
grid-area: primary;
display: grid;
gap: 1rem;
}
.generators {
grid-area: generators;
}
.upgrades {
grid-area: upgrades;
}
.achievement-list {
grid-area: achievements;
}
.stats-grid {
display: grid;
gap: 0.7rem;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.stat {
background: linear-gradient(150deg, rgba(15, 20, 44, 0.9), rgba(27, 34, 71, 0.45));
border: 1px solid rgba(160, 188, 255, 0.18);
padding: 0.75rem;
border-radius: 12px;
}
.stat p {
margin: 0;
font-size: 0.8rem;
color: var(--text-soft);
}
.stat h2 {
margin: 0.3rem 0 0;
font-size: 1.2rem;
}
.click-zone {
display: grid;
justify-items: center;
text-align: center;
}
.pulse-button {
border: none;
color: #09122f;
background: linear-gradient(135deg, #8be3ff, #c4a3ff);
border-radius: 999px;
min-width: 210px;
min-height: 210px;
font-size: clamp(1.2rem, 3vw, 1.8rem);
font-family: inherit;
display: inline-flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 0.3rem;
cursor: pointer;
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.45),
0 22px 55px rgba(136, 184, 255, 0.34),
inset 0 -10px 20px rgba(8, 12, 26, 0.28);
transition: transform 0.15s ease, box-shadow 0.2s ease, filter 0.2s ease;
}
.pulse-button:hover {
transform: scale(1.01);
filter: saturate(1.2);
}
.pulse-button:active {
transform: scale(0.96);
box-shadow:
0 0 0 1px rgba(255, 255, 255, 0.75),
inset 0 8px 18px rgba(6, 13, 32, 0.42);
}
.hint,
.achievement-title {
margin: 0.25rem 0 0;
color: var(--text-soft);
font-size: 0.85rem;
}
#pulseValue {
font-size: 1.05rem;
}
#nextPulse {
margin: 0.3rem 0 0;
}
#floatLayer {
position: relative;
height: 0;
overflow: visible;
}
.floaty {
position: absolute;
left: 50%;
transform: translate(-50%, 0);
color: #9ff7c0;
font-weight: 700;
text-shadow: 0 0 10px rgba(155, 248, 191, 0.75);
pointer-events: none;
animation: floaty 1s ease-out forwards;
}
@keyframes floaty {
0% {
opacity: 1;
transform: translate(-50%, 0) translateY(0) scale(0.9);
}
100% {
opacity: 0;
transform: translate(-50%, -60px) scale(1.05);
}
}
.list {
display: grid;
gap: 0.8rem;
max-height: 520px;
overflow: auto;
}
.item {
border: 1px solid rgba(154, 171, 255, 0.2);
border-radius: 10px;
padding: 0.75rem;
background: linear-gradient(140deg, rgba(15, 21, 50, 0.78), rgba(13, 23, 55, 0.45));
}
.item button {
margin-top: 0.5rem;
width: 100%;
color: #f2f8ff;
font-family: inherit;
border: 1px solid rgba(154, 202, 255, 0.45);
background: linear-gradient(140deg, rgba(28, 40, 92, 0.7), rgba(45, 54, 130, 0.7));
border-radius: 9px;
padding: 0.45rem 0.75rem;
cursor: pointer;
}
.item button:hover:not(:disabled) {
transform: translateY(-2px);
}
.item button:disabled {
opacity: 0.45;
cursor: not-allowed;
}
.item h3 {
margin: 0;
font-size: 0.95rem;
}
.item p {
margin: 0.33rem 0 0;
color: var(--text-soft);
font-size: 0.82rem;
line-height: 1.4;
}
.action-row {
display: flex;
gap: 0.7rem;
flex-wrap: wrap;
}
.action-button {
border: 1px solid rgba(162, 197, 255, 0.4);
padding: 0.6rem 0.9rem;
border-radius: 9px;
color: #f4f8ff;
background: linear-gradient(135deg, rgba(22, 34, 77, 0.85), rgba(35, 42, 102, 0.78));
font-family: inherit;
cursor: pointer;
}
.danger {
border-color: rgba(255, 126, 149, 0.6);
background: linear-gradient(135deg, rgba(79, 26, 38, 0.85), rgba(106, 27, 37, 0.78));
}
.achievement-list .item {
border-style: dashed;
}
.achievement-list .item.unlocked {
background: linear-gradient(140deg, rgba(29, 66, 37, 0.75), rgba(19, 45, 25, 0.45));
}
#toastZone {
position: fixed;
right: 1rem;
top: 1rem;
display: grid;
gap: 0.5rem;
z-index: 5;
}
.toast {
border: 1px solid rgba(141, 221, 162, 0.4);
background: rgba(17, 33, 18, 0.9);
color: #ddffe6;
border-radius: 10px;
padding: 0.65rem 0.85rem;
font-size: 0.85rem;
animation: toastIn 0.3s ease;
max-width: 290px;
}
@keyframes toastIn {
from {
opacity: 0;
transform: translateX(15px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@media (max-width: 1100px) {
.layout {
grid-template-columns: 1fr 1fr;
grid-template-areas:
"primary primary"
"generators upgrades"
"achievements achievements";
}
}
@media (max-width: 700px) {
body {
padding: 1rem;
}
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"primary"
"generators"
"upgrades"
"achievements";
}
.pulse-button {
min-width: 180px;
min-height: 180px;
}
}const SAVE_KEY = 'neonPulseEngineSaveV1';
const BUILDINGS = [
{
id: 'drone',
name: 'Neon Drone',
icon: 'DRN',
description: 'Tiny autonomous drones pull ambient charge from nearby stars.',
baseCost: 14,
baseRate: 0.35,
growth: 1.18,
unlockedAt: 0
},
{
id: 'reactor',
name: 'Pulse Reactor',
icon: 'RCTR',
description: 'A stable reactor with excellent production at higher scales.',
baseCost: 95,
baseRate: 2.4,
growth: 1.22,
unlockedAt: 0
},
{
id: 'orbital',
name: 'Orbital Forge',
icon: 'ORB',
description: 'A rotating forge network that harvests orbital kinetic energy.',
baseCost: 620,
baseRate: 11.5,
growth: 1.3,
unlockedAt: 2
},
{
id: 'nebula',
name: 'Nebula Array',
icon: 'NBL',
description: 'Massive plasma channels generate passive power around the clock.',
baseCost: 4200,
baseRate: 58,
growth: 1.34,
unlockedAt: 10
}
];
const UPGRADES = [
{
id: 'precision',
name: 'Precision Lens',
icon: 'PLS',
description: 'Every level increases manual pulse yield by +25%.',
baseCost: 80,
growth: 1.7,
maxLevel: 12
},
{
id: 'resonance',
name: 'Resonance Coil',
icon: 'RES',
description: 'Each level increases all generator output by +22%.',
baseCost: 240,
growth: 1.85,
maxLevel: 10
},
{
id: 'storage',
name: 'Flux Crystal',
icon: 'FUX',
description: 'Every level increases global multiplier by +8%.',
baseCost: 700,
growth: 1.95,
maxLevel: 8
}
];
const ACHIEVEMENTS = [
{ id: 'first-click', title: 'First Spark', description: 'Generate your first pulse by clicking.', check: (s) => s.totalClicks >= 1 },
{ id: 'touch-of-god', title: 'Touch of Power', description: 'Reach 1,000 total pulse.', check: (s) => s.allTimeEnergy >= 1_000 },
{ id: 'factory-begins', title: 'Factory Begins', description: 'Build 5 generators in total.', check: (s) => Object.values(s.generators).reduce((sum, v) => sum + v, 0) >= 5 },
{ id: 'millionaire', title: 'Million Pulse', description: 'Collect 1,000,000 total pulse.', check: (s) => s.allTimeEnergy >= 1_000_000 },
{ id: 'ascended', title: 'Starforged', description: 'Ascend at least once.', check: (s) => s.stars >= 1 },
{ id: 'automation', title: 'Cold Machinery', description: 'Own 10 Orbital Forges.', check: (s) => s.generators.orbital >= 10 },
{ id: 'legacy', title: 'Legacy Architect', description: 'Ascend 3 times.', check: (s) => s.stars >= 3 }
];
const gameState = {
energy: 0,
allTimeEnergy: 0,
totalClicks: 0,
stars: 0,
generators: {},
upgrades: {},
achievements: {},
lastTick: performance.now()
};
let autoGainPerSecond = 0;
const SAVE_INTERVAL_MS = 2500;
let lastSaveTime = 0;
const els = {
energyAmount: document.getElementById('energyAmount'),
totalEnergyAmount: document.getElementById('totalEnergyAmount'),
clickAmount: document.getElementById('clickAmount'),
starAmount: document.getElementById('starAmount'),
perClickAmount: document.getElementById('perClickAmount'),
perSecondAmount: document.getElementById('perSecondAmount'),
pulseButton: document.getElementById('pulseButton'),
pulseValue: document.getElementById('pulseValue'),
generators: document.getElementById('generators'),
upgrades: document.getElementById('upgrades'),
achievements: document.getElementById('achievements'),
ascensionButton: document.getElementById('ascendButton'),
saveButton: document.getElementById('saveButton'),
resetButton: document.getElementById('resetButton'),
ascensionHint: document.getElementById('ascendHint'),
floatLayer: document.getElementById('floatLayer'),
toastZone: document.getElementById('toastZone')
};
function formatNumber(value, decimals = 2) {
const sign = value < 0 ? '-' : '';
const n = Math.abs(value);
if (n >= 1e12) return `${sign}${(n / 1e12).toFixed(decimals)}T`;
if (n >= 1e9) return `${sign}${(n / 1e9).toFixed(decimals)}B`;
if (n >= 1e6) return `${sign}${(n / 1e6).toFixed(decimals)}M`;
if (n >= 1e3) return `${sign}${(n / 1e3).toFixed(decimals)}K`;
if (n >= 10) return `${sign}${n.toFixed(decimals)}`;
return `${sign}${n.toFixed(3)}`;
}
function getClickValue() {
const precision = 1 + gameState.upgrades.precision * 0.25;
const starMul = 1 + gameState.stars * 0.2;
const storage = 1 + gameState.upgrades.storage * 0.08;
return precision * starMul * storage;
}
function getAutoValue() {
const resonance = 1 + gameState.upgrades.resonance * 0.22;
const storage = 1 + gameState.upgrades.storage * 0.08;
const starMul = 1 + gameState.stars * 0.2;
return resonance * storage * starMul;
}
function getAscensionGain() {
if (gameState.allTimeEnergy < 50_000) return 0;
return Math.floor(Math.sqrt(gameState.allTimeEnergy / 50_000));
}
function getAscendRequirement() {
return 50_000;
}
function getBuildingCost(building) {
const level = gameState.generators[building.id] || 0;
return building.baseCost * Math.pow(building.growth, level);
}
function getUpgradeCost(upgrade) {
const level = gameState.upgrades[upgrade.id] || 0;
return upgrade.baseCost * Math.pow(upgrade.growth, level);
}
function recalcAutoRate() {
const multiplier = getAutoValue();
autoGainPerSecond = BUILDINGS.reduce((sum, building) => {
const level = gameState.generators[building.id] || 0;
return sum + level * building.baseRate * multiplier;
}, 0);
}
function addEnergy(amount, label) {
gameState.energy += amount;
gameState.allTimeEnergy += amount;
if (label) {
spawnFloaty(`+${formatNumber(amount, 2)} ${label}`);
}
saveGame();
}
function spawnFloaty(text) {
const node = document.createElement('div');
node.className = 'floaty';
node.textContent = text;
node.style.top = '-10px';
els.floatLayer.appendChild(node);
requestAnimationFrame(() => {
node.style.left = `${Math.random() * 120 - 60}px`;
});
setTimeout(() => {
node.remove();
}, 980);
}
function triggerToast(text) {
const toast = document.createElement('div');
toast.className = 'toast';
toast.textContent = text;
els.toastZone.appendChild(toast);
setTimeout(() => {
toast.style.transition = 'opacity 0.35s ease';
toast.style.opacity = '0';
setTimeout(() => toast.remove(), 360);
}, 1700);
}
function initializeState() {
BUILDINGS.forEach((building) => {
if (typeof gameState.generators[building.id] !== 'number') {
gameState.generators[building.id] = 0;
}
});
UPGRADES.forEach((upgrade) => {
if (typeof gameState.upgrades[upgrade.id] !== 'number') {
gameState.upgrades[upgrade.id] = 0;
}
});
ACHIEVEMENTS.forEach((achievement) => {
if (typeof gameState.achievements[achievement.id] !== 'boolean') {
gameState.achievements[achievement.id] = false;
}
});
}
function renderGenerators() {
els.generators.innerHTML = '';
BUILDINGS.forEach((building) => {
const level = gameState.generators[building.id];
const cost = getBuildingCost(building);
const unlocked = gameState.generators[building.id] > 0 || gameState.allTimeEnergy >= building.unlockedAt * 50 || level > 0;
const panel = document.createElement('div');
panel.className = 'item';
if (!unlocked) {
panel.style.opacity = '0.55';
panel.innerHTML = `<h3>${building.icon} ${building.name}</h3><p>Unlocked after earning ${formatNumber(building.unlockedAt * 50)} all-time pulse.</p>`;
els.generators.appendChild(panel);
return;
}
panel.innerHTML = `
<h3>${building.icon} ${building.name} (x${level})</h3>
<p>${building.description}</p>
<p>Output: +${formatNumber(building.baseRate * level * getAutoValue())}/s</p>
<p>Cost: ${formatNumber(cost)} Pulse</p>
`;
const buyButton = document.createElement('button');
buyButton.textContent = `Buy`;
buyButton.disabled = gameState.energy < cost;
buyButton.addEventListener('click', () => {
if (gameState.energy < cost) return;
gameState.energy -= cost;
gameState.generators[building.id] += 1;
recalcAutoRate();
spawnFloaty(`Bought ${building.name}`);
render();
forceSave();
});
panel.appendChild(buyButton);
els.generators.appendChild(panel);
});
}
function renderUpgrades() {
els.upgrades.innerHTML = '';
UPGRADES.forEach((upgrade) => {
const level = gameState.upgrades[upgrade.id];
const cost = getUpgradeCost(upgrade);
const panel = document.createElement('div');
panel.className = 'item';
panel.innerHTML = `
<h3>${upgrade.icon} ${upgrade.name} (x${level})</h3>
<p>${upgrade.description}</p>
<p>Cost: ${formatNumber(cost)} Pulse</p>
<p>${level >= upgrade.maxLevel ? 'Maxed' : `Remaining levels: ${upgrade.maxLevel - level}`}</p>
`;
const buyButton = document.createElement('button');
buyButton.disabled = gameState.energy < cost || level >= upgrade.maxLevel;
buyButton.textContent = level >= upgrade.maxLevel ? 'MAX' : 'Buy';
buyButton.addEventListener('click', () => {
if (gameState.energy < cost || level >= upgrade.maxLevel) return;
gameState.energy -= cost;
gameState.upgrades[upgrade.id] += 1;
recalcAutoRate();
spawnFloaty(`Upgraded ${upgrade.name}`);
render();
forceSave();
});
panel.appendChild(buyButton);
els.upgrades.appendChild(panel);
});
}
function renderAchievements() {
els.achievements.innerHTML = '';
ACHIEVEMENTS.forEach((achievement) => {
const unlocked = gameState.achievements[achievement.id];
const item = document.createElement('div');
item.className = `item ${unlocked ? 'unlocked' : ''}`;
item.innerHTML = `
<h3>${unlocked ? '[X] ' : '[ ] '}${achievement.title}</h3>
<p>${achievement.description}</p>
`;
els.achievements.appendChild(item);
});
}
function checkAchievements() {
let newlyUnlocked = false;
ACHIEVEMENTS.forEach((achievement) => {
if (!gameState.achievements[achievement.id] && achievement.check(gameState)) {
gameState.achievements[achievement.id] = true;
newlyUnlocked = true;
triggerToast(`Unlocked: ${achievement.title}`);
}
});
if (newlyUnlocked) {
forceSave();
renderAchievements();
}
}
function renderStats() {
const perClick = getClickValue();
els.energyAmount.textContent = `${formatNumber(gameState.energy)} Pulse`;
els.totalEnergyAmount.textContent = `${formatNumber(gameState.allTimeEnergy)}`;
els.clickAmount.textContent = `${gameState.totalClicks.toLocaleString()}`;
els.starAmount.textContent = `${gameState.stars}`;
els.perClickAmount.textContent = `${formatNumber(perClick)} / click`;
els.perSecondAmount.textContent = `${formatNumber(autoGainPerSecond)} / s`;
els.pulseValue.textContent = `+${formatNumber(perClick)}`;
const ascension = getAscensionGain();
if (gameState.allTimeEnergy >= getAscendRequirement()) {
els.ascensionHint.textContent = `Ascension available: +${ascension} star${ascension === 1 ? '' : 's'} once you reset your machine.`;
els.ascensionButton.disabled = false;
} else {
els.ascensionHint.textContent = `Ascend at ${formatNumber(getAscendRequirement())} all-time pulse and above to gain stars.`;
els.ascensionButton.disabled = true;
}
}
function render() {
recalcAutoRate();
renderGenerators();
renderUpgrades();
renderStats();
renderAchievements();
}
function gameLoop(timestamp) {
const delta = Math.max(0, timestamp - gameState.lastTick) / 1000;
gameState.lastTick = timestamp;
if (delta < 1) {
if (autoGainPerSecond > 0) {
addEnergy(autoGainPerSecond * delta);
}
} else {
gameState.lastTick = timestamp;
}
checkAchievements();
render();
requestAnimationFrame(gameLoop);
}
function saveGame() {
const now = Date.now();
if (now - lastSaveTime < SAVE_INTERVAL_MS) return;
forceSave();
}
function forceSave() {
localStorage.setItem(SAVE_KEY, JSON.stringify(gameState));
lastSaveTime = Date.now();
}
function loadGame() {
const saved = localStorage.getItem(SAVE_KEY);
if (!saved) return;
try {
const parsed = JSON.parse(saved);
Object.assign(gameState, parsed);
gameState.lastTick = performance.now();
lastSaveTime = Date.now();
} catch {
// ignore malformed save
}
}
function hardReset(confirmed = false) {
if (!confirmed && !confirm('Reset everything and lose progress?')) return;
localStorage.removeItem(SAVE_KEY);
gameState.energy = 0;
gameState.allTimeEnergy = 0;
gameState.totalClicks = 0;
gameState.stars = 0;
gameState.generators = {};
gameState.upgrades = {};
gameState.achievements = {};
gameState.lastTick = performance.now();
lastSaveTime = Date.now();
initializeState();
autoGainPerSecond = 0;
recalcAutoRate();
render();
}
function ascend() {
const stars = getAscensionGain();
if (stars <= 0) return;
const confirmAscension = confirm(`Ascend now and gain ${stars} stars? This will reset all generators and upgrades but keeps stars and all-time stats.`);
if (!confirmAscension) return;
gameState.stars += stars;
gameState.energy = 0;
gameState.totalClicks = 0;
gameState.generators = {};
gameState.upgrades = {};
initializeState();
recalcAutoRate();
triggerToast(`Ascended! +${stars} star${stars === 1 ? '' : 's'}`);
forceSave();
render();
}
function clickPulse() {
const amount = getClickValue();
gameState.totalClicks += 1;
addEnergy(amount, 'Pulse');
spawnFloaty(`+${formatNumber(amount)} Pulse`);
checkAchievements();
render();
}
function buildListeners() {
els.pulseButton.addEventListener('click', clickPulse);
els.ascensionButton.addEventListener('click', ascend);
els.saveButton.addEventListener('click', () => {
forceSave();
triggerToast('Game saved');
});
els.resetButton.addEventListener('click', () => hardReset(false));
}
function bootstrap() {
initializeState();
loadGame();
initializeState();
recalcAutoRate();
render();
buildListeners();
requestAnimationFrame(gameLoop);
}
bootstrap();