How I force private games in Colyseus with Auth0 and manage rooms for long played games

Search for a command to run...

No comments yet. Be the first to comment.
Hello. I'm writing a Lambda "tick" function to simulate the universe for my game. It's a different architecture than my previous idea of maintaining a 24/7 server, which simulates a busy real-time game loop. I wanted to give it a try. In this post, I...

A small tool that lets you put a "marker" on a song and have a button to recall that position with a click.

Hey there! I had a blast participating in the Appwrite hackathon and I want to share my journey with you. So, buckle up and get ready for some timer magic! Team Details Okay, before we dive in, let's get to know the team (well, it's just me actually)...

Hello. I've decided to try something for the game I'm developing. The game is a long-running online solo/coop space strategy game with resource balancing and 4x elements, but that's not the subject of this post. I decided to separate game logic code ...

Hello. For this one, I ended up using Hammer.js. I did try Interact.js which is definitely newer and more updated, but that just... well... didn't work nicely. Judging by the examples on both libraries' pages you can see if the core functionality of ...

How I force private games in Colyseus with Auth0 and manage rooms for long played games Hi, what's up? I decided to write about the way I handle my games and game rooms in my Colyseus-based game server.
My game is an online persistent-universe single/co-op player game where your games continue even when you are logged out of your account. In this 4X/resource-management space-themed game, resources are extracted, things are built, researched advances, even when you're offline.
Early on, I made a decision that I don't want a Colyseus game room open for each game and having long-running rooms forever, but rather that for every game session I'll open a dedicated room. When a player or a group of players logs in and chooses the game, a game room is created for them and the room state is synced with the actual game data in the database. The room state is also synced when the game "ticks" or other events occur and all connected clients are updated automatically by Colyseus.
The way I made things work is as such. I have a regular endpoint in my API, separated of Colyseus, that the client calls to get a reservation for a room. Using the Colyseus MatchMaker API I first query for room with a certain identifier for the game, I call it the gameName, at least for now. If that does not exist then I create such room with the name identifier and matchMaker.reserveSeatFor it. If I do find such game then I create a reservation using .matchMaker.joinById as I now know the ID of the room. In both cases, I get a reservation object that I send to the client which consumes it with the Colyseus client API. And the client joins the game.
This is nice, but there's a small catch to how I do things.
I use Auth0 for authentication. It's easy enough to protect my own API endpoints with Auth0, but I did not find a way to protect the Colyseus routes with that same authentication middleware. That made me very sad. I went to sleep on it and in the morning I realized that I can do a funny workaround. My endpoint for requesting a reservation do gets the auth JWT as it's one of the regular protected endpoints. It turns out I can attach options to the reservation object, so I just attached the JWT itself to the reservation.
When the client consumes the reservation, the options from the reservation somehow arrives to the onAuth handler on the GameRoom class as the client is not supposed to tamper with the reservation object. In any case it does tamper for some hacky reason, I fire up my JWT validation again and can deny or approve the user.
It works. One thing that I worry about is multiple coop players, where each is going to use their own JWT and I'm not sure if the reservations will work properly and nothing will go nuts. I'll test that sometime but I think I'm fine.