Skip to content
AsumaCodes
Menu

Creature Clash

A creature-duelling game for phones: six species, secret picks and gym battles, all decided by one TypeScript engine.

A duel in the Creature Clash design prototype: Ashkit against Brookfin, three exchanges, each side's choice revealed, then Victory.
The Claude Design prototype, played through: Ashkit against Brookfin, Special, Attack, Speed. The project's README lists the same line as a check that has to win.

A duelling game for phones. Each creature has 2 HP and four categories, Attack, Defense, Speed and Special, each used once. Both players pick in secret within ten seconds, the picks are revealed together, and the lower value after type costs 1 HP. Three exchanges, and a fourth if it's still level.

Gym battles raise the stakes: lock three of your six in private, deploy one in secret before each of three duels, and the winner may trade one of its creatures for one of the loser's. Wins earn XP, and levels buy training points.

Status
Built
Runs on
Android, as a development build. iOS not verified yet; not in a store.
Built
7 to 25 September 2026
Stack
Expo SDK 57, React Native 0.86, TypeScript, Skia, NativeWind
Design
Claude Design, rebuilt as native screens
Role
Product, game modes, interaction, design and engineering. Built with GPT Astra 6.

Six species, three moods each

Every creature is built from the same parts: a few faceted shapes, one ink weight, light from the top left and a three-part face. The brow does most of the acting.
6 species, as defined in the app's fixtures
The six species from the Creature Clash design: Ashkit, Brookfin, Slate, Fernlet, Voltik and Emberhorn, each with its type, face notes and palette.
Each of the six species in three moods: neutral, confident and defeated.

From the Claude Design character sheet in the project's repo. The app draws the same vectors with Skia.

One engine decides every result

138 tests at the latest checkpoint

The rules live in their own TypeScript package: no React, no Expo, no phone code. The app asks the engine what each side is allowed to see and draws that. No win, score or damage maths lives in the app.

The offline studies below run on the same engine and the app's own AI, so what they measure is the game itself, not a copy of it.

138

Tests: 84 engine, 48 app and controller, 6 studySource: Creature Clash docs/phase-7-verification.md

18 days

First commit to XP and progressionSource: Commit times from the project's git history

19

Commits in the repositorySource: git log

Balance, simulated before it's played

Balance questions went through the engine before they went to a playtest. Two studies are in the repo.
1,600 simulated gyms and 4,320 build cases

The first played 1,600 gyms, both trainers on the same AI, with training and exchanges switched on and off. With both sides on the tactical AI, draws fell to 11 to 22 in 200 gyms, from 47 to 54 with the greedy one.

The second checked training builds across all 36 species pairings, 4,320 build and matchup cases. At the largest budget, 4 of 750 equal-budget matchups left one side with no way to win, all Emberhorn against Fernlet, so that rule is still marked experimental.

These show what can happen, not how often people win. Pacing, readability and whether you want another duel still need people playing on a phone.

Outcomes of 200 simulated gyms per setup: A wins, B wins and draws, by AI policy, training and exchanges.
Greedy AI on both sides
SetupABDraws
Training off, exchanges off796754
Training off, exchanges on906347
Training on, exchanges off806951
Training on, exchanges on886448
Tactical AI on both sides
SetupABDraws
Training off, exchanges off809822
Training off, exchanges on8810012
Training on, exchanges off849719
Training on, exchanges on939611
200 simulated gyms per setup, both trainers on the same policy; A and B are the two trainers. Source: Creature Clash docs/phase-7-verification.md.

From first commit to progression in 18 days

19 commits, 11 milestones

The engine came first, then a playable phone screen. The Claude Design work arrived on 19 September and was rebuilt as native components on top of the working game. These times are straight from the git history, in India Standard Time.

  1. First commit: the Expo app and an empty engine packageeb73c8a · feat: project setup
  2. The battle engine, in plain TypeScript5f7349b · feat: battle engine init
  3. Player views: what each side is allowed to see4db91ac · feat: player views
  4. Sessions, and greedy and random AI7e663c0 · feat: session policies
  5. The first duel on a phone screen8827fb4 · feat: native screen duel simulation
  6. Encounters, 3v3 and an offline battle studyc32be75 · feat: encounters, swap run, 3v3
  7. Gym battles: private teams, secret deployment9bcee03 · feat: gym duel setup
  8. Species clues and the tactical AI14cbadb · feat: species clues + tactical ai
  9. The Claude Design screens, rebuilt as native components6384b8d · feat: creature ui
  10. A trainer journal, saved on the device5279262 · feat: decisions around battle
  11. XP, training and progression5193519 · feat: xp and progression

Decisions

Each one from the project's own docs
  1. Draft, then lock in

    A pick stays editable until you press Lock in; only then does the app hand it to the engine. If the ten seconds run out, the first unused category is committed, whatever the draft said.

  2. No drama the engine didn't decide

    The reveal is a short fade that respects reduced motion. There is no attack animation or extra damage step: the values and the HP change come from one engine event.

    240 ms

    Reveal fadeSource: Creature Clash docs/design-handoff.md
  3. Clues, not numbers, for the opponent

    Each creature's stats differ a little from its species, so the opponent's unplayed values stay hidden behind species tendencies. Exact values and ranges remain as comparison modes for testing.

  4. The clock waits when you leave

    Backgrounding the app mid-pick pauses the remaining time, and waiting at a reveal never eats into the next exchange's clock.

  5. Nothing invented for the screenshot

    The design showed a trainer on Day 12. The native app shows the real roster and no progress it hasn't earned.

  6. A crash can't pay out twice

    Rewards and the pending gym result are saved in one write before the exchange step. Force-closing and reopening restores the result without awarding XP again; that was checked on the Android emulator.