Projects

Arcade

A browser game portal with five games to play alone or with friends in online rooms, on a computer or a phone.

Role
Personal project: I direct it, run it and host it for friends
Year
2026
Stack
TypeScript, Phaser, Vite, Bun, Nakama, WebSocket, PostgreSQL, Caddy, Vitest
Website
play.linhmh.site

Arcade is a small game portal I run for my friends. You pick a game, type a name, then play alone or open a room and share its code. Everything runs in the browser, on a computer or a phone, and online rooms play in real time.

The games

  • Coop Strike: a pixel-art shooter where up to 4 players fight off waves of space chickens and a boss.
  • Võ Lâm Liên Đấu: a martial-arts arena for up to 5 players, last one standing wins.
  • Mochichi: a phone game where you tap to fly two cats past Tokyo towers and neon signs, alone or in a race for up to 6.
  • Bầy Xác: up to 4 players hold out against 10 waves of zombies.
  • Hoa Sơn Luận Kiếm: a fighting game with six fighters, for up to 4 players or against the computer.

Under the hood

  • It is TypeScript all the way: the games are drawn with Phaser and built with Vite and Bun, and the portal page uses no framework.
  • Each game's rules live in a simulation with no graphics or browser code in it, so in every online room the server runs the same code as the player's browser.
  • Online rooms run on Nakama, a game server, over WebSocket, with PostgreSQL behind it and Caddy in front.
  • In Coop Strike the server only sends what changed since the last update. In a 4-player boss fight, that cut each player's traffic from about 760 to about 90 kbit/s.

Playtesting

Friends played the games on their phones, starting with Coop Strike, and whatever they ran into decided what got fixed next.

  • On one phone, the prompt to turn the phone sideways stayed on screen after it was turned. That same night the game started re-reading the screen size after a turn, got a button to play upright instead, and stopped taps on the prompt from reaching the buttons underneath.
  • In Bầy Xác, a tester wanted to fire with a tap instead of a hold and to move with one hand while aiming with the other, and found the ammo hard to keep track of. On phones the game now starts with two sticks, a tap on the right half fires one shot, and an ammo count under the player warns when it is running low or empty.
  • In Hoa Sơn Luận Kiếm, a tap made in the middle of a move only went through once the move ended, which felt sluggish. Now, there and in Võ Lâm Liên Đấu, a press that cannot start when it arrives is simply dropped.
  • After that, phones came first. In tests on an emulated slow 4G phone, Bầy Xác answers the first input after about 0.6 s instead of 2.8 s, and after a simulated stall a player in Bầy Xác or Coop Strike is back in their seat in about 6 to 10 s instead of over a minute.

Art credit

The Hoa Sơn Luận Kiếm fighters in the pictures on this page are "Elementals" by chierit, used under CC BY 4.0 (creativecommons.org/licenses/by/4.0) and modified.

On a computer

Coop Strike played solo: the first of three waves of chickens, the ship at the bottom and the points each hit scores.
Coop Strike played solo: the first of three waves of chickens, the ship at the bottom and the points each hit scores.
A Hoa Sơn Luận Kiếm practice fight against three computer fighters on temple rooftops.
A Hoa Sơn Luận Kiếm practice fight against three computer fighters on temple rooftops.

On a phone

The portal, with Mochichi marked as a phone game.
The portal, with Mochichi marked as a phone game.
Mochichi upright: a cat flies past lanterns and a tower.
Mochichi upright: a cat flies past lanterns and a tower.
Bầy Xác at the first wave, with touch controls to move, aim and shoot.
Bầy Xác at the first wave, with touch controls to move, aim and shoot.

All projects