Lionel: "imagine if there is a fighter jet on the left side of the sheet music and it's flying towards the right ... instead of the player having to wait for the C note to come to the playline to play, the player can just spam C 8 times which then hits the first 8 C quarter notes in succession. located under each C quarter note is a little enemy monster or soldier that's actively trying to shoot the plane ... the key is to have players learn the piano from a molecular level, starting with single note, then double notes, then note runs like CDE."
And the same day, on firing early: "the piano plane has a kill range (like maybe at a 45 degree angle right under it) that is the sweet spot. beyond that, the bullets or missles hit less hard ... your gun doesn't freeze when you hit the wrong note, but you waste a bullet. you start off with 10 bullets and every measure that passes you get a set num of bullets."
And an hour later, with the lab in front of him: "let's go with the piano fighter version (vienna world). unused bullets become coins that get added to your score (maybe not 1:1 ratio). also on the sheet music we should see the same ranges (aka within range / hit zone) ... i can't help but wonder if an isometric sheet music scroller on the ground is possible ... just mock this up and let's take a quick look before deciding whether to proceed or not." The first three are on this page; the mock became two tilted sheets, which are in the gallery.
And having looked at both tilts: "we don't need the tilt. try another version like this. the sheet music is on the ground in the large size that it is now. increase the space between the notes on the horizontal axis ... put the soldier on the RIGHT of the note. so that way a big chord can have 4 soldiers to the right of each note. the note lights up when pressed, but the bullets are aimed towards the soldier standing behind ... no more separation between staves ... the soldiers are 2.5d while the sheet music is 2d."
And having flown that: "definitely this flat sheet view is the one we should implement for now ... we can decrease the overall size of the staff as right now it's definitely more than big enough ... we can have 2 rows - the plane can hit the rows on the top, but the row on the bottom is basically the upcoming measures beyond the first row's measures, but this gives the user an idea of what's coming next without having to extend the side view canvas horizontally. (and it can be somethin glike the soldiers go into a tunnel for the 2nd row and then appear on the 1st row). with this we can have a range upgrade that hits the second row too (but with less damage & higher chance of miss)." That is the bench now.
The plane has six parts (gun, sight, reach, magazine, hull, grenades) and each is bought once and kept. A mission that shoots you down still pays, so the next flight is in a stronger plane whether or not the hands got better. The hands get better anyway: every bullet is a note read off the page and found on the keys.
This is the bench; the game is piano-attack.html (🛩 PIANO ATTACK on the menu): a hundred missions built from the partials, lives, gold, gems and bosses. The bench flies the lab's fourteen missions and the game's hundred (the list under Missions) under the game's rules, every one of them on a slider.
Try it. Pick 🤖 ace, 🤖 eager and 🤖 sloppy under the stage to watch three ways of flying the same mission. To fly it yourself, a MIDI keyboard plays it, and so do the letters printed on the keys under the stage. Space takes off and pauses, R starts over.
What is real: the sheet is the game's own engraver, the sound is the game's piano, the rules are one file the tests run. What is the lab's: the coins and the hangar live in this browser only, and every number in the right-hand panel is a guess to be flown.
Six parts, five marks each. A part is bought once and kept, and coins are paid even for a flight that was shot down.
A slider changes the flight in the air, from the next bullet. The plane's own five follow the hangar unless you override it.
You took the flat sheet, and asked for three things on it: a smaller staff, a second row under the plane's own that shows "the upcoming measures beyond the first row's measures", with the soldiers going "into a tunnel for the 2nd row" and coming out on the first, and a range upgrade "that hits the second row too (but with less damage & higher chance of miss)". All three are on the bench. The two rows are one strip of music: what leaves the second row at its left end comes out at the right end of the plane's row.









To try a long shot yourself: Hangar, +500 coins, buy Reach, then fly Scale Storm and play an F sharp during the first bar.
A run is not widened by making everything larger. The engraver spaces notes by their length and then keeps anything from touching anything else, with a margin. The lab sets that margin as wide as it goes: a staff space to the right of every note and a staff space to the left of whatever comes next, a note, its sharp or a rest. So an eighth, a sixteenth and a thirty-second each get a notehead and a soldier's room, and a long note keeps its ordinary width.
The two meet in one place. The margin stops at two staff spaces, so the room a soldier can be given shrinks with the staff, and the soldier with it: full size on a staff of 26 px and up, two thirds down to 13 px. That is why the medium staff has the smaller soldier.
What came before this is in the gallery: the first flat sheet, the tilt straight back, and the first tilt and the isometric view.
Picked, 2026-10-01: "let's go with the piano fighter version (vienna world)". A clavichord biplane, a walnut fortepiano fighter and a black concert grand jet, the keyboard as the nose in all three; wind-up tin soldiers, a drummer behind his drum and a tuba cannon; Vienna's skyline at golden hour. The jet world it was drawn against is kept in the gallery.


