On this page
  1. Why this article exists on a games site
  2. Rule 1: failure must be attributable
  3. Rule 2: the first thirty seconds teach
  4. Rule 3: budget spawns, do not scale them blindly
  5. Rule 4: telegraph everything that can kill
  6. Rule 5: give the player one thing to get better at
  7. Rule 6: instant restart, always
  8. Rule 7: test against numbers, not feelings
  9. Building the loop before the content
  10. Tuning numbers that actually matter
  11. Making a game readable
  12. Common failure modes and their symptoms
  13. Testing without a test team
  14. What belongs in a shared engine

Why this article exists on a games site

We build every game on Zombie Games Hub ourselves, and the rules below are the ones we actually apply. Publishing them serves two purposes: it explains why our games behave the way they do, and it is genuinely useful to anyone building something similar.

Nothing here is theoretical. Each rule exists because breaking it produced a game that playtested badly, and each is followed by the specific failure it prevents.

Rule 1: failure must be attributable

A player who dies should be able to name the mistake. Not necessarily immediately, but on reflection — 'I reloaded too late', 'I backed into a corner', 'I missed the runner'.

Deaths that cannot be attributed to a decision feel unfair regardless of how difficult the game actually is, and unattributable deaths are the primary reason players abandon arcade games. The usual causes are avoidable:

  • Off-screen spawning near the player. Enemies must appear where the player can see them or from a clearly telegraphed edge.
  • Random introduction of new enemy types. A brute in the first ten seconds teaches nothing.
  • Instant-kill mechanics with no wind-up. Every lethal threat needs a readable tell.
  • Invisible state. If a resource matters, it needs a visible meter.

If a playtester says 'that was unfair' more than once, the problem is almost never difficulty. It is attribution.

Rule 2: the first thirty seconds teach

The opening of an arcade game is not a difficulty setting, it is a tutorial that does not announce itself. A first-time player must survive long enough to learn the control scheme, the enemy appearance and the movement speeds.

Our target is that a complete beginner survives at least thirty seconds on their first attempt in every game. That is measurable and we test against it. Games that fail the test get a gentler opening spawn budget rather than a difficulty option, because a difficulty menu asks the player to make a decision before they have any basis for it.

Rule 3: budget spawns, do not scale them blindly

The naive approach to escalation is to multiply spawn rate by elapsed time. This produces runs that are boring at the start and impossible at the end.

A budget approach works better. Each wave or interval gets a point budget, enemies cost points by type, and the director spends the budget with constraints on how many can be alive at once. This gives you three useful levers independently: total pressure, composition and concurrency.

EnemyCostRole
Walker1Baseline pressure and crowd shape
Runner2Urgency; forces prioritisation
Crawler2Visual challenge; punishes tunnel vision
Brute5Resource drain; forces disengagement

The concurrency cap matters more than the budget. A wave of thirty walkers arriving eight at a time is a fair challenge; the same thirty arriving at once is a screen-filling mess that cannot be played well by anyone.

Rule 4: telegraph everything that can kill

Every lethal or costly event needs a signal that precedes it by at least the player's response time — call it 400 ms as a working minimum, and more for anything requiring a decision rather than a reflex.

  1. Spawns: an edge indicator or a visible approach from off-field.
  2. Charges and lunges: a wind-up animation or colour change.
  3. Timers: a visible countdown, not a sudden expiry.
  4. Resource exhaustion: a warning state before the resource hits zero.
  5. Difficulty steps: an announcement, even if only a wave number changing.

Telegraphing does not make a game easier in any meaningful sense — a skilled player was going to react anyway. It makes the game learnable, which is what determines whether anyone stays long enough to become skilled.

Rule 5: give the player one thing to get better at

A game that tests aim, positioning, resource management and reaction simultaneously is not four times as deep. It is unreadable, because a player cannot tell which of the four caused any given failure and therefore cannot improve at any of them.

Every game on this site has a primary skill and at most one secondary. Zombie Target is aim and nothing else. Zombie Rush is movement and nothing else. Zombie Hunter is prioritisation with aim as the secondary. The flagship, Ultimate Zombie Arcade, is the deliberate exception — and it separates its skills into stages rather than mixing them.

Rule 6: instant restart, always

