Diamond Edge

Case study · Kotlin Multiplatform

Two apps on one Kotlin Multiplatform codebase

Diamond Tabletop and Napkin Scores shipped to the App Store and Google Play in 2026. Both come from one codebase, written once in Kotlin and Compose Multiplatform for Android, iOS and desktop.

Diamond Tabletop

Eight card and board games: Hearts, Rummy, Gin Rummy, Oh Heck, Kentucky Discard, Prosper, Inlay and Tempt Fate. Bots fill empty seats, and friends can play together across phones.

Rules as downloaded scripts

Each game's rules are written in kscript, a Diamond Edge interpreter for a subset of Kotlin. It parses with an ANTLR grammar, runs without reflection so it works on every Kotlin Multiplatform target, and serialises compiled programs to blobs the app loads without the parser. Board layouts, tap input schemes and house rules (such as Oh Heck's four scoring systems) are bundle data too. The app ships none of the games: the whole library syncs from a published catalog at first launch, with conditional GETs and SHA-256 checks, so a new game or a rules fix needs no app release.

Multiplayer with an elected host

One device is the authority: it runs the rules and broadcasts state, and the others send input and render the changes. A Ktor relay and signalling server, deployed at relay.diamondtabletop.com, connects them over WebSockets into public or private rooms. A full game has been played across networks, a desktop on a LAN against a phone on cellular, surviving backgrounding and airplane-mode reconnects. A player whose app is killed can reopen it, enter the room code and land back in the same seat. Optional accounts are served from the same Ktor server, backed by Postgres.

A release decision

The desktop app builds, runs and hosts LAN games, and its installer pipeline produces DMG and MSI files. It still didn't ship. A JVM desktop app has no store and no auto-updater, so every install would become a permanently stale client against a relay, catalog and API that keep moving. Launch went ahead on Android and iOS, with desktop kept as a development and test target.

Kotlin · Compose Multiplatform · Coroutines and Flow · Koin · Room · Ktor client and server · kotlinx.serialization · Exposed · Postgres

Napkin Scores

A score pad for games played with physical cards, with ready-made scorecards for Flip 7, Qwirkle, Five Crowns, Skyjo, Skull King, Canasta, Oh Heck and Golf. It is deliberately small: no game engine, no sign-in, no ads and no analytics, and its App Store privacy label reads Data Not Collected. At real card tables it introduces people to Diamond Tabletop.

Its look comes from Napkin, an open-source Compose Multiplatform theme in which every Material 3 component is sketched at runtime. Each outline is drawn from a seed, so it wobbles like a pen line but doesn't move between frames.

The Napkin theme's demo: hand-drawn buttons, checkboxes, radio buttons, a text field, a progress bar and a sticky note
The Napkin theme's demo screen.

Back to Diamond Edge