An image model does not draw on a grid. What comes back looks like pixel art and is not: the soldiers were drawn on cells of 11 to 12 pixels, the tuba cannon and the grand on 7. Side by side they would read as different games. tools/attack_art.py build puts every sprite on one grid, twice.

The palette is cut at full size (20 colours a sprite), then each art pixel takes the commonest colour of the block it covers. Averaging the block was tried beside it and is muddier: a red coat and a white strap average to pink, where the vote keeps one of them. Alpha is a vote too, so an edge is on or off.
Frames. Each is one drawing, moved by code: the plane bobs and kicks, a soldier flashes when hit, an explosion is drawn in squares. Codex does not hold a sprite steady across frames (the walking pianos' idle frames varied 4.5 to 7.6% in size on Codex, against 0.6 to 2.9% on gpt-image-2), so a walk or a firing cycle is the next round's question, not this one's.
Canvas 2D, inside the game. A screen of this is under two hundred sprites, and any of the engines below draws that without effort, so drawing speed decides nothing. What decides it is that the mode sits on four things the game already has and an outside engine would have to rebuild or reach across a bridge for: the engraved sheet, the MIDI input, the piano, and the account.
| Engine | What it would give | What it would cost here | Verdict |
|---|---|---|---|
| Canvas 2D the browser's own, as this lab | Sprites at whole-number scale with smoothing off. Shares the page with the engraved sheet, so a soldier is drawn at its notehead's own x. | No shaders. A CRT filter or ten thousand particles would want more. | Use it. |
| PixiJS a 2D renderer on WebGL or WebGPU | Batched sprites, filters, palette swaps, the same code on a Canvas fallback. A renderer only: it does not want the loop, the input or the sound. | A library to vendor and a GPU context beside the sheet's layers. | The step up, if the look ever asks for shaders. The rules do not change: they never touch the screen. |
| Phaser a whole 2D game framework | Scenes, physics, tilemaps, its own input, loader and audio. | It expects to own the loop, the input and the sound, and the game owns all three. Nothing here collides or tiles. | No. |
| three.js / Babylon both already vendored | A camera and lights. A plane that banks in 3D, a ground that tilts. | For flat sprites it is more code than Canvas 2D for the same picture, and pixel snapping is by hand. | Not for 2D. Keep it for the hands. |
| Godot 4.x, exported to the web | The best 2D tools of the list, and it does export: single-threaded since 4.3, WebGL 2, Web MIDI in every browser but Safari. | A second program in the page: about 40 MB of WebAssembly, 5 MB compressed (Godot's own figure for 4.3), a build step in a repo that has none, and the sheet, the judge, the piano and the wallet either rebuilt inside it or called across a JavaScript bridge every frame. | Only if Piano Attack becomes its own download, the way Atlantis was weighed. |
| Unreal | Nothing a 16-bit side-scroller uses. | No browser export: found on 2026-09-17, and streaming was ruled out on cost. | No. |
| Blender | Not an engine. A sprite factory: one model of the piano fighter rendered in every bank and turn, then cut to the grid, so every frame agrees. | A model to build. | Later, for animation frames Codex cannot hold steady. |
Each of these is a switch on the bench, set to my reading of what you said. Fly both sides before deciding.
Two rows or one, and which of the three staff sizes. Both are switches under Picture, and the gallery round has them side by side.
A quarter of the second row for each mark of Reach, half the strength, three misses in ten. The last two are sliders under Rules. As they stand, the second row is somewhere to spend spare bullets, not a way through a mission.
Half a coin, rounded down, paid only to a plane that comes home. A clean first mission brings its ten bullets back: 5 coins on top of 67. A Mk V magazine brings thirty.
Sweet spot is your second telling: whole for two beats ahead, then half at every four. By bar is your example read to the letter: this bar 100%, the next 50%, the one after 33%. Set the sweet spot as long as the reach and you have your first telling, where every bullet kills.
"Every measure that passes" could be the bar behind or the bar ahead. Entering a bar is the default, because a dense bar after a quiet one otherwise opens with too few. A bar is worth a bullet for every hit it needs, so a shielded bar pays double.
Fingering (you said to leave it). Held notes: a half note is one bullet, like a quarter. Animation frames. The wallet: the coins here are the lab's. A mission from a real piece, though Excalibur's phrases are cut and waiting.