Side project

Games

Game development is my hobby — evenings and weekends, not my job. My day job is senior fullstack engineering at Google; see the resume for that. What the two have in common is how they get built: a pure, deterministic rules core with no platform dependencies, a thin rendering layer over it, and a headless test suite that plays the game so I don't have to verify it by hand. Five titles in development across two stacks. Every screenshot is a real frame from the running build.

01

Grimoire

Clear the spellbook before the candle dies.

A fast fantasy solitaire built on the TriPeaks/Golf pattern and wrapped in an arcade run. A candle burns down continuously from the moment the board deals. Chains build a multiplier, and clearing a spread buys back enough wax to keep going — so the game is a race you extend by playing well rather than a timer you simply lose to.

  • One verb. Tap a card. Play an exposed card one rank above or below the page card and the chain advances; draw from the stock and the chain resets and costs you wax. Ace wraps both ways (K→A→2).
  • Chains are the game. Every link is worth more points and a little more wax. At chain 5 you earn an Arcana — a wildcard that plays on anything, and the only way to rescue a chain about to die.
  • The tutorial is the real run. Four prompts coach you over the actual first game rather than a scripted fake board, so there is no second set of rules to keep in sync and the first board you clear is one you really cleared. The candle is held for the first two steps — a player who hasn't made a move yet can't be put on a clock — and live for the last two, because the cost of a draw is the lesson.
  • No unwinnable deals. Every board opens on a page card that some exposed card already answers; a timed run can't afford an opening whose only move is a draw. The test suite walks 25 consecutive boards across 20 seeds and asserts a legal play exists on every one.
Stack
TypeScript, HTML5 Canvas, Capacitor (Android + iOS)
Role
Sole developer — design, engine, art direction, release
Status
Playable build; store assets and icons prepared
Source
github.com/Sethvg/grimiore
Privacy
Privacy policy
02

Comet Caddy

Sink the comet, mind the gravity.

Pull back, let fly, and curve your shot around planets into the goal ring. The whole game lives in one moment that lands inside your first three shots: you aim wide on purpose, gravity catches the comet, and the curve carries it in. Everything the campaign adds afterwards — repulsors, moving gates, wormholes, bumpers — is a new answer to that same question.

  • Honest physics you can read. A planet's mass is radius² × skin density, so both size and surface tell you how hard it pulls: gas 1.7, molten 1.2, rock 1.0, ice 0.55. The drawn field ring tracks mass rather than size, so a gas giant visibly hauls about three times as hard as an ice body the same width.
  • A toolkit of hazards. Voids repel, black holes pull hard and swallow, asteroids exist purely to be dodged, and bumpers are perfectly elastic — the one surface you're allowed to aim at. Moving bodies are a pure function of a level clock that keeps running while you aim, so when you release is part of the shot.
  • 200 holes across ten worlds. Thirty-five are hand-authored; the rest are generated, then flown and difficulty-rated by the game's own solver. A level only ships once the simulation has actually completed it and measured the aim window that sets its par.
  • Boost that can't replace aim. One charge per shot adds a fixed 70 u/s along the current heading — enough to stretch a shot falling just short, never enough to substitute for aiming.
Stack
TypeScript, HTML5 Canvas, Capacitor (Android + iOS)
Role
Sole developer — physics, level generation, solver, art direction
Status
Playable build; full 200-level campaign generated and rated
Notable
Automated level pipeline: generate → prove solvable → derive par → assign difficulty tier
Privacy
Privacy policy
03

Alley Loop

A stray cat, a nightly patrol, and nine lives to spend.

A cat-themed Loop Hero-like for Android and iOS. The cat walks and fights on its own; your decisions are all about the world it walks through. You place world-building cards that raise reward and risk together, watch the lives drain, and choose the moment to retreat to camp and bank the haul — because a run that ends at zero lives banks nothing. Between runs you rebuild the Colony to unlock new cards and classes.

  • Fully deterministic simulation. The core advances in fixed 100 ms steps and every mutation goes through a single funnel. A run is defined by its seed plus a timestamped action trace, which means the same inputs always reproduce the same result — replays and mid-run saves are the same mechanism.
  • Portable by construction. The rules module has zero Android, Compose or platform imports, so identical game code runs on Android, iOS and a JVM test harness. Rendering is a single Compose Canvas screen.
  • Generated loops that are always valid. Each night's track is a single closed ring of 42–60 tiles with the camp on it, verified so that every ring tile has exactly two ring neighbours — no dead ends, no forks.
  • All tuning in one place. Every balance constant lives in a single file with no magic numbers in the systems, so difficulty can be swept and re-tuned by a headless bot rather than by replaying the game by hand.
Stack
Kotlin Multiplatform, Compose Multiplatform, Gradle, AdMob
Role
Sole developer — design, simulation, rendering, art pipeline
Status
Android build running on device; iOS shell in place, shared core complete
Art
Custom pixel-art pipeline — generated, staged and wired through a sprite registry
Also

In development

Future Conflicts

Turn-based tactics

Grid battles in the spirit of Advance Wars — movement ranges, unit counters, and artillery that can't move and fire in the same turn. The rules are pure Kotlin with no Compose or platform imports, so they're portable and unit-testable; rendering and touch live in a single Canvas screen.

Kotlin Multiplatform Compose Source

Stroads

Traffic / routing puzzle

A Mini Motorways-style network builder: you draw roads and cars route themselves from houses to destinations along the shortest connected path, using an A* pathfinder over the live road graph. Same architecture — pure simulation module, Compose rendering on top.

Kotlin Multiplatform A* pathfinding Source