Deep Sea Bomber

A calm bedtime arcade game set in a glowing ocean trench

Status
In progressFeature-complete. A v1.0.1 release bundle was built for a first Google Play upload in July 2026; no public store listing yet.
Platforms
Android, iOS
Role
Solo: game design, code, art direction, audio, store assets
Timeline
Jun 2026 – Jul 202636 commits
Version
1.0.1 (build 2), prepared for Google Play

01 The story

A low-stress Flutter game for iOS and Android: steer a small submarine with single taps and drop slow-sinking depth charges on rigs and crab harvesters below. I made it as a late-night wind-down toy, with a dark bedtime palette, no harsh flashes, a 12-stage campaign and 27 hulls.

Deep Sea Bomber started with a question: what would a classic arcade bomber, in the spirit of Atomic Bomber, feel like if it were designed to help you wind down instead of wind up? The answer is a slow, forgiving underwater game. The sub glides on its own, you tap to change its heading, and depth charges sink gently onto targets on the seabed.

The design rules are strict. Colors stay in deep abyssal blues with soft cyan and seafoam accents, pure-white pixels are kept to a tiny share of the screen, and nothing flashes or explodes. Dying dissolves the sub into a ring of dark bubbles and dims the screen. You get four lives, a grace period on entry, dodgeable torpedoes, and hazards that arrive late and sparse. Around that sit a 12-stage campaign through six biomes, a final 'Vent Guardian' you soothe rather than kill, an endless mode and a hangar of 27 hulls.

There's no game engine. Everything is drawn with Flutter's CustomPainter. Every creature and prop is a sprite paired with a depth map, and a GLSL fragment shader turns each pair into live 2.5D: relief lighting plus parallax that makes crabs and rigs seem to turn toward the passing sub. Lit frames are cached per quantized light and parallax angle, so only nearby sprites re-bake each frame. Sound effects are synthesized as raw PCM at runtime, so no SFX files ship.

The art is generated: the sprites and depth maps with Gemini's image model, and the three music tracks with Google's Lyria. The game is feature-complete with a passing test suite and CI. I built version 1.0.1 as a signed Android App Bundle for a first Google Play upload in July 2026, along with designed store screenshots and a feature graphic. There's no public store listing yet.

02 What it does

  1. 01

    Tap-to-vector steering: one tap sets a new glide heading, or hold and drag to steer continuously

  2. 02

    Slow-sinking depth charges that inherit the sub's speed, with a seabed reticle showing where a drop would land

  3. 03

    12-stage campaign on a descending world map across six biomes (shelf, kelp, wreck, rigs, mooring, black smoker), plus an endless mode

  4. 04

    A final-stage 'Vent Guardian' leviathan that you calm with six hits instead of destroying

  5. 05

    Hangar of 27 hulls with small handling differences (glide speed, reload, spare charges), and 15 paint liveries

  6. 06

    Rigs that fire bubble torpedoes, walking crab harvesters, drift mines, anglerfish, thermal geysers, currents and relics to carry up

  7. 07

    Bedtime presentation: dark palette, no bright flashes, soft death animation, gentle haptics, separate sound and music controls

03 How it's built

AppFlutter app (menu, campaign, hangar)
AppGame engine (simulation)
DataLocal settings / progress
ModelAsset tools: sprites, depth maps, music
AppCustomPainter renderer
AppRuntime PCM synth + music
Apprelief.frag depth shader

A fully offline, single-device game with no backend. Art (Gemini) and music (Lyria) are generated ahead of time, processed by Python tools and bundled as assets. At runtime the engine simulates, a CustomPainter draws, and a fragment shader lights each sprite from its depth map.

All 6 connections, as text
  • Flutter app (menu, campaign, hangar) → Game engine (simulation): starts runs, hull stats
  • Game engine (simulation) → CustomPainter renderer: world state each frame
  • CustomPainter renderer → relief.frag depth shader: sprite + depth map
  • Game engine (simulation) → Runtime PCM synth + music: SFX events
  • Flutter app (menu, campaign, hangar) → Local settings / progress: save progress
  • Asset tools: sprites, depth maps, music → CustomPainter renderer: bundled PNG assets

04 Engineering notes

  • 2.5D pipeline: each sprite has a matching depth map; a GLSL fragment shader (relief.frag) contrast-stretches the depth, derives surface normals for lighting, and aims parallax at the sub so props seem to turn toward it

  • Lit sprite frames are baked offscreen and cached per quantized light and parallax angle, so only nearby sprites re-bake each frame

  • No game framework: the renderer and simulation are hand-written Dart (CustomPainter), with a depth-sorted parallax camera and toroidal left-right screen wrap

  • Sound effects (sub drone, release thump, hit ping, boom) are synthesized as raw PCM at runtime and written to temp WAVs for gapless looping. No SFX files ship

  • Performance pass: per-sprite saveLayer calls replaced by opacity in the paint color, a full-screen blur's bounds tightened, and a frame-time benchmark test against a 16.67 ms budget

  • Flutter tests (campaign, hulls, ammo, audio synthesis, sprite loading) run in GitHub Actions on every push; test scripts also render preview frames and build the app icon from the game's art

05 By the numbers

12
Campaign stages
27
Submarine hulls
15
Paint liveries
110 PNGs
Generated art files (sprites + depth maps)
93 MB
Signed Android App Bundle, v1.0.1

06 Stack

App

  • Flutter
  • Dart
  • CustomPainter
  • GLSL fragment shader (FragmentProgram)

Data

  • shared_preferences (settings, best run, unlocks)

Infrastructure

  • GitHub Actions CI (flutter analyze + flutter test)

Tooling

  • audioplayers
  • path_provider
  • flutter_launcher_icons
  • Python asset tools (Pillow, NumPy)
  • Gemini image model for sprites and depth maps
  • Google Lyria for music

Lines of code (approx.)

  • Dart14,213
  • Python1,223
  • GLSL143

≈ 15,579 lines

Repositories

  • deep_sea_bomberprivate

Git history starts 2026-06-30, when I turned the existing project into a repo. The Flutter project files on the SSD copy are dated 2026-06-22. All 36 commits fall between June 30 and July 6, 2026.