The gap between failing and playing again determines how many attempts a player makes, and the number of attempts determines whether they improve.

Our target is under one second from game-over to playable, achieved with a single click or the R key. No confirmation dialogs, no score submission step, no interstitial. The game-over screen shows the result and a Play Again button focused by default, so the keyboard path is Enter.

This is also an accessibility requirement, not just a retention one. A player using keyboard navigation should never have to tab through a screen to restart.

Rule 7: test against numbers, not feelings

Balance discussions collapse without measurements. The four numbers we test against for every game:

  • First-attempt survival: at least 30 seconds for a complete beginner.
  • Median run length: between one and four minutes after five attempts.
  • Skilled run length: at least four times the first-attempt time — if it is not, skill is not expressing itself.
  • Improvement visibility: a measurable gain within ten attempts.

That third number is the most diagnostic. If a very good player can only survive twice as long as a beginner, the difficulty curve is too steep or too linear, and no amount of content will make the game feel rewarding.

Building the loop before the content

The most common structural mistake in a first arcade game is building content before the loop is right — levels, enemies and art on top of a core that is not yet fun for thirty seconds.

A useful discipline: get one enemy type, one player action and one failure condition working, then play it for ten minutes. If ten minutes of one enemy type is boring, adding five more will not fix it, because the problem is in the verb rather than the variety.

  1. One verb. Shoot, dodge, jump, place. Pick one and make it feel good in isolation.
  2. One constraint. Ammunition, cooldown, space, time. Without a constraint the verb has no decisions attached.
  3. One failure condition. Clear and immediate.
  4. Then, and only then, variety. Enemy types, environments, escalation.

Every game on this site started as a prototype under a hundred lines that was playable before it was interesting. The ones that failed that ten-minute test were rebuilt around a different verb rather than padded with content.

Tuning numbers that actually matter

Balance discussions sprawl unless they are anchored to specific quantities. These are the ones that change how a game feels most.

QuantityTypical rangeWhat it controls
Player speed vs. slowest enemy3–5× fasterWhether escape is always possible
Player speed vs. fastest enemy1.05–1.3× fasterWhether runners are a real threat
Time-to-kill, basic enemy1 hitWhether crowds are clearable
Time-to-kill, heavy enemy4 hitsWhether kiting beats fighting
Reload / cooldown0.9–1.8 sWhether timing is a decision
Difficulty half-life45–70 sWhere the ramp and plateau land
Contact damage10–20% of max healthHow many mistakes a run can absorb

The two speed ratios do most of the work. If the fastest enemy is slower than the player by a wide margin, nothing is ever urgent. If it is faster, the player has no agency. The narrow band just above parity is where chases become tense without becoming hopeless.

Making a game readable

Readability is the property that separates a hard game from a frustrating one, and it is mostly a visual-design problem rather than a balance problem.

  1. Silhouette before colour. Enemy types should be distinguishable by shape and size alone, so that colour is reinforcement rather than the only channel.
  2. Size encodes threat consistently. Across all thirty games here, smaller and lighter means faster; larger and darker means tougher. Consistency across a library is worth more than cleverness within one game.
  3. Player must always be findable. A distinct colour that nothing else uses. Losing track of your own character for even a moment is fatal and unfair.
  4. State changes need a visual and an audio channel. Reload, cooldown, damage, pickup. One channel is not enough for players who cannot use it.
  5. Keep the background quiet. Detailed backgrounds compete with gameplay elements for attention and the gameplay always loses.

A good readability test: take a screenshot mid-run and show it to someone who has never played. They should be able to point at the player, name the most dangerous thing on screen, and say what is about to happen.

Common failure modes and their symptoms

Symptom in playtestingLikely causeFix
'That was unfair'Attribution failureTelegraph, or stop spawning off-screen
'It got boring'Curve too flat, or one dominant strategyIntroduce a threat that punishes the strategy
'I don't know what to do'Too many systems at onceCut to one primary skill
'It's too hard'Usually the opening, not the whole gameSoften the first 30 seconds only
Everyone plays identicallyOne strategy dominatesAdd a cost to it, not a nerf
Scores cluster tightlyRandomness dominates skillReduce variance, not difficulty

