Gear Train

Q8FMADE BY Qwen3.8-Flash-Next

Clockmaker's bench: place brass gears between a driven barrel and a clock-hand arbor so the train produces one exact ratio. Meshing demands the right tooth counts and alternates direction, and the hand lands a few degrees off if your fraction is wrong.

▸ CARTRIDGE SLOT · GEAR TRAIN
↗

* THE GAME RUNS IN A SANDBOXED FRAME — IT CAN’T SEE THIS SITE OR YOUR OTHER TABS. BEST SCORES STAY IN THIS BROWSER.

Cartridge promptTHE EXACT PROMPT THAT BUILT THIS GAME
Build a tiny browser game called "Gear Train".

Game spec
---------
A clockmaker's bench where you build the gear train by hand. The bench holds a driven barrel gear, an output arbor carrying a clock hand, and a rack of loose brass gears with different tooth counts. Drag a gear onto an empty arbors slot (or use the arrows plus Enter to place and rotate a selection), and any two adjacent gears must mesh: meshing is only possible when the centre distance and tooth counts allow it, and meshed gears turn in opposite directions at a ratio set by their teeth. The target is printed on a card: the output hand must point at a given hour, which means the whole train has to produce an exact overall ratio from barrel to hand — build it wrong and the hand lands a few degrees off and the clock fails inspection. A live readout shows the achieved ratio as a fraction and the hand's angle, so the arithmetic is inspectable rather than guessed, and the direction of every gear is drawn with a curved arrow. Press TEST (Space) to run the train: it turns, the hand sweeps, and inspection scores by ratio exactness, gear count used and time taken; the next movement demands a harder ratio and gives fewer usable gears. A wrong tooth count grinds and costs a tolerance. Three tries on easy, one on hard. Horologist look: green baize bench, oiled brass gears with cut teeth and spoke lightening holes, a jewelled bearing glow, blued screws, and a tick-tock escapement sound in WebAudio.

Hard constraints — the game will be embedded in a sandboxed iframe on a static gallery site, and a headless browser will screenshot it:

1. Output exactly ONE self-contained HTML file. All CSS and JS inline. Zero external requests: no CDNs, no external fonts, images, or sounds, no fetch/XHR/WebSocket. Any sound must be synthesized with WebAudio.
2. The iframe sandbox is "allow-scripts allow-pointer-lock" (plus an autoplay permission). So: no localStorage, cookies, or indexedDB (opaque origin — access throws); no popups, window.open, or navigation; no access to the parent page; alert()/prompt()/confirm() are silently blocked.
3. The playfield must be visible within 800 ms of load — that is when the screenshot is taken. No dead white screen. If there is a start screen, make it visually rich.
4. Controls: keyboard AND mouse must both work, plus on-screen touch buttons for phones. Call preventDefault() on game keys (arrows, space) so the page never scrolls.
5. The view is 16:9 and must scale to fill the viewport with no overflow or scrollbars.
6. Show a visible score. If the genre has a losing state, show a game-over screen with a restart (button and a key). Idle/clicker games skip game over but still need clear numeric feedback.
7. If you track a score, report it to the arcade shell so the player's best is remembered between visits: on every score change, call parent.postMessage({ source: "ai-arcade", type: "score", score: <number> }, "*"). It is safe to call it no matter what the parent does with it.
8. Keep it tiny: aim for under 400 lines, 60 fps, no frameworks. That 400-line target does not apply to 3D games — true 3D (a camera and perspective-projected world) or pseudo-3D (projected road/track, depth-sorted sprites) — which need their own software renderer and typically land at 800–1400 lines. The rest of this constraint still binds every game: 60 fps, no frameworks, no external assets, and no padding to reach a length.
9. Difficulty: the arcade shell passes the player's chosen difficulty as a URL query parameter. Read it with new URLSearchParams(location.search).get("difficulty") — the value is "easy", "medium", or "hard" (missing or unknown means "medium"). Make the three levels meaningfully different — speed, lives, enemy pressure, reaction time, whatever fits the genre; clicker/idle games with no losing state use starting resources and upgrade cost curves instead. Show the active level in the HUD. Without the parameter the game must be fully playable at its default (medium) tuning.

Return only the complete HTML file, no commentary.