← Back to blog

Number Forge: building a stacking idle tycoon with Clidex

How I used Clidex to design, build, and verify an idle-tycoon web demo — click-to-forge income, automated workshops, exponentially huge numbers, and an infinitely repeatable prestige loop.

Try the demo ↗

Try it first

Open the Number Forge Demo, click “Forge” a few times, and buy your first Apprentice workshop once you have 15 ingots. Leave it running and it keeps producing on its own; once you cross 1,000,000 ingots you can “Reforge” for a permanent multiplier and start stacking an even bigger number from scratch. Progress stays local to your browser.

How I framed the brief

The brief was built around three ideas: a builder/tycoon loop, something genuinely time-consuming, and numbers that keep stacking past any sane scale. I turned those into concrete mechanics in the prompt:

Create the number-forge static web demo, an idle number-growth tycoon game. Core loop: clicking produces "ingots"; ingots buy workshops that produce ingots automatically and continuously; workshops have escalating tiers, and purchase cost grows exponentially with how many you already own. Numbers need to scale into the far tail, so display values using K/M/B/T-style unit abbreviations. Add a prestige mechanic: spend current progress for a permanent production multiplier, resettable infinitely so the stacking never truly caps. Use vanilla HTML, CSS, and JavaScript, no backend, persist with localStorage, and settle offline earnings based on real elapsed time when the page reopens. Keep the existing off-white paper, ink-toned visual language, add a warm forge accent color, and support dark mode plus mobile layouts. When done, specifically check the number-formatting rounding at unit boundaries, and confirm purchase buttons re-enable live as income accrues, not just after a manual action.

That description maps directly onto the eight workshops, the reforge formula, and the save logic. I deliberately called out two failure-prone spots at the end — and, sure enough, both turned up real bugs during verification.

What you’ll see in action

The page opens on a large ingot counter and a “Forge” button; every click pops a small floating number as feedback. Buying the first Apprentice makes the rate readout show “+0.10 / sec”, and from there the workshop list keeps unlocking: Bellows, Furnace, Forge Machine, Conveyor, Refinery, Foundry Tower, Stellar Forge — each tier produces more per unit but also costs more to keep buying. Once lifetime earnings this run cross a million, the “Reforge” button in the sidebar lights up; clicking it wipes your current ingots and workshops but grants Embers that permanently boost both passive output and click income by 2% each, forever repeatable. Step away for a few minutes and come back to a banner reporting how much the forge burned through while you were gone, at 70% efficiency.

Start with a small need

There’s no multi-currency economy, no tech tree, no achievement wall here — just one loop: click, automate, reforge. It’s enough to be genuinely absorbing, but the scope stays deliberately small. If you want to turn an idea like this into a working page, start with writing a clear brief before your first demo: name who plays it, the shortest possible loop, the technical constraints, and how you’ll verify it, before handing off the build.

Define the experience before picking the stack

The easiest way to ruin an idle tycoon demo is over-designing the systems — too many currencies, formulas that don’t read at a glance, which quietly kills the “watch the number get bigger” payoff the genre runs on. So I sketched exactly one loop first: click to earn a starting stake → buy automation → cross the reforge threshold → restart from a stronger baseline. Every UI element serves that line; there’s no secondary menu or page to navigate.

Technically it stays vanilla HTML, CSS, and JavaScript: one setInterval-driven loop plus localStorage for persistence. State is deliberately thin — current ingots, lifetime earnings for this run (used to compute reforge payout), Ember count, and how many of each of the eight workshops you own. No framework, no state-management library.

How the numbers keep stacking

Stacking absurdly large numbers is the whole point of this brief, so number formatting got its own function: scale by powers of a thousand into K, M, B, T… up through No (10³⁰), then auto-generate two-letter suffixes like aa, ab, ac to keep climbing past the named units:

