I'm building a game server for a turn-based RPG game, where the players control their characters through a web interface ( think kind of like a Jackbox Party Pack game, where there's a screen that shows shared info and the players devices let them send their inputs ).
I've got most of the foundation set up: clients can connect, create a game, additional players can join the game using a code, the game server is doing real basic game loop stuff.
I'm starting to work on the actual input & tick handling. Because this is in Go, there's a goroutine that handles the input which is separate from the goroutine that handles the game updating every tick. I've basically got a for loop with multiple selects ( so that a new client doesn't prevent a server tick from getting processed ), kind of like this:
func (g *Game )listen(){
ticker := time.NewTicker(time.Millisecond * 200)
for {
select {
case nc := <-g.newClients:
g.acceptNewClient(nc)
case lc := <-g.closingClients:
g.unregisterClient(lc)
default:
}
select {
case u := <-g.output:
if len(g.players) > 0 {
for c := range g.players {
c.out <- u
}
}
case in := <-g.input:
g.handleInput(in)
default:
}
select {
case t := <-ticker.C:
g.tick(t)
default:
}
}
}
What I'm trying to figure out right now is the best way to handle that player input and how it should update the game state.
For example, the first state the game starts in is character select. All players are able to select one of four character classes, but can't double up ( ie, can't have two fighters -- first come first serve ). The VIP also has the option to start the game, which will randomly assign classes to players who haven't selected, and create AI players if there are fewer than 4 players.
Should the input handler be able to directly modify the game state -- ie, when it gets a message from player 1 saying they want to select a fighter, it modifies the game state to do the right thing, or should it be throwing messages into a queue? For example saying "hey, the VIP says to start the game" or "player 2 selected fighter" and then the tick handler does the appropriate thing?