Seeking advice on choosing an appropriate networking model for my game

Godot Version

4.6

Question

Hello everyone. I come with a question which is bothering
me lately. I am building a suite of word mini games. When first
starting this project, I thought its going to be fun when playing by
yourself – I am type of a player who plays mostly single player
things. However the more my friends tested the games, the more obvious
it became that they want a multiplayer version of the suite so I
started researching on how to best implement it. Here are the
requirements I have outlined for my project.

  • Quick registration: no E-Mail, no phone number, just user name and
    password (for playing with friends and saving scores).
  • Central server: the target audience for my game should not be
    expected to know how to forward ports or host a reverse proxy just to
    play some word games with friends or strangers online.
  • Room based design: every player should be able to do the following:
    • Create their own room (possibly password-protected).
    • (optional) invite other online players to the room.
      Room administrator should be able to start the game when a
      sufficient number of peers is connected.

The research

Before asking here I have decied to do some research. My ability is
very limited but I have outlined 3 paths I could follow.

High level multiplayer

It seems like the easiest option. Its built-in, supports high variety
of nodes and the setup overheat is minimal. However there are some
gripes with it, of which the biggest one is that, from what I have
found in the docs its UDP only. Since my games are turn based, sending
only text I don’t think UDP is a good idea.

Lov level network abstraction

I can implement most of the game state myself, however then I am
risking my player’s security. I have never written a multiplayer game
before, and I know there are many ways an attacker can exploit my lack
of skill to attack my players.

Server in another framework

I am very familiar with Swift and Vapor. I could write my server in
Vapor (using Websocket) and make my game connect to this server. The
manual state management is still up on me, but I decrease the risk of
making a mistake because I use a familiar framework, however, I want
to become really good at Godot and making a substantial part of my
game in another framework won’t help with that.

I would like to ask you, which path should I choose and why? And where
can I learn?

What platform are you planning to ship on? Various platforms have ready-made systems for this; Apple stuff has GameCenter, for example.

GameCenter isn’t great (or at least, it wasn’t the last time I messed with it, but I suppose it’s been over a decade…), but it’s fairly plug & play for the kind of thing you need, and it makes the server be someone else’s problem.

On the other hand, if you want something that’s not tied to a specific platform…

UDP isn’t a problem, particularly, and has some advantages even in a turn-based setup. In particular:

  • no head blocking, so if a packet gets lost it doesn’t stall everything; in a spotty network situation, this can help even for turn-based games
  • no connection, so you can hang everything off one socket

There are other options, though; depending on how long your turns are, you could use email, SMS or platform notifications to deliver turns.

The big thing is, if you’re making your own server with matchmaking and such, you’re going to discover that you’ve become responsible for content moderation, user name moderation, banning and harassment management… a handful of jerks and griefers can cause problems all out of proportion to their number, and those problems get to be yours.

Hi, I plan to ship on Windows and macOS. Now you got me scared, how other simple games do it? I didn’t know that UDP has such advantages. My turns are rather quick – 10 minutes at most.

I think there are some frameworks out there for it, but I haven’t tried them myself; I’ve used GameCenter on iOS (which is… okay… if everyone is on apple platforms, but I don’t think works anywhere else) and adhoc stuff on Nintendo DS (which is also platform-specific and also very localized). I’ve been involved with larger networked projects, but someone else handled the infrastructure for those, and I know a lot of effort went into content moderation.

Any place someone could create an image or type some text, including places like user names, you have to be careful.

You also generally want to make it so that any decisions that could affect who wins are made on the server, if you can; if my machine tells you what I rolled, I can make my machine lie and always roll perfectly.

Assuming your turns are relatively simple, you can probably pack all the info needed into a single UDP packet. The “safe” size for a UDP packet is generally ~1400 or so bytes or less, for a variety of reasons; look for UDP MTU if you want details. You can use that to encode action requests for the server to resolve, and the server can send out update packets.

Personally, I’d probably put a simple header on the packet that was (say) an opcode (what kind of packet is this?), a turn index, a source id (one of the players? the server?), and a data size in bytes. I’d probably put a flag field in too, maybe pad it out to some power of two number of bytes.

Websockets would work fine too; they have the head blocking problem (under the hood it’s largely a framing mechanism layered on TCP), but most of the time that should be fine. In practice what it means is occasionally someone on a lossy network connection winds up stuck.