I'm creating a multiplayer game that can have many game rooms and I want to associate a game object (or game state) per room; I am using NodeJS, Socket.io, socket.io-redis (not sure if this one is even needed).
Just to be more clear, I am using Typescript as well.
I have tried using socket.io-redis' remoteJoin()
function and successfully setting a game object to the room by using
io.of('/').adapter.rooms[<roomId>].game = Game
.
However, I read that this is not the proper way of setting a room wide object.
Event for creating a room
socket.on('create-game', (createData: any) => {
this.io.of('/').adapter.remoteJoin(socket.id, createData.roomId, (err: any) => {
let player = new Player(createData.username)
let game = new Game(createData.roomId)
game.addPlayer(player)
this.io.of('/').adapter.rooms[createData.roomId].game = game
})
})
Event for joining a room
socket.on('join-game', (joinData: any) => {
this.io.of('/').adapter.remoteJoin(socket.id, joinData.roomId, (err: any) => {
let player = new Player(joinData.username)
let game = this.io.of('/').adapter.rooms[joinData.roomId].game as Game
game.addPlayer(player)
})
})
What happens on the create-game
event:
- the data coming in is used to create a
Player
- and a
Game
object - then the
player
is added to thegame
object - finally, the
game
object is added to the room
What happens on the join-game
event:
- the data coming in is used to create a
Player
- the
Game
object is created by retrieving it from the room player
is added to the game object
After countless days/weeks? of searching, I stumbled on this Stackoverflow thread: socket.io, how to attach state to a socket room
What this answer is saying is to basically not do what I did above. Their suggestion is to create your own data structure (not sure how to even begin doing this).
Other answers I've found say to just create a global variable in the server, but again, others say this is bad practise (which I think as well).
Another popular answer is to store the game in Redis, but Redis cannot hold complex Javascript objects. I now that Redis can hold hash data, via the hmset()
function, but I found this to not work with something as complex as a Game
object, with functions, constructors, and getters/setters.
One more answer that stands out is to only store the game to the DB after a "round", but in my case, once the game is finished, the room is closed and the associated game is destroyed; I don't need to persist this game in the sense of "saving a game".