Game Numerical Design
RPG formulas and growth curves, taming the idle exponential, elimination board structures, and pricing letter probabilities
Casual mini-games look light, but their numbers and algorithms are anything but: the RPG’s combat formulas and growth curves, the exponential the idle game must tame, the board’s mathematical structure the elimination game picks first, and the price the word game puts on letter probability — at bottom it is all one craft. This post takes the site’s twenty-odd widgets, in a few groups, apart to see how numerical design lands across genres.
RPG Numerics: Formulas, Curves, and Gates
Every argument comes with a test bench. Hands-on versions: Turn-Based Combat Simulator, Weapon Damage Calculator, Monster Bestiary, Skill Tree, Spell Book, Inventory, Deckbuilder, D&D Character Sheet.
Three Schools of Damage Formulas
The first fork: how the defense stat enters the formula.
The subtraction school is the most direct: damage = attack − defense.
The Turn-Based Combat Simulator plays in this school. Each attack rolls to hit first, then settles:
const variance = Math.floor(Math.random() * 3); // a fluctuation of 0..2const real = Math.max(1, att.atk - Math.floor(Math.random() * (att.def + 1))) + variance;The reduction isn’t a fixed number; it’s a uniform integer draw between and . Expect to subtract points, with variance growing as .
Run the numbers: the hero’s attack 12 against an orc’s defense 3 gives an expectation of , times 90% hit rate for 10.35. The other way, the orc hits the hero for , times 80% for 7.2.
HP at 50 against 40, the paper estimate puts the hero’s kill in about 4 rounds and the orc’s in about 7. The win rates out of the simulator agree.
The floor means subtraction can never quite kill and never quite whiff. Stack defense past attack and damage doesn’t fall to zero, it just gets compressed to 1-3 points.
But subtraction has a famous imbalance: each point of defense subtracts a fixed 0.5 damage, while the relative mitigation rate inflates at an accelerating pace. Squeezing from 10 to 9 is 10% mitigation; from 2 to 1 it’s 50%. Late-game defense’s marginal return rises exponentially, and the hole has to be patched with a “diminishing defense returns” clause.
The multiplication school cages the mitigation rate with division: .
Each point of defense then has a strictly decreasing absolute return and never zeroes the damage. is the curvature knob.
Mainstream online games are almost all this school. Multiplication guarantees that a linear investment in defense buys a diminishing but predictable survival gain, and the model stays solvable forever.
The third school turns defense into a hit mechanism. D&D’s AC doesn’t reduce damage, it only decides whether d20 plus modifiers crosses the line. Every point of defense becomes the probability of ignoring this attack outright, and expected damage = hit rate × expected dice damage.
The three schools feel completely different in play: subtraction is squeezing, multiplication is diluting, AC is dodging.
The dice school earns its keep beyond nostalgia. The Weapon Damage Calculator parameterizes completely: dice count, sides, flat bonus, crit multiplier, with three buttons for a single roll, the analytic expectation, and a thousand-roll simulation.
Expected damage is the textbook formula:
What actually separates design quality is variance: . At the same expectation of 10.5, has a standard deviation near 2.9, fixed damage has none, and a single big die carries a far wider tail.
A crit in the source is a 10% chance to multiply the dice sum by the multiplier and then add the flat value, for an expectation of . The crit multiplier lifts the multiplier, the flat bonus lifts the floor, and the two stack along different paths — which is why “crit builds” and “panel builds” are never mathematically equivalent.
The thousand-roll box reports average damage, kill count, and DPS. Compare against the analytic expectation and Monte Carlo’s convergence noise shows up.
One detail from reading the source: the simulation already books misses as zero and folds them into the denominator of average damage, and then the results panel multiplies DPS by the hit rate again — the miss penalty is counted twice. Separately, the “target armor” input is never referenced by the settlement code; it’s a reserved hook.
A numerical system’s three accounting bases (single roll, expectation, simulation statistics) must agree on definitions, or the panel contradicts itself.
Hit Rate, CR, and the Offense–Defense Balance
Hit rate is the most counterintuitive stat in combat numerics.
Intuition says “10% less hit is 10% less output”, but one miss frustrates a player far more than a ten-percent damage cut — behavioral economics calls it loss aversion, combat edition.
The simulator defaults the two hit rates to 90% against 80% rather than 100%, which happens to make the phenomenon reproducible. Set the hero’s hit rate to 100% and back to 90%: the win rate barely moves, but those lines of “damage 0” in the battle log read completely differently.
There are two mature remedies: hide hit rate inside hit surplus the way the multiplication school does, or quietly add probability to losing streaks the way XCOM does underneath, artificially truncating the geometric distribution’s cold streaks.
On the enemy side, the numerical vehicle is CR (challenge rating).
The Monster Bestiary holds ten monsters, from the CR 0.25 goblin with 7 HP to the CR 21 lich, each with six ability scores and an attack/defense panel, filterable by humanoid, beast, undead, dragon, giant, aberration.
The table hides a counterintuitive fact: the CR 21 lich has fewer HP (135) than the CR 10 young red dragon (178).
If difficulty were carried by HP, that inversion would be a design accident. Open the ability scores and the compensation shows: the lich has Intelligence 20 against the dragon’s 14, plus higher AC and Dexterity, and its difficulty sits in spellcasting and control.
The core of the CR system: challenge rating is not a function of any single stat but a composite estimate of how many resources a party must spend to solve the encounter. HP, armor, output, and control each carry a share.
The goblin at CR 0.25 is still the classic opening monster, because the system lets four CR 0.25 monsters stack into a CR 1 encounter. Monsters can trade quantity for level, and the difficulty budget decomposes.
The role of the six ability scores deserves a note as well.
In the bestiary a stat is an ability score from 3 to 20, while the combat formulas consume a modifier, and a mining-style mapping joins them: .
10 is the mortal baseline, and every 2 points of score buy 1 point of modifier. 10 and 11 are indistinguishable; 18 against 10 is +4 against +0.
That nonlinear mapping is the bedrock of the whole D&D-style numerical system. Ability scores give players an intuitive “bigger is better” interface, modifiers are the real exchange rate inside the formulas, and one tier per 2 points makes even scores a permanent purchase target.
The red dragon’s Strength 23 converts to +6, the lich’s Intelligence 20 to +5, small numbers both. The system would rather look resplendent on the stat sheet than let any single modifier run to two digits.
Growth Curves
Every disagreement among growth systems condenses into one question: each time you gain a level, how much stronger do you get?
The D&D Character Sheet gives three standard answers.
Hit points are linear: . The class base (fighter 10, wizard 6, cleric 8) plus the Constitution modifier times level, with a constant increment per level.
Between level 1 and level 20 lies a sixty-point linear expansion of the Constitution term, and the 4-point base HP gap between classes gets diluted by the growth term until it’s nearly invisible.
Proficiency bonus is a staircase: . It jumps 1 point at levels 5, 9, 13, and 17, gaining 4 points across twenty levels. That’s the “bounded accuracy” philosophy: numbers must stay small so the d20’s randomness always has a say.
Armor is constant outright: , independent of level.
The three curves combine into a deliberate stance: a character’s absolute numbers barely inflate; what inflates is the capability list. The price is that attack bonus creeps up with proficiency while AC doesn’t, so to-hit quietly climbs with level and magic items have to push AC back up.
Linear is the conservative answer, exponential is the idle game’s engine.
Exponential growth scales each level’s gain proportionally, so every early upgrade feels like a qualitative change; the price only surfaces after the 73rd multiplication, when the numbers blow past floating-point precision and all content dies in one or two hits. How that curve is closed out (prestige resets, soft caps) is where idle-game design is actually fought.
The power function (, between 1.5 and 2) is the compromise: steeper than linear, more convergent than exponential. When monster HP follows a power law in level, “how many hits to kill” stays stable across levels.
The choice of curve finally leaks onto one unified scale: marginal return.
Run two accounts on the HP formula: a fighter with Constitution 16 (modifier +3) has at level 1 and at level 20. A wizard of the same Constitution has at level 1 and 66 at level 20.
A 44% HP gap at the start is down to 6% at max level. The linear growth term dilutes the class base gap as levels rise, which is the mathematical cause of “class identity vanishing in the late game” and the motive for reopening the gaps with equipment and skills later.
Go the other way and let HP grow exponentially: the class gap is preserved proportionally, but a level-20 fighter and a level-10 fighter stand an entire order of magnitude apart, and content design can never again cover both with one encounter table.
Every curve answers two questions at once: how much absolute gain the player gets per level, and at what rate players from different starting points converge or diverge. The first is pacing, the second is balance, and one curve settles both.
The three curves have no ranking, only a question of matching the pace at which content is consumed. The exponential curve’s runaway and its taming are taken apart in detail in the next section, Idle Games.
The Skill Tree’s Shortest Path
The Skill Tree is a small tree, nine nodes in four layers. The root Core splits into Combat and Magic, Combat runs down to Slash and Guard, Magic to Fire and Frost. The third layer holds two endpoints: Whirlwind requires Slash and Guard lit at once, Meteor requires only Fire.
The point budget is 5, nodes with unmet prerequisites stay locked, and clicking a lit node refunds it.
This little tree is really a constrained optimization problem on a directed acyclic graph. Each node is a task, prerequisites are AND dependencies, the budget is at most five steps.
The shortest path to “unlock Whirlwind” is Core → Combat → Slash → Guard → Whirlwind, exactly five points eating the whole budget. “Unlock Meteor” needs only Core → Magic → Fire → Meteor, four points, leaving a slot to light Frost on the way.
Whether two builds exist under the same budget, and whether they exclude each other, are pure computations on the graph’s reachable set.
All three classic questions of talent design can be rehearsed here.
One, depth for strength or breadth for strength. The Whirlwind route bets all five points on a single endpoint; the Meteor route spends four and keeps one slot in reserve. A deep route’s endpoint must be markedly stronger than the shallow route’s combination, or nobody walks the deep route.
Two, the refund rule. In this implementation the refund doesn’t check downstream. Light Whirlwind, then refund Slash, and Whirlwind stays lit with a dangling edge in the dependency graph. The general rule in real games is “a refund must cascade and reclaim downstream”, which the source lacks — perfect counterexample material.
Three, the cost of resets. A talent tree with free unlimited resets degenerates into a lookup table; shipped games either charge a reset item or price trial and error with “respec keeps your level but costs gold”.
Spell Slots: Another Set of Gates
The Spell Book shows resource gating from another dimension. Twenty spells layered by spell level 0 to 4, filterable by eight schools, every entry carrying a casting time and a description.
Spell level is the vertical acquisition gate. A slot of a given level holds only a spell of that level, and slots themselves are single-use (refilled on a long rest), which turns the caster’s output budget from “cast freely, no cooldown” into a rationing of a few high-level casts per day.
Spell slots are one of the few offensive resources that settle across fights, which puts the wizard’s strength and weakness at the decision layer rather than the stat layer.
The casting time column carries content too. Action, bonus action, and reaction encode “when you may cast” as a resource. Reaction is the elegant one: it consumes the moments when it isn’t your turn, effectively opening a free second-action economy inside a turn-based game.
The school filter is pure taxonomy. Evocation, illusion, conjuration, abjuration, enchantment, necromancy, transmutation, and divination impose almost no hard mechanical constraints, yet they carry the retrieval and narrative labeling of the build phase. When a player says “I play an illusionist”, the taxonomy has already finished half the character concept for them.
The “auto-hit” wording on magic missile deserves its own look. It rewrites the attack roll into an automatic hit and keeps only the dice portion of the damage — the standard surgery by which designers excise RNG’s worst experience, hurling a high-level spell at empty ground.
Inventory, Drops, and Resource Gates
The Inventory gives 20 slots (a 5×4 grid), 15 item types, and 6 categories. The “Add” button draws uniformly from the pool of items not yet in the bag and stuffs one into the first empty slot, the same item can’t exist twice, and a full bag raises an explicit error. A selected item can be equipped (moved out of the grid into the equipment bar) or removed.
It looks like a warehouse toy, but the slot-based bag is one of the RPG’s most important hidden economies. Cells are currency; picking anything up pays rent in occupied space, so “what to throw away” becomes a more frequent decision than “what to pick up”.
Three schools of bag design: slot-based (this component, the Diablo line), grid splicing (items occupy different sizes and shapes; Resident Evil and Backpack Hero), and weight-based (capped by total weight). In essence, three different spatial mathematics: slots discretize cost into 0/1, splicing makes it a two-dimensional geometry problem, weight flattens it into a one-dimensional scalar.
Why does the health potion read “restores HP” instead of a fixed number? Expectation points, standard deviation about 1.6. Healing rolls dice too, sharing the same dice algebra as damage, only pointed the other way.
Drop tables sit upstream of systems like these.
The industry implementation is a weighted tree: roll “drops or not” (the drop rate), then draw an entry from the drop sub-table by weight, descending layer by layer after rarity tiering.
Naive weighted random has a famous experience problem: an item at 1% has an expected 100 rolls to appear, but the geometric distribution’s long tail means about 5% of players are still empty-handed at 300. Hence two domestication devices, PRD (pseudo-random distribution, raising the next probability after each failure) and pity (a hard counter), which flatten the long tail in player perception.
This bag’s “Add”, because it deduplicates, is actually uniform sampling without replacement. Each press shrinks the remaining pool by one cell with equal probability, and the full set is guaranteed within fifteen presses. That’s a different random structure from the drop table’s weighted sampling with replacement: the former has a hard ceiling on time-to-complete, the latter never guarantees.
Which one a collection system picks depends on whether you want to sell the safety of pity or the luck of the lucky few.
The Probability Structure of Deckbuilding
The Deckbuilder has the most intricate random structure of the eight components. The rules are standard climb-the-tower: a ten-card starting deck, five attacks (deal 6), four blocks (block 5), one power-up (Strength +2). Each turn you draw 5 with 3 energy, and every card costs 1. Played cards go to the discard pile; when the draw pile empties, the discard is shuffled back. At end of turn the enemy hits for 9, block absorbs damage then clears to zero, and Strength persists permanently. The player has 30 HP, the enemy 48.
First the opening hypergeometric account: the chance of seeing that single power-up in your opening five is exactly .
Now the pure offense line: three attacks a turn deal 18, so the enemy’s 48 HP takes two and a half turns, with the second swing of turn three finishing it. Along the way the player eats two 9s and sits at 12 HP, a tight win.
The mixed line: one block plus two attacks a turn, block pressing the 9 down to 4 points of bleed-through, output 12 a turn, a four-turn kill, ending at 18 HP. The defensive line’s HP advantage comes from block’s 4-for-5 exchange rate and the extra output window of finishing a turn earlier, paid for with one more turn spent.
These two lines are the whole embryo of deck numerical design. Energy is the gate welding shut the three-cards-per-turn ceiling, and any gain worth more than 3 has to come from mechanics outside the cards.
Finally the steady-state probability inside the cycle.
The draw pile and the discard pile keep swapping at the shuffle boundary. The source’s draw function pops from the top of the draw pile, and once it’s empty shuffles the entire discard back. Past the opening few turns, the chance that any given card shows up in any given draw event approaches “hand size ÷ deck size” — five out of ten, about .
That steady state explains the most central axiom of deckbuilding design: the smaller the deck and the more uniform the per-card quality, the smaller the draw variance. It also explains why the cost of adding cards far exceeds intuition — every card added dilutes the draw rate of every key card at once — and why “draw a card” is itself among the strongest effects in the game: it enlarges the numerator of the steady state directly.
By the same token, a permanent buff (Strength) is worth more than the equivalent panel damage. Every extra +1 revalues all five attack cards at once. Compound interest, not simple.
Probability’s role in these systems isn’t “roll for a win or a loss” but translating every build decision the player makes into expectation and variance that can be computed. This craft of splitting draw probability down to the hypergeometric distribution keeps the same books as counting outs and pot odds in Probability at the Card Table.
Idle Games: Four Curves for Taming the Exponential
Every system in an idle (or incremental) game revolves around one contradiction: output must grow to feel good, but uncontrolled exponential growth destroys the game. Balance work in this genre is therefore the craft of taming exponentials — with caps, cost growth laws, bottlenecks, and resets, holding a curve that ought to explode inside a playable tempo. Four widgets on the site happen to cover four sides of that craft: a clicker, a fishing hole, a virtual pet, and a startup.
Hands-on versions: Cookie Clicker, Idle Fishing, Tamagotchi, Startup Simulator.
Why a click is worth exactly 1
The core interaction of the clicker is a cookie. Each click adds 1, forever, and no mechanic ever makes a click worth more.
Four production lines surround it, with textbook pricing and throughput: cursor 15 coins for 1/s, grandma 100 for 5/s, farm 1100 for 40/s, factory 12000 for 250/s.
Start with a counterfactual: what if the click yielded in proportion to your assets (say 1% of total production)?
The optimal play would always be clicking. Clicks ignore the cost growth law, need no saving, and pay instantly; the production lines would become the inefficient option and the entire purchase system would be void on the spot.
A fixed manual yield of 1 is a deliberate cap. Its mathematical meaning: manual output is a constant, automatic output grows linearly with assets, so the click’s share of total output tends to zero. Attention gets pushed from the hand toward the production lines.
But clicking cannot be removed either. At the start production is zero, and clicks are the only source of startup capital. Five clicks a second gets you the first cursor at 15 coins — that is the game’s step zero.
Each click also carries two pieces of feedback: a small +1 floats up at the cursor, and the total click counter in the top bar never stops moving.
Neither detail has any numerical meaning, and together they answer the most important experiential question in the genre: at the start, when output does not exist yet, why does the player stay. Because every input has an immediate, visible, non-revocable reward.
The pricing of the lines hides another thread. Compute payback time (price ÷ throughput): cursor 15 s, grandma 20 s, farm 27.5 s, factory 48 s.
The more expensive the line, the slower the payback, but its per-unit throughput is an order of magnitude higher. Newcomers trade worse value for a stronger single-unit punch.
That keeps buying the newest line a ritual moment instead of mindless scrolling down a purchase list. And because payback only degrades mildly (15 to 48 seconds; three orders of magnitude in price buys a factor of three in time), saving up for the big one is never a loss, only slower.
Payback time stretches gently from 15 seconds to 48; the player shifts from frequent small purchases to saving up for the big items, and the sense of rhythm hides in that gentle slope.
The 1.15 law
Any one item can be bought without limit, but each purchase raises the next price by 15%. , where is how many you already own.
This is the single most important curve in the genre.
Numbers first, to build intuition: , , .
In other words, the fiftieth cursor costs a thousand times the first.
On the output side, cursors produce — linear. On the cost side, the price of the -th — exponential.
Each copy stretches the payback time by a factor of 1.15, and sooner or later it exceeds the player’s patience threshold. The player hits a wall.
Hitting the wall is not an accident, it is the design. Something must sit on the far side of the wall: a higher-throughput line, an unlocked upgrade, or a reset.
The real function of the cost growth law is to build an exponential resistance field around linear output, forcing the player to keep switching targets.
Why 1.15 of all numbers? Too low (1.05, say) and prices are decorative, the snowball rolls unopposed, and the mid-to-late game is dead boring. Too high (1.5) and you slam into the wall after three or four copies, turning saving into a grind.
1.15 puts a single item’s decay exactly where it stays worth buying a dozen times or so. Cookie Clicker’s original uses the same value; it has become the industry default constant for idle games.
Two implementation details are worth a look.
First, the price updates immediately after a purchase (count increments, then floor(base × 1.15^count) is recomputed), with no buffer.
Second, the buy button’s enabled and highlighted states flip in real time with cookies ≥ cost. The player is always staring at the “how much is missing” number, and the tension of the price curve is transplanted straight into the UI.
This per-frame affordability feedback is the standard interface language of incremental games. Values rise monotonically and the button oscillates between “almost” and “affordable”; that oscillation is itself a reward metronome.
Buying order
All four lines share one currency, so “what to buy next” becomes a constantly shifting question.
The rigorous answer compares each item’s marginal output against the time needed to reach its price. In practice players split into two schools.
Pipeline style: buy the cheapest affordable item whenever you have money, keeping purchase frequency up.
Savings style: hold off and accumulate for the next big item.
The 1.15 law makes saving better in the long run, and the reason hides in the “age” of each price curve. You have bought the cheap item so many times that its exponent has run out to a high power (the thirtieth cursor costs 15 × 66 ≈ 990 coins, ten times a brand-new grandma), while the big item’s price curve is still young, its exponent at zero.
The core skill of an experienced player is continuously judging which price curve has not yet been pushed up. In the original Cookie Clicker that judgment evolved into a whole tech-tree priority order, but its seed is already written in these four numbers and the coefficient 1.15.
The second curve
Idle Fishing makes “output is a random number” the core loop.
Six fish, five value tiers: sardine 5, carp 8, bass 15, trout 20, salmon 45, golden fish 150, with rarity from one to four.
The draw weights are not a table but a formula: , where rod is the rod level.
The behavior of this weight formula deserves three sets of numbers.
Rod level 1: all weights are 1, uniform distribution, expected value per cast .
Rod level 5: weights become , the golden fish is , and expectation rises to about 124.
Rod level 10: weights , golden fish , expectation about 138.
The pattern is visible: the expectation is converging.
The distribution is swallowed by the rarest tier, and the expectation creeps toward the golden fish’s ceiling of 150.
Going from rod 5 to rod 10, the price tags climb from 327 to 2147, about 5200 coins in total. The expectation bought by that goes from about 124 to about 138 (+11%).
The diminishing marginal return of upgrades is not produced by any anti-inflation mechanism; it is built into the structure of this weight formula. Once the distribution has collapsed onto the rarest item, squeezing harder only approaches its face value.
The most elegant form of diminishing returns in a design is letting the formula do it itself.
The rod is also a dual-purpose upgrade: it lifts manual income (rarity weights) and idle income at once. The automatic fisher’s per-second output is .
Early on you cast by hand and watch your luck; later you lie back and collect. The transition between the two play styles happens naturally through this single variable, with no “unlock idle mode” button.
The power balance between manual and idle starts out lopsided. With zero auto-fishers everything is hand-cast, 40.5 expected per cast at rod 1. Even clicking at one cast per second, manual income is more than twenty times idle income.
But manual income has two ceilings. It does not accumulate over time (people sleep), and per-cast expectation is pinned near 150 by the convergence. Idle income, by contrast, climbs without bound as fishers times rod level.
So the player’s income structure must go through a gear change. The stats panel lays coins, catches, and per-second output side by side, and the player can watch the dominant term shift from the jolt and delight of “last catch” to the steady ticking number in the “per second” cell.
Good idle games all offer this observable gear change. It is the direct proof that “my strategy is working”.
Two price curves coexist in the shop. Rod , a gentle exponential that allows a dozen or more levels. Auto-fisher , doubling with each purchase: the fourth is 1600, the sixth 6400, the ninth 51200, and the count caps itself in the single digits.
Two growth laws in one shop give the player two different ceiling expectations. The rod is a “grind it out over the long run” asset; the auto-fisher is an “enough to be useful” asset.
And the income structure is multiplicative. The two variables magnify each other: buying one machine or leveling the rod once reprices the other side.
The clicker’s total output is an additive engine; fishing’s is multiplicative. Additive engines inflate slowly and keep a steady rhythm; multiplicative engines explode late but demand a fresh accounting at every step. The latter is exactly where the late-game “sudden takeoff” thrill of idle games comes from.
How time is settled
What “one second” means in a production game determines whether the whole game can be cheated.
The clicker’s implementation is the industry standard answer. setInterval fires every 100ms, but settlement uses real elapsed time. Each tick computes , then accumulates .
Settle by the wall clock, not by tick count.
That apparently redundant distinction is the first gate against cheating. Browsers throttle background-tab timers to once a second or slower; settle by count and switching away to listen to music tanks your income, making timer frequency part of the income function. Settle by dt and throttling only affects how often you settle, not how much: however the interval jitters, the credit per unit time is exactly cps.
Timers and the event loop, that browser fundamentals set, were covered in the earlier JavaScript notes; here only the numerical consequences matter. Time becomes the only accounting unit, and any attempt to “speed up the tick” fails automatically.
The virtual pet runs the time axis backwards. It is not a production curve but a consumption curve.
One tick every 2 seconds, hunger and mood each −1. When either drops below 20, health falls by 2 per tick; with both healthy it recovers 1 per tick. Feeding gives +25 hunger, playing gives +25 mood but −5 hunger, medicine gives +20 health.
Do the survival math. Starting at 80, it takes 60 ticks (two minutes) to fall to 20 and start losing health, then 50 more ticks (100 seconds) to drain 100 health. Left alone, it dies in under four minutes.
The player’s interaction window is a maintenance loop measured in minutes, the exact opposite of the clicker’s “output forever” sense of time. The clicker settles “how much did you earn while away”; the pet settles “how much did you owe while away”.
But note one restraint in the implementation. The timer lives inside the widget, and destroying the widget stops the clock. Leave the page and the pet pauses rather than dies.
This is a deliberate decision not to settle offline. Catch up honestly at one tick per 2 seconds and a night’s sleep guarantees a corpse, which is emotionally unacceptable. “Pause” is a gentle cheat in the player’s favor: technical dishonesty traded for emotional fairness.
The conflict between balance design and emotional design is settled here by sacrificing simulation fidelity.
When offline income is genuinely wanted, the general pattern has three parts: a save (assets plus timestamp), a catch-up (on return, credit elapsed × cps in one go), and a cap (bound the catch-up duration, 8 hours say).
The cap is not optional. Without it, a month away means a month of free output, the entire middle of the curve is skipped, and the pacing collapses.
None of the four widgets saves state, so a refresh zeroes everything, which means their “offline” stops at “the tab stays in the background”. A reasonable trade-off for browser mini-games, but keep capped catch-up in mind and you will know which pieces you are missing next time.
On timer lifecycle, in passing: the clicker clears its interval manually in onDestroy, while fishing returns a cleanup function from $effect. The two are equivalent; just pick one and stick with it.
Lining up the three widgets’ tick rates is instructive too.
Clicker 100ms. Fast enough that the floating +1 keeps up with the finger.
Fishing 1s. Income is the integer , credited per cast with no dt compensation.
Pet 2000ms. Slow enough that “minus one per tick” is visible to the naked eye, generating a little anxiety about watching the gauge.
Tick rate is a compromise between presentation and settlement, but whether the two can be separated is decided by the settlement method. A dt-settling clicker can change its tick freely without changing income (frequency only affects visual smoothness), while integer per-cast settling in fishing welds frequency into the numbers: change 1000ms to 500ms and idle income doubles.
Decide the income model first, then the tick. Do it in the other order and the balance table is welded to a timer parameter.
Bottlenecks and events
Startup Simulator turns “exponential output” into an exam question.
Five state numbers: cash 50000, monthly revenue MRR 1200, monthly growth 20%, monthly burn 4500, and a month counter.
Each press of “next month”: , . Win when ; bankrupt when .
Solve the baseline without events first. MRR climbing from 1200 to 4500 takes eight months ( is where it overtakes). The first seven months accumulate about 12900 of net outflow, with the cash low around 37100. The cushion is thick; under a pure exponential model losing is nearly impossible.
So the real opponent is the random event fired with 30% probability each month, and the three events apply precisely to the model’s three parameters.
40%: a funding round (15000–35000 cash in, growth rate +4 percentage points). It steepens the curvature of the exponential.
30%: customer churn (MRR loses 20%). It snaps the exponential: , more than a month of compounding undone.
30%: a hire (monthly burn +400, plus a 2500 one-time cost). It raises the line that decides the game.
The most instructive part of this structure is why burn is fixed.
The scissors gap between the fixed cost line and the exponential revenue line is the game’s entire drama. Early on MRR struggles below the line; after the crossing point the gap opens exponentially.
If burn grew exponentially too, the player could never become profitable and the game would degenerate into endless delay. If burn fell, the bottleneck disappears and so does the tension.
Keep one line that does not move, and the exponential means something. That is the principle running from the clicker’s price law all the way to this cash-flow model.
Win and loss are judged on two different quantities, which is worth pointing out.
Profit is a flow test (MRR > burn, the monthly difference). Bankruptcy is a stock test (cash < 0, the accumulated pile).
Between them lies the most realistic window of all: the flow has turned positive while the stock still bleeds — money in the account, a loss every month. Profitable in theory at any moment, insolvent at any moment in practice.
In real-world cash-flow analysis, “how many months of runway are left” is exactly this difference. A two-hundred-line simulation widget preserved it, with clean conditions and no discount on the semantics.
The sense of time forms another contrast.
Clicker and fishing flow time automatically (100ms and 1s ticks), while the startup advances only when the player pushes. The “next month” button makes the flow rate itself a resource: press more often and the game runs faster, but each month’s settlement is a decision heartbeat — the event die, the cash flow, how many months remain to profitability.
Discrete turns amplify the shock of exponential growth from a per-second trickle into a monthly jump. The same feels entirely different.
Last comes the prestige loop, the ultimate taming device of the genre.
None of the four implements a full prestige, but two naive resets mark its two endpoints.
The pet’s revival resets health, hunger, and mood, but the age counter does not clear. Age is the only cumulative quantity that crosses death; it just has no redemption outlet yet.
Startup Simulator’s restart is an unqualified full reset: 50000, 1200, 20%, 4500, everything back to zero.
The general prestige formula sits between them: initial conditions of round = , where is the multiplier that survives.
Mathematically it cuts the single exponential curve into segments, each climbing the same curve from a higher starting point. What the player relives is precisely the steepest, sweetest early-to-middle stretch of exponential growth, and “when is the best time to reset” breeds an optimization game of its own.
For these widgets the minimal path is clear too: add a line to the clicker that stores cumulative output in localStorage, convert it into an initial multiplier on restart, and a minimal prestige exists.
The design difficulty of prestige is entirely in pricing .
Too small a multiplier and the reset has no ceremony, the player feels cheated; too large and you have handed out a time machine, flattening every curve that follows.
The common yardstick: each reset roughly doubles the overall rate of progress, and the recommended reset point sits right where the player has just hit the wall. The wall built by the cost growth law is itself the best salesman for the reset.
One easily overlooked detail: what you keep must be a multiplier, not an asset.
Hand the player a factory and its output still obeys the linear stacking of production lines, with the price law still raising costs. A multiplier applies directly to total output and answers to no price law. Only it can restart the exponential.
Put another way, prestige sells not resources but the slope of the curve itself. What the player actually buys with achievements is time in the next cycle.
Elimination Games: One Verb, Four Mathematical Structures
Move to elimination games and the skeleton turns out to be remarkably uniform: the six games share one set-theoretic move — delete from a finite set the subset satisfying some predicate, then let the remainder heal. How the predicate is defined, how the subset is found, how the world collapses and regrows after the deletion: every distinct answer grows into a species of its own, and the site’s six games fall into exactly four mathematical structures.
Hands-on versions: Match Three, Bejeweled, Bubble Shooter, Zuma, Color Flood, Jigsaw Puzzle.
The Four Mathematical Moves of Elimination
Arrange elimination games on a two-dimensional matrix: one axis is what the predicate of elimination is, the other is whether the board is static or dynamic.
The predicate axis has three typical answers: same color and enough of them adjacent (the match-three family), connected but out of reach of support (Bubble Shooter’s floating check), correctly placed (the puzzle’s home position).
The board axis splits into static and dynamic: match three and Bubble Shooter change only when you cause a clear, while Zuma’s board itself moves every frame.
The two axes combine into the four moves this chapter walks through:
- Swap — detect — clear: the player only makes local swaps, detection and clearing belong to the system, and healing comes from gravity-fed refills. Match three and Bejeweled sit here.
- Launch — snap — clear: the player injects a new element into the board and lets the addition induce a subset that satisfies the predicate. Bubble Shooter does this on a static grid, Zuma on a moving chain.
- Expand — occupy: delete nothing; let one connected region eat the adjacent same-colored cells. This is elimination’s inverse operation, and the entire content of Color Flood.
- Permute — restore: what gets eliminated is not a piece but the abstraction of misplacement; Jigsaw Puzzle replaces the delete with a transposition.
Three of the four admit a monotone measure: Color Flood’s territory only grows, the obstacle modes’ remaining targets and Bejeweled’s overlay layers only shrink, and Bubble Shooter’s Boss HP only falls.
Every effective player action moves the measure toward the endgame.
What makes elimination games durable is precisely how the designer layers non-monotone impressions over that monotonicity with probability (random refills), geometry (launch angles), and a clock (the steadily advancing chain). The illusion of a score that rises and falls, the illusion of danger at every turn, the illusion of luck arriving.
Here they come, one at a time.
Swap Match Three
The site’s Match Three classic mode is textbook swap match three: an 8×8 board, 6 colors, swap adjacent tiles, three or more same-colored in a line clears.
Only a few lines of rules, but behind each one sits an algorithmic decision that has to be made right.
The Opening Board Is Rejection Sampling
Roll each cell’s color independently and uniformly at the start and three-in-a-rows sprout in batches on their own.
Do the arithmetic: horizontally each row has 6 windows “starting at c, covering c/c+1/c+2”, 8 rows give 48, the vertical direction another 48, so 96 windows in total. Each window’s chance of three identical cells is .
So a fully random board carries an expected three-in-a-row windows. The opening hands out two or three free clears, the rhythm breaks, and the player’s first swap loses its meaning.
The countermeasure in makeBoard is rejection sampling: fill cell by cell, and reroll whenever the new color matches the two cells to its left or the two above it.
The constraint looks back only two cells, each cell’s rejection probability is about , rerolls are the exception rather than the rule, and sampling is bound to terminate fast.
The resulting board “looks completely random”, yet strictly contains no ready-made three-in-a-row. Randomness and playability are, here, two quantities that need explicit reconciliation rather than synonyms.
Match Detection
Match detection is itself one pass of run-length encoding: scan each row left to right, extend the run while colors repeat, and at a break with a run of at least three, add the whole segment’s coordinates to a set. Then do the same down the columns.
The set deduplicates, so cells at an L or T intersection naturally appear once.
One pass over the whole board is linear, which is the precondition for a match-three engine on low-end hardware.
Swap legality uses the plainest and most correct method there is: simulate the swap on a copy of the board, run detection on the copy, and declare the swap invalid when nothing matches.
The player perceives “that move doesn’t work, the tiles bounce back”; the machine reads “this swap produced no subset satisfying the predicate”.
No heuristics, no special cases; one simulation costs the same as one real detection.
Cascades, Gravity, and Refill Probability
How the world heals after a clear sets the ceiling on how match three feels.
resolve is a loop: detect, clear, let gravity drop, detect again, until detection comes back empty.
Every cell cleared in round scores multiplied by . That is the cascade multiplier, the number the combo badge on screen shows.
The gravity step hides match three’s most interesting piece of probability design.
Each column compacts its non-empty tiles and fills the gap at the top with independent, uniformly random colors — note that refills bypass the opening’s rejection sampling.
So that earlier arithmetic — an expected 2.7 three-in-a-rows in a random region — applies exactly around the refilled cells. Chains are not a lucky Easter egg but the statistical inevitability of uniform refills.
The designer deliberately rejects random three-in-a-rows at the opening and lets them run during play; the two together produce the free-bonus structure of “the player only has to trigger the first clear, probability takes over from there”.
Refills fill only the gaps while the rest of the board keeps its memory, so every post-clear position carries history. The player’s arranging work keeps appreciating through the cascades.
Deadlock Detection
A swap board carries a risk static games do not: a dead position where no swap produces a match.
The source answers in two layers.
The first is detection: enumerate every adjacent swap. horizontal plus vertical makes 112 pairs; simulate one full detection on a copy for each, and a single success marks the position solvable — millisecond cost.
The second is remedy: when nothing is solvable, shuffle. Classic mode redeals the entire board (still through rejection sampling), up to 50 attempts. Only a dead board after 50 tries ends the game.
Obstacle mode adds a third layer of care: a shuffle rerolls only colors and keeps the obstacle layout, so an endgame the player carved out by hand does not get reset along with its obstacles.
The design meaning deserves spelling out: the system absorbs dead ends, and the player always faces a solvable board, except in the vanishingly unlikely case of 50 failed shuffles.
Honesty is underwritten by the attempt cap; despair is converted into a mathematically rare event.
The match-three page also offers an obstacle mode: 5 stones (two adjacent clears each — crack first, then shatter), 4 locks (unlocked by one adjacent clear), and 12 jellies (cleared by completing a clear on them), with victory for clearing every obstacle within 30 moves.
Its most interesting engineering detail is gravity. Once stones hold cells, a column is cut into segments, tiles fall only within their segment, and each segment compacts and refills on its own.
Obstacles here are structural: they change the board’s topology.
Bejeweled’s Overlays
Bejeweled shares the engine with match three: 8×8, 6 colors, invalid swaps bounce back, and the opening rejects ready-made three-in-a-rows (redealing the board until it is clean).
Its obstacle mode demonstrates a different obstacle philosophy on the same engine. Obstacles occupy no cells; they sit on the gems as overlay layers, rewriting the objective from score points to clear covered cells.
Placement is carved out by three random thresholds: about 14% of cells are ice with two layers. Below that, about 12% are double jelly and 18% single jelly. Altogether roughly forty-five percent of the board carries an overlay.
A clear that reaches a covered cell peels off one layer — 20 points per jelly layer, 30 per ice layer — and a cell counts as cleared when its layers hit zero.
A progress bar shows the cleared share, and clearing everything within the 30-move budget wins.
The ice locking rule is the hinge of this economy: an ice cell with both layers intact cannot be one side of a swap. The player cannot move it in or out, only let a three-in-a-row assembled by neighboring swaps wrap it up and take its hits.
Strip the first layer and the lock lifts; the second proceeds as usual.
So the value formula for each move is rewritten: a clear that touches no overlay is a net loss of one move in obstacle mode.
Run the budget: the expected total layer count is layers, so a 30-move budget means peeling about 1.5 layers per move just to break even.
The cascade is promoted from a bonus in match three to a necessity.
Set the two obstacle modes side by side and the design judgment shows: match three’s obstacles hold cells, cut gravity, and change the board’s topology. Bejeweled’s hold nothing and only press on the objective function.
The first changes what you can do; the second changes what you should do.
Another engineering difference is deadlocks: Bejeweled’s source has no deadlock detection, and whether a position is solvable rests entirely on the random reshuffling of gravity refills.
The same random refills are a bonus under a scoring objective and something the player must plan around under a clearing objective.
That is the smallest complete case of an objective function rewriting gameplay.
Bubble Shooter
The Offset Grid and Six Neighbors
Bubble Shooter uses no square board.
The site’s Bubble Shooter grid is 12 rows, 11 columns on even rows and 10 on odd, the whole thing staggered by half a diameter — an offset grid, the rectangular approximation of hexagonal close packing.
The staggering matters for adjacency: each bubble has 6 neighbors (one either side, two diagonally up, two diagonally down), two extra diagonal paths over a square cell’s 4-neighborhood.
Same-color clusters therefore look rounder, and the cut-the-support tactic gains a dimension.
The neighbors function enumerates the six directions by row parity, and every connectivity computation in the game — same-color detection, the floating check — is built on that adjacency table.
The starting position is the first 6 rows, an 85% chance of a bubble per cell, in 6 colors.
Those 15% holes are not decoration: snapping needs somewhere to land, the initial sparseness leaves aiming some margin, and it makes an opening plan of where to fill and where to cut possible in the first place.
Launching
The launch end is a stretch of continuous geometry.
Mouse aim derives the angle with atan2, the arrow keys nudge it 0.12 radians a press, space or click fires. The angle is clamped to at least 0.15 radians (about 8.6 degrees) above the horizontal. Flat shots hugging the bottom edge are forbidden; every shot is forced to help build the grid rather than sweep along the floor.
Projectile speed is 7 pixels per frame, and the horizontal velocity flips on hitting a side wall. Mirror reflection turns one aim into a polyline; banking off a wall to hit a bubble’s back is technique, not exploit.
Hit detection compares squared distance against ( being the bubble diameter): an effective radius of about , slightly under one bubble.
A slight overlap still counts, so the boundary feels lenient. The trick of a detection radius slightly smaller than the visual one is standard in bullet-hell and shooter games — the error stays on the player’s side.
An engineering fact worth noting in passing: per-frame constants like projectile speed and chain advance rate bind the game’s tempo to the render frame rate. Between a 60Hz and a 144Hz screen, projectile speed differs by more than double.
The trade-off between frame loops and time steps was unpacked in the earlier piece on game loops. Bubble Shooter is a living specimen of running bare on a variable time step: the physics is simple enough not to need a fixed step, and the cost is only a drift in feel across refresh rates — a fair trade for this kind of casual play.
Snapping and Two Floods
When the projectile crosses the top or hits an existing bubble, snapping happens: the continuous coordinates are rounded to the nearest slot. If the target cell is taken it falls to the first empty neighbor, and only when no empty neighbor exists is it a loss.
Discretization happens only at the moment of impact; the whole flight stays continuous. “Continuous aiming, discrete landing” — the shared skeleton of every bubble shooter.
Snapping is followed by two floods with entirely different predicates.
The first takes same color as its predicate, spreading the same-color component out from the landing point; at three or more the whole cluster clears for 10 points a bubble.
The second takes reachability of the top row: a connectivity check from every top-row bubble, after which any floating bubble that cannot reach the top drops as a group, for 20 points each.
The price gap between the two floods is precise design language: cutting a support to drop 8 bubbles pays better than dutifully clearing 3 same-colored ones.
The game rewards “cutting the bridge” over “cutting a lot”, which is why expert aim always heads for the structural chokepoints.
The losing line is the bottom row: any bubble reaching it ends the game.
Boss mode makes that pressure explicit. The Boss has 100 HP, taking 5 per cleared bubble and 2 per dropped one. It acts every 9 seconds, alternating between pressing down a full row and throwing indestructible gray stone bubbles, and if you clear the board it refills the top four rows to eighty percent.
In the original, failure is “your own tower collapsed”; in the Boss fight it is “the opponent is raising the stakes”. Same grid, with the pressure moved from endogenous stacking to an exogenous clock.
Zuma
Zuma’s contribution to the genealogy is the second axis: the board itself moves.
The site’s Zuma replaces the static grid with a one-way conveyor: a string of colored beads advances at a steady 0.4 pixels per frame toward the hole at the left end, and the tail touching the hole is a loss.
The board no longer has a “layout”, only a “countdown”: chain length times spacing divided by speed is the total time the player gets, and it lengthens as clears push the chain back and shortens with every lapse.
Pressure turns from a geometric quantity into a temporal one.
The opening is 6 beads in 5 colors. Generation applies one gentle random constraint: when a new bead matches the previous one, there is a 60% chance it is swapped for a neighboring color.
Not a hard ban but probabilistic suppression, far looser than match three’s strict rejection sampling. The occasional ready-made pair survives, a small taste of an instant split.
The launch end is isomorphic to Bubble Shooter: mouse aim, click to fire, 8 pixels per frame, hit detection by a squared-distance threshold of .
Insertion goes before or after the struck bead depending on their relative horizontal coordinates.
The chain semantics after insertion differ completely from Bubble Shooter’s, and that is the design difference most worth chewing on.
Bubble Shooter’s chain is a physical chain: after a clear the bubbles above lose support and fall, so the chain propagates along gravity.
Zuma’s chain is an algebraic chain: after a clear the left and right segments close up directly, and the code recursively checks the two newly adjacent colors. If they match and total three, another round runs.
The former depends on grid topology, the latter only on sequence structure. A chain in the former needs the player to bury a same-colored cluster underneath; in the latter it only needs the chain to happen to hold repeated segments.
The two chains give the player entirely different things to anticipate: one is read spatially, the other sequentially.
In pacing terms the conveyor’s constant speed is deliberately slow. At 60Hz that is about 24 pixels a second; a chain with 30-pixel spacing advances less than one bead per second.
Victory therefore depends almost not at all on reaction speed but on decision density: every shot has to pick an insertion point on the chain, weighing the current bead color, the next bead color, and the adjacent same-color segments already there — the search space is the chain’s length, not the board’s cell count.
Match three trains pattern spotting, Bubble Shooter trains geometric planning, Zuma trains sequence decisions under a countdown. One verb, three cognitive loads.
Color Flood and Jigsaw Puzzle
Color Flood
Color Flood flips elimination entirely: instead of deleting elements and letting the world collapse, one region grows until it swallows the world.
The site’s Color Flood board is 14×14 in 6 random colors. The connected same-color region holding the top-left cell is the player’s territory; each move picks a color, the territory absorbs every adjacent cell of that color and recolors itself as a whole (textbook flood fill), and dyeing the entire board one color within 25 moves wins.
Picking a color the territory already has is an invalid move: the source ignores it outright and charges no step. Even wasting a move is precisely defined.
How few moves does this family of flood-fill games (the Flood-It family) need? There is a clean lower bound to derive.
The territory expands by at most one layer of adjacency per move. Absorption requires adjacency, and newly absorbed cells stop conducting once recolored, so the territory’s maximum Manhattan distance grows by at most one per step.
The far corner sits at Manhattan distance from the origin. Let be the greatest distance the opening territory already reaches. Unless the top-left corner happens to have a same-colored neighbor (about a thirty percent chance with 6 colors), is almost always 0.
Then winning takes at least moves.
Check that against the hard-coded 25-move cap: holds strictly at .
In other words, under the current parameters the win condition is mathematically unreachable even with every move played perfectly. Even with a free same-colored neighbor at the opening, all 25 moves would have to push the farthest boundary forward exactly one cell, none wasted.
This is not a question of execution or strategy but of budget. Raise the cap above 26 and the game turns from a guaranteed loss back into a hard one.
Reading source sometimes turns up mathematical facts the author may not have known they wrote — an unexpected dividend of putting rules into code.
One level up is complexity: minimum-move flood filling is NP-hard on generalized boards and color counts, with no usable closed form.
The greedy strategy players actually lean on — absorb the most border cells each step — drifts from optimal in the worst case.
The 14×14 board compresses that greedy-but-not-optimal gap into a felt size: choosing a color cannot look only at immediate absorption, it has to consider what color interface the new border leaves for the next move.
Jigsaw Puzzle
Jigsaw Puzzle sits at the other end of the genealogy: no randomness, no same colors, no elimination — just a scrambled permutation to restore.
Two pieces of mathematics in the site’s Jigsaw Puzzle implementation deserve a separate look.
The first is slicing.
The source never actually cuts the image into pieces. Each piece uses CSS background positioning to see its own cell of the original: background-size set to , background-position taken as and .
Percentage positioning aligns the image’s mark with the container’s mark. When the image is exactly times the container’s width, the -th piece (counting from zero) aligns at .
One formula saves an actual crop and image objects; switching difficulty between 3×3 and 6×6 does not even need the original resent.
The second is scrambling and solvability.
The scramble runs Fisher–Yates over the pieces with a single extra constraint: never shuffle into the solved state. If it lands on the identity permutation, the first two pieces are swapped.
Play is transposing any two pieces.
An essential difference from the fifteen puzzle is worth spelling out: every move there is a restricted permutation, the reachable states are only half of all arrangements, and parity is a wall. Transposing any two pieces generates the entire symmetric group, so every scramble is restorable and no deal is unsolvable.
The puzzle player’s difficulty is always “how to arrange”, never “whether it can be arranged”.
Race mode straps a clock on: pieces get seconds — a linear budget of 4 seconds per piece, timeout is a loss, and the fastest record is stored locally.
It is also the only game in this genealogy that permits regression: the first five keep ledgers that only move toward the endgame — territory only grows, targets and overlays only shrink, scores only climb. A single transposition in the puzzle can seat one piece while wrecking two already placed.
Its difficulty therefore comes not from pattern recognition but from planning and working memory. What gets eliminated is the abstraction of misplacement, and misplacement reproduces itself as you operate.
Word Games: Pricing the Probability of Letters
Where elimination games work the board, word games swap the board for language itself: they look like vocabulary tests, but underneath they all settle the same thing — the probability of letters appearing. Wherever probability shows up, the game charges for it: Scrabble pricing marks it up as scores, anagrams compress it into index signatures, crosswords translate it into crossing constraints, guessing games turn it into items of feedback. The site’s six word mini-games are six ways of cashing out one formula: letter probability × position constraints.
Hands-on versions: Scrabble Scorer, Anagram, Word Scramble, Crossword, Number Guess, Hangman.
Pricing the Letters
Open the source of the Scrabble Scorer and the first thing you see is a twenty-six-line price list.
A, E, I, O, U, L, N, S, T, R are worth 1 point each. D and G are worth 2. B, C, M, P are worth 3. F, H, V, W, Y are worth 4. K sits alone at 5. J and X are worth 8. Q and Z bring up the rear at 10 each.
Strictly speaking the table is the inverse function of English letter frequency. In modern English text E appears about 12% of the time, T about 9%, while Q and Z are both under 0.1%. Frequencies two orders of magnitude apart, scores exactly tenfold apart.
The pricing logic can be stated in one sentence: the score compensates for scarcity. You can scare up a dozen E’s at almost any moment, so E is cheap. You may not draw a Q once in a whole game, so Q has to be expensive — otherwise nobody would design tactics around it.
Next to the price list sits a supply list. The program’s letter bag is a hardcoded string; expanded and counted it holds 98 tiles. A has 8, E and I have 10 each, O has 8, N and T have 6 each, R, D, L, S, U have 4 or 5 each, most of the rest have 2, and Q, X, Z have only 1 each.
The classic Scrabble set has 100 tiles (12 E’s, 1 each of J and K), so the site version makes small adjustments. The skeleton is untouched: supply of the high-priced letters is strictly scarce. Of the 98 tiles, Q and Z together contribute 20 points, a share of the bag’s value far above their 2% share of its count.
Scarcity converts straight into probability. Drawing 7 of 98 without replacement, the chance of pulling at least one Q is
(The second step uses the identity .)
So on average a Q turns up on the opening rack once every fourteen games — and when it does, you may still not be able to play it, since Q almost has to be followed by U. That pairing constraint is the frequency table’s unwritten rule for players: expensive things usually need another scarce thing before they can circulate.
The Other Side of Supply
The most interesting letter in this pricing is S.
By frequency it sits in English’s top ten, yet it costs 1 point, the same as E.
The reason: S is English’s universal plural suffix. Any noun already valid on the board becomes a new word with an S attached, and the bonus squares get recalculated along the way.
The designers pressed its monetary value to the floor and let it charge elsewhere, in the currency of “grafting ability”.
In the whole scoring table points compensate scarcity; a resource that is plentiful but useful gets charged for by the board in other ways. Understand S and you understand the entire logic of the table.
The supply list also yields a baseline. The bag’s total value is 200 points over 98 tiles, about 2.04 per tile, so a 7-tile rack expects a base score around 14.3.
That number is the zero point of every placement decision. Play a word with no bonuses and check it against that first. Below 14 and the move is spending your luck; above and the word itself beat the market, with the margin left for bonus squares to amplify.
What the probability table cannot give you is variance. A 7-tile rack naturally rides the swings of the vowel-consonant ratio; an all-consonant rack is a nightmare every player has had.
The site implementation deals the player and the computer a separate 98-tile bag each, so neither depletes the other. There is no zero-sum game of “my opponent drew the Q”, only independent sampling of “is my bag feeling generous this game”.
Playing all 7 tiles earns a 50-point BINGO bonus, and that number turns “hold or play” into an expected-value problem: bank a small word now, or wait one more draw to make seven?
The Board Is a Multiplier
If the scoring table is the letters’ primary market, the board is the secondary market.
61 bonus squares are scattered over the 15×15 grid. 8 triple-word (TW) squares, holding the four corners and the midpoint of each side. 17 double-word (DW) squares, including the central start ★. 12 triple-letter (TL) squares. 24 double-letter (DL) squares.
The order of operations in the scoring function is written very clearly:
word score = Σ(letter score of each square × that square's letter multiplier) × Π(word multipliers along the way)Letter multipliers act only on their own square; word multipliers act on the whole word, and multiple word multipliers multiply together. A word hitting two DW squares at once is ×4.
This order, addition first and multiplication after, determines every placement decision.
In the addition layer a Q on a TL goes from 10 to 30, a marginal 20 points. In the multiplication layer the same Q, if its word also catches a DW, doubles the whole word.
Run the numbers on QUIZ. Base . Q on a TL gives . If that square is also a DW, .
One Q, different positions, a fourfold spread in price. What the player is really managing is not letters but the relative geometry of letters and bonus squares.
Placement has one hard constraint: every letter laid in a turn must be collinear (same row or column). The program extends the new letters along the line in both directions, counts any connected old letters into the full word, and rejects non-collinear placements outright.
That rule turns free collage into “working along the extension lines of existing words”. Every score creates or blocks bonus squares for the next move, and all the board’s tension comes from there.
Rack Management
The variance of supply lands on the 7-tile rack, so rack management becomes a second craft alongside scoring.
The site implementation equips that craft with two unobtrusive but telling buttons.
Recall: pull every tile placed on the board but not yet committed back to the rack in one click. A misplaced tile costs no heartache; the cost of trial and error drops to zero.
Shuffle: randomize the rack’s order. The second looks redundant but is a classic counter to shape fixation. Stare at one set of letters in one order long enough and only those few word-starts remain in view; change the arrangement and combinations hidden by position float up on their own.
The program also lets you recall placed tiles one at a time (click a placed tile and it returns to the rack), so exploratory layout — spread it out and try, then recall the lot — becomes the default workflow. The board doubles as scratch paper alongside its scoring duties.
Design like this has a generic name among game tools: lowering the cost of exploration. Let players dare to try, and the output of trial and error — intuition for letter combinations — settles in faster.
The computer opponent reduces this economics to the extreme, which usefully throws rack management’s value into relief from the other side. Its lexicon is 30 common words (CAT, STAR, QUIZ, JAZZ territory); each turn it builds the rack into a multiset and finds the first word whose letters it has, or swaps the whole rack when nothing fits.
Scoring is the base score times a coefficient that looks only at word length — ×3 for 7 letters and up, ×2 for 5 to 6 — plus the 50-point seven-letter bonus.
It ignores bonus squares entirely. An opponent that believes only “length is wealth” demonstrates the scoring system’s first layer cleanly: score with no sense of position has a ceiling you can see at a glance.
Its lookup logic is worth using as a code-class example, though: multiset comparison, one pass, zero backtracking. With a 30-word lexicon, brute force is the optimal solution.
Anagrams
Scrambling a word’s letters makes an anagram; restoring the scramble is the shared theme of Anagram and Word Scramble.
The mathematical bedrock of the genre is an observation so plain it’s easy to skip: words that are anagrams of each other share one sorted signature. Sort the letters and listen, silent, enlist, tinsel all become eilnst.
The signature is the perfect primary key. Compute one signature per dictionary entry at preprocessing time, sort the input at query time, look it up in a hash table, and the whole same-letter family comes back in one fetch.
Real anagram dictionaries and the candidate generation in some spell checkers use exactly this trade of O(n log n) preprocessing for O(1) lookup.
Families, Generators, and Rejection Sampling
The site’s generator mode builds no full dictionary; it ships 15 hand-curated families.
The listen family has 4 members. The stop family is the most prosperous: stop, tops, opts, pots, spot, 5 in all. skate, stake, steak, takes are a family of 4. Further down are smaller households of two or three: earth/heart/hater, angel/angle/glean, night/thing, lemon/melon, dusty/study, care/race/acre, below/bowel/elbow.
Enter a word and the program finds its family and lists the rest. How many words one bag of letters can legally hold depends on the language’s lexicon, not on the letters — the most direct demonstration of signature granularity.
The shuffle itself has an engineering detail. A naive permutation has a chance of returning the word unchanged — for six letters, ; the player spots at a glance that the “scramble” is the original word, and the experience breaks on the spot.
The source’s fix is rejection sampling: shuffle, check whether it equals the original, redo if so. The Anagram version caps retries at 20; the Word Scramble version is an unbounded while loop.
With a per-draw hit rate of , the expected number of retries is about 1. A fairness problem an if cannot settle, fixed with two lines of rejection sampling. The most common move in randomized algorithms: if the sampling distribution is wrong, resample until it is right.
Information Has a Price Tag
The scoring rules of Anagram hide a piece of information economics. A straight correct answer earns 10 points; take a hint first and you get 5. One hint is worth exactly 5 points.
Its timed mode pushes the pricing further. Each word gets a 20-second countdown and scores “10 + seconds remaining”; the faster you answer the more you earn, and a timeout skips to the next question empty-handed (8 words a round).
Once speed has a price, players hunt on their own for the marginal balance between “one more second of thought, one more point” and “the clock burns out and you have nothing”.
How many points a hint is worth is essentially how much it cuts the candidate set. That measure of information is the same thing as the value of each piece of feedback in the guessing games — we’ll come back to it shortly.
The Anagram game has two more modes worth mentioning. Cryptogram mode swaps anagrams for a substitution cipher: generate a random letter-to-letter mapping, encrypt a proverb character by character, and crack it letter by letter with frequency analysis and pattern matching. Multiplayer mode pulls Chinese proverbs into the cipher too, giving each distinct Chinese character a random code from A to Z.
The Cryptogram
Cryptogram mode happens to give this letter economics a stage for both attack and defense. In the Scrabble game the player prices letters by frequency; the cryptanalyst verifies letters by frequency.
A substitution cipher preserves all of the plaintext’s statistical structure. The most frequent letter in the ciphertext is most likely E or T in disguise. A three-letter word that keeps recurring is probably THE. A lone letter after an apostrophe is almost certainly S or T.
What the cryptanalyst does is the scoring table designer’s inverse: align ciphertext frequencies with English’s prior frequencies and claim them one by one.
The source knows to close that shortcut. When generating the mapping it retries up to 40 times until no letter maps to itself. Mathematically that is a derangement; a random permutation is one with probability approaching , so two or three tries usually do it.
And the payoff of derangement is sealing off all the free anchors like “A encrypts to A”, leaving the cryptanalyst to work honestly from statistical features.
As for the Chinese proverbs in multiplayer mode, once the prior frequency table fails you have to lean on character counts, punctuation, and the fixed collocations of set phrases. The same reasoning of prior × evidence, but swap the prior and the posterior changes wholesale — the cracking intuition has to be swapped out with it.
As for Word Scramble, it is the lightest link in the chain. 20 six-letter puzzles (planet, rocket, castle, dragon difficulty tier), 10 points per correct answer, a definition hint when stuck, and the option to skip ahead. The timer counts up and only keeps accounts, no penalty — a no-pressure table overall.
Don’t underestimate the search space of the puzzle, though. Six letters have permutations, and a human is obviously not scanning 720 candidates linearly but executing layer after layer of pruning.
Q is almost always followed by U, and that one rule kills every permutation with Q not before U. Vowels tend to appear at intervals. Common consonant clusters rarely end a word. 720 is cut to a few dozen, and a few dozen are cut to one by the dictionary query “is this a word”.
What the player runs unconsciously is heuristic depth-first search, and all 20 puzzles sit exactly at the humanly solvable scale. Two letters longer and pushes naive enumeration out of the game; the value of pruning grows exponentially with length.
Chinese Crosswords
The mechanical core of the Crossword is not words but intersections.
The site version is a Chinese crossword. The word list holds over 180 words, almost all two-character (人生 “life”, 天气 “weather”, 大学 “university”, 火山 “volcano”, 西瓜 “watermelon”…), plus four three-character words — “科学家” scientist, “对不起” sorry, “没关系” it doesn’t matter, “辛苦了” thanks for your effort — deduplicating to 142 distinct Chinese characters carrying the crossing duties.
Generating a grid goes like this. First build an inverted index over the word list: each character maps to every word containing it. Give each word a “crossing potential score”, the number of other words sharing at least one character with it. The top scorer becomes the seed, laid horizontally at the center of the 15×15 board.
Then comes multi-round scanning. Early rounds set a word-length threshold (long words first), later rounds relax it round by round. Each round loops “collect every crossable position on the board × rank candidates by overlap with characters already placed”, placing whatever fits until nothing fits.
The whole generation runs several attempts (8 on easy, 16 on hard), each with a new seed and a fresh random order, keeping the grid that placed the most words. Difficulty here is just the target word count: 6 on easy, 10 on normal, 16 on hard.
The legality checks before placement are harsher than you’d expect — four in all. The crossing character must match. Apart from the crossing points, the new word may not cover any existing letter. Every cell perpendicular to each cell of the new word must be empty (so glued-together strings can’t spell anything beyond the grid). And the cells before the word’s head and after its tail must be empty too.
Together the four checks guarantee exactly one thing: every run of consecutive characters on the board is precisely one word from the lexicon.
English crosswords tolerate plenty of coincidence strings for the sake of grid density; two-character Chinese words are structurally too brittle. This version trades “touch only at crossing points” for semantic strictness. It sacrifices density so that every cell’s meaning stays clean.
The solving side mirrors the generating side. One clue, “the course of a person’s life”, plus one known first character, and the candidates shrink from 180-odd to about a dozen. One more crossing character and often only the unique solution remains.
Variables are cells, values are characters, words are constraints. This is the everyday shape of a constraint satisfaction problem.
And the UI makes the propagation visible to the naked eye: click a clue to select the whole word, each cell takes one character, the program re-checks every clue after each input, and all-correct auto-completes — no submit button needed.
Stuck, you can reveal every answer in one click. One small detail worth noting: clicking that button again does not retract the answers but deals a fresh grid outright. The program offers no continuation for a peeked-at board — if you want to play, play a clean one.
Generator and play are two side-by-side mode tabs sharing one generation kernel. Every word you fill in correctly makes every other clue a little easier. Constraint propagation, that algorithms-course term, is here the concrete feel of “fill one square, watch the neighboring candidates collapse”.
Pruning in the Guessing Games
The previous sections were all “word known, order unknown”. The last genre inverts it: the word itself is unknown, and every move shrinks the candidate set.
Hangman is the unordered one. The lexicon holds 30-odd common words (nearly all six letters), and you get 6 wrong guesses. Guess a letter right and all its positions in the word light up at once. Guess wrong and the gallows gains a stroke; six strokes end the game.
Letters have no order among them, so binary search doesn’t apply, but the logic of asking by probability stands. Sort the 26 letters by frequency and E, T, A, O, I, N are natural probes: a hit earns the most positional information, a miss buys the widest exclusion for the budget spent.
The source makes that feedback loop very explicit. Guessed letters leave green (in the word) and red (not in the word) marks on the keyboard, and together with the known positions in the mask (say S _ _ _ E R) the candidate set collapses far faster than intuition suggests. Beyond the on-screen keyboard it also listens to the physical one, the 26 letter keys doubling as hotkeys.
Six wrong guesses look harsh, but they quietly follow the frequency table’s stratification. The first six or seven high-frequency letters will probably hit; the real test is reading the remaining blanks from the position pattern. High-frequency letters are cheap, so you dare use them as probes — E costing only 1 point in the Scrabble table runs on the same pricing logic.
Number Guess is the ordered one, the textbook opener for this class of problem. Think of a number between 1 and 100; each guess gets back only “higher” or “lower”.
The number line is monotone, so an optimal solution exists. Guess the midpoint of the current interval, each reply cuts the candidates exactly in half, and guesses must pin the answer. And that is an information-theoretic lower bound; no strategy can reliably do better.
Binary search’s precondition (a monotone search space) and its cost (halve within one step) lie bare in this little game. To carry the line of thought back to a proper problem set, the binary search section of the site’s Hot100 algorithm notes has the full problem list and the monotonicity criteria.
The site implementation also keeps a ledger. Every guess and its verdict enter the history, and the best record is stored in the browser locally. You can see at a glance how far you are from the theoretical bound of 7.
Incidentally, this page is a training collection. Number guess is just the default tab; memory match, attention counting, mental arithmetic, reaction speed, and the 24 game all hang under the same tabs. The 24 game, when you give up, brute-forces every pairwise combination and operation order of the four numbers to find a solution. When the search space is finite, brute force plus pruning is forever the most honest algorithm.