← Projects
Personal 2026

Crystalysis

A slingshot roguelite for Android, made and shipped alone. One immortal ball defends a crystal from an endless horde, with survivors-style drafting on top of a ball the player aims and throws. Live on Google Play in thirteen languages.

Where to play

On Android today, with more platforms coming. This list is kept current: when a platform goes live, its button here goes straight to the store.

Google Play Available now
iOS / App Store Planned
PC / Steam Planned

You pull back, let go, and one immortal ball tears a hole through the horde closing in on your crystal. The ball never dies. But it slows down as it kills, and damage is speed, so a run turns into a fight to keep it moving: bounce it off the walls, catch it mid-flight to re-aim, never let it crawl.

The building is borrowed from Vampire Survivors. Between waves you draft weapons and passives that pair into evolutions. What is not borrowed is where the damage comes from. Your weapons fire on their own, but the ball is yours: you pull it back, you aim it, you let it go. Holding the aim freezes the world, but the freeze is metered, and it runs out with your thumb still down.

Underneath, one rule shaped the architecture. The aim preview and the real flight run through the same simulation function, so the game cannot lie about where the ball will go. The ball uses custom kinematic integration instead of physics. A custom world clock replaces Time.timeScale, so the interface never freezes along with the world. Everything is built from code at runtime, the visuals are drawn procedurally and the audio is synthesized, which is why the build ships almost no assets.

It carries 3,700 automated tests, thirteen languages, leaderboards, cloud save, remote config and a release pipeline that reaches Google Play in one command. Android first, more platforms on the way.

Duration In active development
Status Live on Google Play (open testing)
Year 2026
1
Team Size
13
Languages
3,700+
Automated Tests
Google Play
Platform

Overview

A slingshot roguelite for Android, made and shipped alone. You defend one crystal with a single immortal ball, drafting weapons and passives between waves the way survivors games do. The difference is that survivors games never ask you to aim: here the ball is yours to throw, and damage is speed. Live on Google Play in thirteen languages.

Challenge

Ship a live mobile game alone. No team, no publisher, no art budget. The controls had to carry a whole action game on one thumb, the difficulty had to run forever without hand-authored content, and the architecture had to survive months of me adding to it.

Discovery

I went through the survivors-like genre asking which parts its appeal actually rests on. The drafting and the build fantasy, it turns out. What is convention is the passivity: you move, and everything else happens for you. Putting a ball the player aims and throws at the centre kept what people come for and made the minute-to-minute mine instead of borrowed. Device playtests, a telemetry pipeline and a simulation bot then replaced opinion with measurement on every balance call.

Solution

One rule decided the rest: the trajectory preview and the real flight have to be the same code, so the game cannot lie about where the ball will go. From there a custom world clock turned time into a resource, an orchestrator generated pressure from a threat budget instead of authored waves, and a strict module pattern gave every weapon and passive its own data and behaviour.

Implementation

Unity 6 with URP's 2D renderer and UI Toolkit. The ball runs on custom kinematic integration rather than physics, which makes it deterministic and testable. The scene is built from code at runtime, the visuals are drawn procedurally and the audio is synthesized, so the build stays tiny. Unity Gaming Services covers leaderboards, cloud save and remote config. The release pipeline is scripted end to end, from batchmode tests through IL2CPP to a published Google Play track.

Results

On Google Play, playable worldwide in thirteen languages, with an open test running and feedback coming in from players who owe me nothing. Every report is tracked in an audited ledger with its real root cause and how it was closed. 3,700 automated tests, one person maintaining all of it.

Development Workflow

Crystalysis doubles as an experiment in solo development with AI, and the interesting part is not the assistant. It is the scaffolding around it. I build the game with Claude Code against a written contract that lives in the repository and holds the architecture rules, so the assistant works under the same constraints I do. Project state lives in one canonical document instead of being rebuilt from memory each session. Player feedback goes into an audited ledger, and closing an entry there takes the commit hash, the real root cause, and a note on what the fix does not cover. That last field exists because the reported cause is often not the real one. What keeps it honest is automated. Content documentation is generated by running the game's own functions, so an inventory of weapons or economy numbers cannot quietly rot. A hygiene linter runs on a pre-commit hook. A knowledge base invalidates its own pages from Git history when their dependencies move, so a page cannot claim to be current just because nobody checked. Guard tests break the build when new content is registered wrong. The Unity Editor itself is driven over MCP for asset edits, test runs and console reads. To be exact about what that means: the code is AI-assisted and the localization is machine translated. There is no generative AI art or audio anywhere in the game. The visuals are drawn in code and the audio is synthesized at runtime.

Challenges

  • •A ball the player aims and throws is far less forgiving than the movement-only control the survivors genre leans on, and here it carries the whole game on one thumb
  • •Difficulty that can run forever, with real rhythm, without hand-authoring waves or hitting a wall of repetition
  • •Staying able to add content for months, alone, without the architecture caving in

Solutions

  • •The preview and the real flight share one simulation function, so the path you see is the path you get, with several aiming schemes on top
  • •An orchestrator fills a rising threat budget with a procedural composer, plus a rhythm layer and an adaptive pacer so pressure breathes instead of climbing flat
  • •Every weapon, passive and evolution owns its data and behaviour. Adding one is a new asset and a new class, with nothing touched in shared code, and 3,700 tests behind it
Tech Unity 6C#URP 2DUI ToolkitProcedural AudioDeterministic SimulationTelemetry & Analytics
Platform AndroidGoogle Play
Role Solo DeveloperGame DesignerTechnical Director