TinyGames · how it works
A vertical shooter with a hangar between missions. Fly, shoot, bank the bounties, buy a bigger gun, fly again.
Open index.html. No build step, no dependencies, no images.
talon/
index.html markup
style.css the frame around the canvas
js/engine.js copied unchanged from Overdrive - the sixteenth game on it
js/patterns.js bullet patterns, enemies, missions and the shop
- no pixels, no engine, no DOM
js/talon.js the playable layer
test-patterns.js node test-patterns.js
A bullet pattern that covers every square the player could reach is not difficult, it is broken — and by eye it is indistinguishable from one that is merely hard, so playtesting will not find it.
So patterns here are pure functions from (source, target, phase) to a list of bullets, with no reference to the world. That makes them cheap to fire thousands of times in a test and ask, for each firing: was there anywhere the player could have been standing, and could have reached in time, that this pattern does not cover?
$ node test-patterns.js
can it be dodged:
single 900 firings narrowest escape 58 of 61 places always dodgeable
twin 900 firings narrowest escape 57 of 61 places always dodgeable
fan 900 firings narrowest escape 38 of 61 places always dodgeable
burst 900 firings narrowest escape 33 of 61 places always dodgeable
lance 900 firings narrowest escape 58 of 61 places always dodgeable
barrage 900 firings narrowest escape 31 of 61 places always dodgeable
73 passed, 0 failed
And the check can say no. Otherwise the result above is vacuous. The suite fires a rank of 200 bullets across 2,000 pixels — dense enough that there is no room between two, wide enough that you cannot run round the end — and confirms it is reported inescapable 50 times out of 50. Then it punches one hole in the same wall and confirms it becomes escapable 50 out of 50. It is the gap doing the work, and the test proves that rather than assuming it.
The first version used a fixed 2.2-second window. Slow bullets fired from the top of the screen never reached the player inside it, so every one of those firings was declared safe because nothing had arrived yet. It is now derived from the slowest bullet and the distance it has to cover.
That is also why the Dreadnought's barrage — a wall with a single hole in it, placed away from where you are standing so it has to be flown to — is in the game at all. It is the one pattern that would be unfair without care, and the test is what says it is not.
Enemies were scenery that shot at you. At the first speeds a drone crossed the screen in under five seconds, and a measured bot banked 11% of a mission's value — the rest simply flew past. Speeds are roughly halved now.
That barely helped, which was the useful part. The real constraint was never speed, it was that one narrow gun cannot reach six to nine targets spread across the screen before they are gone. Wave counts are halved and bounties doubled: a mission is worth the same, but each enemy is something you can go and kill. Capture went from 11% to 18%, and the first upgrade now lands after a mission or two.
The shop ladder is tested against that measured rate, not against full capture. Pricing it as though you kill everything would mean upgrades that in practice never arrive.
Wave counts step rather than climb smoothly, so two missions running can pay the same — while the health multiplier rises every single mission. A mission can therefore be harder than the last without paying more.
The tests assert them separately: threat strictly climbs every mission, pay never falls and never stays flat for more than two. The first version asserted strict growth on the bounty total and failed, blaming the wrong number for a difficulty curve that was working perfectly well.
| Drag | the ship follows your finger |
| ← ↑ ↓ → / WASD | fly |
| — | the gun fires by itself |
| 1–5, H | buy in the hangar |
| Space | launch |
| R | new run |
The ship goes exactly where you point rather than being dragged relative to your finger, and there is no trigger — anything needing a second thumb costs you the half of the screen you most need to see. A tap far from the ship snaps it over rather than doing nothing.
Five guns and four hulls. The tests hold the table to properties rather than to numbers: each gun costs more and does more than the last, the best is more than three times the first, hulls get tougher and dearer in step, and — the one that matters — the whole ladder is reachable inside thirty missions at a realistic capture rate, with the first upgrade early and the last one earned.
Advertisement