The last row is subtle and important. If skilled and unskilled players score similarly, adding difficulty will not help — it will make everyone score less. The problem is that outcomes are not tracking decisions, which is a variance problem.

Testing without a test team

Most people building an arcade game are testing it alone, which introduces specific blind spots. Some workarounds that genuinely help.

  1. Automate a random-input run. A bot pressing keys at random should survive roughly ten to twenty seconds. Much less means the opening is too harsh; much more means it is too generous.
  2. Play with your non-dominant hand. A crude but effective proxy for a less skilled player, and it exposes control schemes that only work when you are precise.
  3. Leave it for a week. Returning without muscle memory reveals how the opening actually reads to a newcomer.
  4. Watch someone play once and say nothing. The urge to explain is exactly the signal that something is not readable.
  5. Log where runs end. A histogram of end times tells you where the curve is too steep far more reliably than memory does.

The first of those is what we use here. Every game in this library is run headlessly with synthetic input for thousands of frames before release — it catches crashes, and the survival time under random input is a genuinely useful tuning signal.

What belongs in a shared engine

If you are building more than one arcade game, the question of what to share becomes the main architectural decision. Share too little and every game reimplements the loop; share too much and the engine starts dictating what games can exist.

The line that worked for us: share anything that should behave identically, and nothing that expresses what a game is.

SharedNot shared
The frame loop and delta-time clampingWhat update() does
Input abstraction (actions, not keys)Which actions a game uses
State machine and overlay screensWin and loss conditions
HUD rendering and field formattingWhich fields exist
Object pooling and collision mathsEntity behaviour
Particles, screen shake, audioWhen they fire
Personal bests and play recordingWhat counts as a result
Canvas sprite drawing helpersScene composition
Difficulty curve functionsWhich dial a game turns

The right-hand column is what makes thirty games different from one game with thirty levels. Every item in it lives in the individual game file, which is why those files are a few hundred lines each rather than a few thousand.

The test we used: if adding a feature to the engine required a game to opt out of it, it did not belong in the engine. That rule killed several plausible-sounding shared systems — a universal enemy AI, a shared upgrade framework, a standard wave format — all of which would have made the games more similar to each other for no gain.

Key takeaways

  • Every failure must be attributable to a decision the player can name.
  • The first thirty seconds are a tutorial. Beginners must survive them.
  • Budget spawns by enemy cost and cap concurrency — the cap matters more than the budget.
  • Telegraph anything lethal by at least 400 ms; telegraphing makes games learnable, not easy.
  • One primary skill per game, and a skilled run should be at least four times a first attempt.
  • Get one verb, one constraint and one failure condition fun for ten minutes before adding content.
  • The ratio between player speed and the fastest enemy does more for tension than any other number.
  • Enemy types must be distinguishable by silhouette, with colour as reinforcement rather than the only channel.
  • If skilled and unskilled players score similarly, the problem is variance rather than difficulty.
  • Share what should behave identically; keep anything that expresses what a game is in the game file.

Frequently asked questions

Do I need a game engine to build something like this?
No. Every game on this site is plain JavaScript drawing to an HTML5 canvas, with no framework and no build step. The shared engine here is roughly two thousand lines.
How long does one of these games take to build?
With a shared engine handling the loop, input, state and HUD, an individual game is mostly its own rules — typically a few hundred lines. The engine itself took considerably longer than any single game.
How do you decide a game's difficulty rating?
By execution pressure rather than depth. Zombie Roadblock is strategically the deepest defense game here and rated Easy, because it never asks you to react quickly.
What is the most common balance mistake?
Concurrency. Designers tune total enemy count carefully and then let too many arrive simultaneously, which converts a fair challenge into an unreadable one.
How long should the first prototype take?
Hours, not weeks. If a prototype is not playable quickly, the design has too many moving parts to evaluate.
How do you test a game alone?
Random-input runs, playing with your non-dominant hand, leaving it for a week, and logging where runs actually end.
Illustrated portrait used for the Zombie Games Hub editorial byline

Alex Morgan

Gaming Editor & Arcade Content Specialist

Alex Morgan is the editorial byline for everything published on Zombie Games Hub — game design notes, strategy guides and the tuning decisions behind all 30 arcade titles. More about our editorial byline.

Published · Last updated