TapIn Pokémon

Architecture

How TapIn Pokémon is put together: the TapIn app, a game server and one WebSocket.

TapIn Pokémon has two parts: the TapIn web app, which gained a Pokémon layer, and a game server that owns every rule. The app shows; the server decides.

 Browser (TapIn web app + Pokémon layer)
   │  REST   /pokemon-api/*        Bearer <ID token>
   │  WS     /pokemon-ws?token=…   live battles, encounters, events
   │  files  /pokemon-assets/*     artwork, sprites, cries, fonts
   ▼
 Game server (Bun, one process)
   ├─ battle engine      pure TypeScript, Gold and Silver rules
   ├─ game services      encounters, gyms, tournaments, trades, flyovers, rewards
   ├─ SQLite             trainers, Pokémon, items, badges, points
   └─ TapIn API          who you are, which communities you own, who is hosting

The game server

A single Bun process serves everything:

PathWhat
/pokemon-api/*REST: reading state and one-off actions (buy, heal, nickname, trade). REST API
/pokemon-wsWebSocket: everything in real time. WebSocket messages
/pokemon-assets/*Static game assets: artwork, sprites, icons, cries, the battle font
/healthHealth check as JSON
everything elseThe built web app, with single-page fallback

The server is authoritative. It rolls encounters, runs every battle turn, pays rewards, moves items and Pokémon, and keeps the tournament bracket. The client never computes an outcome; it sends choices and animates the events it gets back.

Identity

A trainer is a TapIn account. The client sends the ID token it already holds from TapIn sign-in. The server verifies the token's signature and audience, then asks the TapIn API who the user is (id, username, display name, avatar). Trainers are keyed by the TapIn user id, so a trainer's lead Pokémon can appear next to their avatar anywhere TapIn shows that user. Community ownership and live hosting are checked against the TapIn API in the same way.

The battle engine

Battles run in a pure TypeScript engine with no I/O: a battle is a plain JSON state, and resolving a turn is a function of the state and both sides' actions, with a seeded random number generator. The same inputs always give the same result, which keeps battles easy to test and to resume after a restart. The server stores the state, applies the 10 second turn timer, and on timeout asks the engine's AI for a move.

The engine follows Gold and Silver: the damage formula, the type chart, critical hits, statuses, weather, held items and the catch formula. What it does is documented in Battles and Catching.

Data

Species, moves and items are generated once from public sources (PokeAPI and the disassemblies of the original games) into typed data files: 251 species with Crystal level-up learnsets and Gold and Silver TM lists, the 251 moves, and every item. The Pokédex on this site is built from the same files.

The Pokémon layer in the app

A provider mounted once at the root of the TapIn app holds the socket and the trainer state. It renders the encounter overlay, the battle screen, the evolution scene, move-learning prompts, challenge and trade toasts and the starter screen on top of any page. On live pages the battle docks beside the stage; on phones it becomes a bottom sheet.

TapIn Pokémon is an unofficial fan project. Pokémon and all related names and artwork are trademarks and © of Nintendo, Game Freak and Creatures. Legal

On this page