Porting the Second Game — Treasure Cove via Pygbag
Treasure Cove (Breakout) is now playable in the browser. The second port took a fraction of the first — most of the infrastructure was already in place.
What Shipped
Play Treasure Cove in your browser.
The second browser port is live. Treasure Cove runs at 1600×900, 60 FPS, with the same logic, paddle physics, brick grid, ball trail effects, and procedural audio as the desktop version.
The game code bundle is 11.6 KB (vs Cannonball’s 15 KB — fewer game modules). The CPython WebAssembly runtime (~12 MB) is already cached from Cannonball on repeat visits.
What It Took
The second port reused the entire pipeline from Cannonball:
-
index.html— Copied Cannonball’s file, changed the game name, archive URL, and controls hint. Thecross_filemonkey-patch, boot script,WebAudioclass injection, DOM elements, and CSS stayed identical. -
audio-bridge.js— Added two new sounds to match desktopaudio.py:brick_break: dual sine at 600+900 Hz (0.12 s)life_lost: dual sine at 200+150 Hz (0.3 s) The existingpaddle_hit,wall_hit, andlevel_win(=victorychord) sounds were reused verbatim.
-
game.py(the port) — The desktopBreakoutGame.run()method needed the same treatment as Cannonball’sPongGame.run():async defwithawait asyncio.sleep(0)for cooperative multitasking- Fixed
dt = 1/60instead ofclock.tick(c.FPS) / 1000.0 - No fullscreen toggle, no mouse click pause in the event loop
- All keyboard handling kept intact (pause menu, FPS toggle, sound toggle, restart, quit)
-
Shared modules —
constants.py,audio.py(stub),highscores.py(stub), andrenderer.pywere copied from the Cannonball port without changes. All four are identical between the two browser games. -
Game source —
gameplay.py,ball.py,paddle.py, andbrick.pywere copied from the desktop source verbatim. Zero changes needed — nogfxdraw, no file I/O, no platform-specific code.
File Count
The Treasure Cove port consists of 7 Python source files:
| File | Lines | Notes |
|---|---|---|
game.py |
249 | Ported from desktop (async run loop) |
gameplay.py |
209 | Copied verbatim from desktop |
ball.py |
78 | Copied verbatim from desktop |
paddle.py |
43 | Copied verbatim from desktop |
brick.py |
50 | Copied verbatim from desktop |
main.py |
55 | New WASM entry point |
audio-bridge.js |
109 | Extended from Cannonball (2 new sounds) |
What Validates the Approach
The second port took roughly 30 minutes of engineering time. The heavy lifting —
cross_file patching, Python boot injection via blocks[0], pip_install("pygame")
in WASM, display.set_mode() ordering, the WebAudio bridge class — was already
solved and documented in the first shipping post.
Two data points do not make a pattern, but the effort delta between port one and port two suggests the remaining two games (Kraken’s Wake, Port Royale Tycoon) will also be straightforward ports.