function formatNumber(num, keepDecimals) {
  const n = Math.max(0, num);
  if (!isFinite(n)) return '∞';
  if (n < 1000) {
    if (keepDecimals && n > 0) return n < 10 ? n.toFixed(2) : n.toFixed(1);
    return Math.floor(n).toString();
  }
  let tier = Math.floor(Math.log10(n) / 3);
  let scaled = n / Math.pow(1000, tier);
  if (Number(scaled.toFixed(scaled < 10 ? 2 : 1)) >= 1000) {
    tier += 1;
    scaled = n / Math.pow(1000, tier);
  }
  return scaled.toFixed(scaled < 10 ? 2 : 1) + suffixFor(tier);
}

The first pass displayed 999999 as 1000.0K — rounding pushed a three-digit value up to a thousand without bumping the unit tier. I asked it to specifically check this rounding boundary, and it added a correction: if rounding lands at or above 1000, step the tier up once more before formatting. That class of off-by-one-tier bug is easy to miss in a number-stacking game, yet it directly undermines the one payoff the genre sells — watching the number visibly grow.

The economy: workshops plus the reforge loop

The eight workshops are ranked by tier; purchase cost grows by ×1.15 with every unit already owned, while output stacks linearly:

function buildingCost(i) {
  return BUILDINGS[i].baseCost * Math.pow(1.15, state.buildings[i]);
}
function rawPerSecond() {
  return BUILDINGS.reduce((sum, b, i) => sum + b.rate * state.buildings[i], 0);
}

Reforge payout is the square root of this run’s lifetime earnings: floor(sqrt(lifetime earnings / 1,000,000)) Embers, each worth a permanent ×1.02 to both passive output and click income. That formula keeps the first few reforges cheap enough to feel the “restart, but stronger” payoff quickly, while later ones need exponentially more income to earn the next Ember — which, paired with the workshops’ exponential costs, produces a loop that can extend indefinitely even as its pacing naturally slows.

Click income isn’t fixed either — it’s Math.max(1, this run's per-second output × 0.05) × Ember multiplier. Clicking carries the early game, and it keeps mattering once automation takes over instead of becoming pure decoration.

Saving and offline earnings

State autosaves to localStorage every 5 seconds, plus once more right before the page unloads. On reopen, it compares the saved timestamp against the current time and settles offline production at 70% efficiency, capped at 4 hours:

function applyOfflineProgress(lastSave) {
  const elapsed = Math.min((Date.now() - lastSave) / 1000, OFFLINE_CAP_S);
  if (elapsed < 5) return;
  const gain = rawPerSecond() * multiplier() * elapsed * OFFLINE_RATE;
  state.ingots += gain;
  state.runEarned += gain;
}

The 70% efficiency and 4-hour cap are a deliberate strategic knob: leaving it alone still pays off, but checking in and buying manually stays meaningfully better — which is exactly the incentive this genre relies on to make you come back.

Verification and boundaries

Beyond clicking, buying, reforging, toggling dark mode, and testing narrow viewports by hand in the browser, I wrote a small jsdom-based headless script that loads the real index.html and app.js into a simulated DOM and steps through it: clicking to afford a purchase and checking the rate readout afterward, verifying save/load round-trips, fast-forwarding to a million lifetime earnings and confirming reforge grants the expected Ember count, and forging a save file timestamped “10 minutes ago” to confirm reload settles offline earnings against the formula exactly. All four scenarios matched the expected numbers before this shipped.

This version has three explicit boundaries: saves don’t sync across devices, there are no achievements or leaderboards, and purchases are one workshop at a time (no “buy 10” or “buy max” shortcuts). Each is an independent addition that doesn’t touch the core loop already in place.

What’s next

First, bulk purchasing — buy 10, or buy as many as current ingots allow — to cut down on repetitive late-game clicking. Second, a per-workshop upgrade that doubles a single tier’s output for a steep ingot cost, so unit count isn’t the only lever. Third, a small prestige tech tree layered on top of the flat Ember multiplier, so reforging unlocks new workshop types instead of only scaling existing ones.

This demo is best read as a test of one claim: a click-automate-reforge loop, paired with number formatting solid enough to trust, is already enough to make someone want to check back. Whether to stack more systems on top is a call best made with real players’ feedback in hand.