Snek Snacks
Classic snake, re-engineered — a frame-perfect arcade core wrapped in a 90-card collection gacha.
Overview
Snek Snacks reimagines the arcade classic with a modern engine and a collection meta. The core is a framerate-independent fixed-timestep simulation hardened against app-backgrounding: the snake body is an O(1) set-backed structure with a correct tail-chase collision waiver (the edge case most clones get wrong), growth is modeled as debt so power-ups extend you gradually, and the board expands rightward without remapping a single coordinate.
On top sits an 18-stage, 90-card gacha that awards a weighted-random card per qualifying run and unlocks cosmetic snake colors as stages clear — with the entire unlock schedule regenerated deterministically from a single persisted seed. Monetization is a mature AdMob layer, telemetry runs on Firebase Analytics, and every card, sprite, app icon, and chiptune track is generated by a standalone Python pipeline.
Full stack
- Flutter · Dart 3 · Flame 1.37 (FlameGame, components, overlays)
- flutter_soloud (BGM + SFX mixer, real-time pitch sync)
- google_mobile_ads (banner · interstitial · rewarded)
- Firebase Core + Analytics (GA4 funnel events)
- games_services (iOS Game Center leaderboard)
- shared_preferences (high score · gacha state · settings)
- dart:ui Canvas procedural pixel-art rasterization
- Python 3 · Pillow · numpy · ffmpeg (offline asset generation)
Engineering highlights
The parts a code review would find interesting.
01A snake engine that's actually correct
The body is a ListQueue for ordered traversal plus a parallel Set for O(1) collision membership, kept in sync at every move. A single "will the tail move this tick" boolean drives both tail removal and the collision waiver, so chasing your own retreating tail is correctly safe — the classic snake bug, eliminated and unit-tested.
02Frame-perfect and backgrounding-proof
A fixed-timestep accumulator decouples simulation from render framerate, every time-accumulating clock is dt-clamped, and the lifecycle auto-pauses a running game — so returning from the background never teleports the snake into a wall. A whole bug class designed away.
03Seed-only gacha persistence
The full color-unlock schedule across all 18 stages is never stored; it is regenerated deterministically from a single integer seed via a constraint-satisfying permutation generator (no color repeats within a category, distinct per stage, with restart fallback) — an elegant space and migration win.
04Live-ops monetization done right
AdMob banner, interstitial, and rewarded video with mature UX idioms: rewards fire only after the ad is dismissed (never under it), and a suppression window prevents jarring back-to-back ads while still surfacing the owed interstitial. Frequency capping survives app restarts.
05Audio that tracks difficulty
BGM playback rate is synced to game speed every tick via SoLoud's setRelativePlaySpeed (with a dead-band to skip redundant native calls), so the chiptune pitch rises smoothly as the snake accelerates — plus voice protection so SFX floods can't evict the music track.
06Procedurally generated everything
A standalone Python pipeline synthesizes all 90 cards from a composable pixel-creature engine, the app icon, sprites, and seamless-looping NES-APU chiptune BGM and SFX. The build never touches Python — only the baked assets ship.