Hosting game servers on demand (when another service asks for it)

Hi everyone!

Quick theoretical question on the Fly ecosystem; I’m making a multiplayer game using websockets/webrtc(udp) and I want to host a singular Node.js app that are holding the game instance. Think of this like a Counter Strike server for example. The trick here is that these servers should be created and run on demand when there is a request for a server done in some other service (for example, postgres table is checked if there is a need for server).

Could you provide some reference how you would set this kind of setup on the Fly?

You should be able to use Fly machines for this:

1 Like

Yeah this sounds pretty solid! Basically I need to boot up a new server using the api, then store the state and the public ip to some database for the clients to be able to join… And after the game session ends, I destroy the created server. Might need some access control though, so only some players are allowed to join…

Another thing I am kind of pondering, is the fact that am I able to create the servers from an another fly app? I still don’t know what that would be, maybe the regular api app polls the database to see if some servers need to be booted up and then orchestrates that (or if you have additional ideas)? And in case of errors, can the machines self terminate as well? :smiley:

This’ll work well with Fly Machines and a feature we call fly-replay.

What most people do is have one “gateway” app that accepts all requests, and then one or more other apps that contain the machines they expose to end users. Since you’re talking about sending people to specific machines, I’d put all the game servers in a second app. So you’ll end up with:

  • game-gateway
  • game-server

When you receive a request in the gateway, you do all your work to figure out which machine it should be routed to. Or create a machine, then keep the ID.

Once you know the ID you want the request to go to, just reply with a header like fly-replay: app=game-server;instance=<id>. This will result in the websocket being connected to the server you want. If the machine is stopped, our proxy will even start it for you if it’s in a stopped state.

Killing off old machines is a little more work. The simplest is probably to make them exit when they’re finished, and then poll the API from your gateway app periodically to find stopped machines, then remove them.

Does that make sense?

4 Likes

I am also trying to run game servers on fly. I am a bit confused about one thing - how does game-gateway figure out which region to bring up the instance in. From what I feel, the region can only be decided

  • from the client device itself, by pinging some publicly available fly servers in all regions to see which have the lowest latency. and then passing along the region info in the request to the gateway.
  • some way for game-gateway to know that the server we are trying to spawn should be close to the given client IP address (and not close to the game-gateway itself). Because the game-gateway may only be running in a single region, and the game-servers are needed to be geographically closer to user, as they are the one eventually handling the websocket connection.

Any suggestions on how to achieve this? I was actually going to make a separate post asking whether fly has some API which can tell which region is closest to the API caller.

@hi.kanily you can use the Fly-Region HTTP request header to see what region the client is in: https://fly.io/docs/reference/runtime-environment/#fly-region

1 Like