Elegant Pirate Visuals + Browser Game Art Direction

All three browser-playable games got an art-direction pass: elegant ship paddles, a treasure-barge longboat, fortress-styled bricks, and automated testing to protect them. Here's what was done and what still needs work.

What Shipped

This pass replaces every generic rectangle in the browser games with hand-drawn Pygame visuals — no image assets, just procedural geometry driven by the existing collision rectangles.

Cannonball Clash (Pong) — Pirate Ship Paddles

Both paddles are now elegant side-profile pirate ships drawn with layered polygons:

Treasure Cove (Breakout) — Longboat Paddle

The breakout paddle is an elegant horizontal longboat (skiff/barge):

Treasure Cove — Fortress Stone Bricks

The breakout bricks were rainbow-colored rectangles. They are now fortress-style stone blocks:

Kraken’s Wake (Asteroids) — Nebula Background + Polish

The Kraken’s Wake ship was already a layered polygon sprite (hull, deck, mast, sails, flame effect). Colors were already cohesive with the pirate palette. This pass adds:

The enemy barrels (formerly “asteroids”) already had a detailed wooden barrel appearance with bands, cross-bracing, and varied wood tones — no changes needed there.

Design Decisions

Why Procedural Drawing Instead of Image Assets

Why side='left' / side='right' Parameter

The original Paddle class had no faction identity. Adding the side parameter lets the constructor build a mirror-image ship with different accent colors:

The _build_surfs method caches the ship surface per instance, so the faction identity is set once at construction and never changes.

Why Teal for Player, Rum-Red for AI

The existing CSS design tokens define --sea (teal) and --rum (red) as accent colors. The Python constants use PIRATE_TEAL and PIRATE_RED which map to the same hue families. Using the same color families in-game creates visual cohesion between the site theme and game visuals.

Known Gaps

Collision Rectangle vs Visual Size

The ship visuals extend ~40px wider than the collision rectangle (16px wide). This means:

On mobile in landscape, the visual overhang is less noticeable because the canvas is scaled down.

No Kraken Tentacle Visual

Kraken’s Wake now has a nebula backdrop, but:

This is acceptable because the game’s visual identity is “space pirates” — the abstract barrel enemies work within that theme.

Fortress Bricks Replace Rainbow Color Coding

The original breakout bricks used rainbow colors that served as a visual row indicator. The new stone palette preserves distinct row hues (dark stone → weathered brick → terracotta → sandstone → limestone → mossy → sea-weathered → pale treasure vault), but:

No In-Game Visual Toggle

There is no option to revert to the original rectangle visuals. Players who preferred the minimal look cannot switch back. Adding a visual toggle would require:

This is tracked as a possible future enhancement but was out of scope for this pass.

Test Coverage

A new Playwright test (tests/game-theming.spec.ts) protects the visuals:

The manual visual smoke checklist in tests/TESTING_CHECKLIST.md also got a new section:

- [ ] Cannonball Clash: player paddle (left) reads as a ship, not a rectangle
- [ ] Cannonball Clash: AI paddle (right) has distinct red/rum accent
- [ ] Cannonball Clash: power-up state adds gold glow
- [ ] Treasure Cove: longboat paddle reads as a skiff/barge, not a rectangle
- [ ] Treasure Cove: treasure cargo crate is visible amidships
- [ ] Treasure Cove: bricks have stone bevel appearance, not plain rectangles
- [ ] Treasure Cove: bricks show row-specific stone palette
- [ ] Kraken's Wake: ship has layered polygon sprite, sails, and flame effect
- [ ] Ball collision still feels aligned with visual paddle (no misleading wide hitbox)
- [ ] Mobile landscape: ship/longboat still readable at reduced scale
- [ ] prefers-reduced-motion respected (no unnecessary animation)

Files Changed

File Change
scripts/pygbag-port/cannonball-clash/games/pong/paddle.py Elegant side-profile ship with side param, hull, cannon ports, teal/rum accent
scripts/pygbag-port/cannonball-clash/games/pong/gameplay.py Updated Paddle constructors to pass side='left'/side='right'
scripts/pygbag-port/treasure-cove/games/breakout/paddle.py Elegant longboat with treasure crate, crow’s nest, lantern, oars
scripts/pygbag-port/treasure-cove/games/breakout/brick.py Stone bevel fortress bricks with 8-row stone palette + row accent markers
scripts/pygbag-port/krakens-wake/games/asteroids/gameplay.py Nebula backdrop + twinkling starfield
tests/game-theming.spec.ts Visual smoke checks for all 3 games
scripts/check-game-theming.mjs Source-marker checks for all 3 games (Node.js)
tests/TESTING_CHECKLIST.md Visual/art direction smoke checklist added
ROADMAP.md Visual polish items marked complete
src/data/publicDomainArt.ts Howard Pyle public domain art manifest
public/images/art/*.webp 4 Pyle illustrations (optimized WebP)
src/components/Hero.astro Optional decorative background image support
src/components/Footer.astro PD art attribution
src/styles/components.css Hero/section art styles
src/pages/index.astro Hero background + experiment section art