What's it all about?
I always admired how games like agar.io and slither.io are simple yet successful at retaining players. As my main stack being JS/TS, I wanted to see if I can develop a multiplayer game.
The thing I imagine
I'm a total stranger to game design and development and I'm only interested in the tech part. So it can be a silly and unbalanced game, but I wanted to achieve:
- A lobby logic
- A real-time game experience
- A canvas where players interact with each other or other elements
I started see what I can start with. My best guess at that moment for the requirements were:
- A game server and a client
- Server should
- store a collection of ongoing game sessions, each element relating a game ID and the state of the corresponding game session
- there should be a game loop that should only be executed for the game sessions started, ticking nearly at 16.67ms for a 60FPS game experience
- the game loop should update a game according to the inputs collected from each game client, evaluate non-player mechanics with them and calculate the new state
- send the calculated game state back to the clients
- cleans up the game sessions if all players leave or the game is over
- Client should
- Request to create/join game sessions
- Render the game state received from the server
- Collect user inputs and send them to the server
Colyseus: Multiplayer game server framework
After some experiments with Express.js, I decided that it will be cumbersome to discover and test with all the work I need to do and found Colyeus.
It is a nice framework that can be used for various needs, from turn-based to real-time and can handle most of the boring stuff eg. game room logic, game loops, and types for TypeScript.
Phaser: JavaScript game framework
I could also work with a plain HTML canvas, a plain JS client and consume a Colyseus backend easily. I'm already using Cursor, so I could feed the Colyseus docs into a doc index, open the composer, type "consume this game backend" and voi la!
In fact, I did that exact thing and it was OKish, but not that great. Using assets from a stripe images was basically hell. Fast-moving elements was flashing, adding any effect was slowing it down, simulating slow networks with Chrome DevTools caused a disaster, and although Cursor composer is quite successful at coming up with a solution for the each visual effect I prompted, they were not consistent in style.
Then I found this cross-tutorial, exactly what I sought for.
In the second part I'll dive into the implementation. Spoiler: I wired them inside a Turbo monorepo.
But first I probably need to add remark-gfm
support to this Next.js MDX blog starter so that I have proper highlighting for all the code.