- Home /
Should I be using peer-to-peer networking for my 1v1 game?
I could use some help getting pointed in the right direction on an appropriate networking solution for my game. The thing is I don't need or want an authoritative server running my games, once the players have been matched the game can be played entirely peer to peer. I successfully added the UNet multiplayer to an old version of my game years ago but I'm otherwise very inexperienced with online services, which is why I'm posting here for guidance. I have almost no idea which multiplayer system, matchmaking server, and database I should be using.
Most important to me is cost, I need something I can build and test for cheap or free that will have a low cost with lots of users in the future. The game will be sold first in China in a free-to-play model so that's potentially thousands or millions of concurrent non-paying users. I'm looking into adding Forge Networking Remastered to my project with an Amazon AWS EC2 instance to run the matchmaker and authentication, which may or may not be the right idea at all.
Here's some info on the way my game uses networking:
The game is played 1v1 only (for now). Cheating by hacking the client is impossible by design, the players only send a list of moves to each other (grid point to grid point) and moves enabled by hacking will simply desync the game. They can make up to a couple dozen moves each second which can be bundled and sent at a very low frequency because those moves do not directly affect the other player more than once every second or two at most. I have no physics, animations, Transforms, or player models to sync.
Whatever networking solution I use will need a way to connect the players to each other by a matchmaking system that pairs them based on skill level. This part I've never done before. I know I can't let the client declare the player's skill level without checking it against an authoritative database (which also needs to record the outcome of every match) so I'm going to need a whole user login system.
In addition to automatic matchmaking I'd also like if they had the option to search for opponents by name and physical proximity, make friends lists (and spectate their friends' games), set up unranked offline local matches, and very importantly allow cross-play between PC, Android, iOS, and eventually even web browsers and consoles. They'll need to be able to login to their own account from every platform (not simultaneously) and have their wins and losses tracked across all devices.
The problem I'm facing is that all the information I find about networking solutions advertises features like "animation syncing" and "hundreds of players in one game" which I'm never going to use, and then charges hundreds of dollars a month for a thousand or more simultaneous players. I just need my matchmaking server to connect the players and get a reported result of the game when it's done (win/loss/disconnect/desync). It does not need to run any games itself or stay connected to a game in progress.
As I understand it, this means that my game actually should run peer-to-peer, or at least client-server with one of the players as host. Am I missing something? Any recommendations for services that do what I need?
Answer by NathanHitchcock · Mar 25, 2019 at 10:23 PM
Peer to peer is really a tricky technique to get right. Although it is cheaper in that you don't need to pay for dedicated server space, you open yourself up to a lot of cheating and tampering, which can cost you players and thereby revenue. No game is totally tamper-proof.
The nice thing about having an authoritative server is that you have someone in the game that you can trust. You can trust them when they say who scored a point, you can trust them when they say a user is cheating, and you can trust them when they say who won the game.
In a peer-to-peer game, especially one with a player count of 2, how do you know who is telling the truth about game state? Who tells you who won the game? If someone tampers with their client to always tell the matchmaker they won the game, how do you know if they're lying? Sometimes you can ask all the players in the game who won, but if there are only two players, then consensus can't really be trusted since the cheater is 50% of the vote.
Peer to peer is a risky move for a game, is all I'm sayin'. Here's how I would do it anyway:
Firstly, I would separate the backend from the game, logically speaking. The networking solution for the game is the peer to peer thing, the backend is some other entity that does the user authentication, matchmaking, and manages other user requests or actions. These systems will probably communicate in some way, but they are built to solve different problems.
1. The Matchmaker/Authentication/UserManagment Server (aka The Backend)
There are a lot of solutions to this piece of the puzzle. When it comes to "out of the box" solutions, you might want to checkout Playfab, or something like it. Having an "out of the box" solution can save you a ton of dev time. You might have to give up a little bit of control, like writing your own matchmaking algorithm, or building your stats api if you want one, but you could have a prototype up and running pretty quick (estimating, I haven't used Playfab in any of my projects). I would highly recommend not building a backend from scratch if you don't need to.
1.1 Building a Backend from Scratch Because You Need to
If you want to go H.A.M. and build your own backend from scratch, there are a lot of options available. There is an entire industry around building enterprise level backends, so the D.I.Y. approach is a deep rabbit hole. AWS has some good starter packs, like their elastic beanstalk framework. The gist of making a backend is that you're making web servers (or something web-server like). Your users connect to a web server, and that web server talks to other web servers to authenticate them, which maybe allows the users to connect to other web servers, etc... etc... etc... It's web servers all the way down, man.
The simplest approach would be to build one monolithic web server that handles everything. A user connects to it, authenticates through it, matchmakes through it, and queries for user information through it. This monolithic approach suffers from an almost complete lack of scalability (it won't be able to service a high volume of users), but it is fast to build and cheap to run (for small amounts of users). You could probably manage hundreds or thousands of peak concurrent users on a decent sized monolithic server.
1.2 Authentication Ideas
I would highly recommend not managing user authentication yourself. There are plenty of authentication services that you can use, like OAuth, that takes care of handling sensitive user information so you don't have to. You can still have a user database with profile information and stats without having to manage passwords.
1.3. Ranking Algorithms
The big decision when it comes to ranking systems is: "Is your game Zero-Sum"? Does every win for one user equate to a loss for the opponent? If your answer is yes, then a very simple system to rate user skill is the ELO ranking system (used in the early days of chess).
The high level of ELO is: - Every user starts with a certain score (1200 or something) - Every win takes some amount of score from the opponent and gives it to the victor (Maybe 12pts)
There are a lot of variants of ELO, but that is the heart of it, and it's pretty dirt simple to implement.
This version of ELO also has some drawbacks, like being too punishing for very high skill users, not rewarding the underdog enough, and new players all start at the same score regardless of actual skill, but it's a fine starting point.
If your game is not zero sum, you need some metric to evaluate how well your user did, so you can increase their matchmaking ranking by the proper amount.
1.4 Matchmaking Algorithms
Once you have a way to rank players, finding matches in a pool of users isn't too much more work. You would have to wait for users to queue up for a match, then find another queued user within a certain ELO range (maybe +/- 20 ELO) or physical range(1 mi). After some time, if you haven't found a good match, you could relax the matchmaking constraints and find someone with +/- 40 ELO and 20 miles, so on and so forth. The ranges all depend on how long you want to make your users wait for a match, and how many users you have available.
2. Figuring out the Peer to Peer Part
Once you have a backend in place, and you've matched two players, you can send one the information to connect to the other, and you tell the other to await the first ones connection (NAT punch through is something to look into for this step, most peer to peer libraries will handle this though).
You have the peer to peer communication working, but the hard part is forming a consensus on what the result of a game is. It's possible one player is really de-synced, or cheating, so how do you build trust in a client? One way might be to require that both users submit a whole log of the game to the matchmaker, but those can still be forged. If you had more users in a game, you could just trust the majority vote, since it is unlikely a single malicious entity could control two clients, but what happens when the Goon Squad shows up? Maybe you could require frequent check-ins from both clients about the state of the game, and then your matchmaker would have a better record of what's going on, but that's essentially an authoritative server at that point. The problem of deciding who to trust is in a decentralized system is non-trivial, and it's why we have technologies like the blockchain for decentralized currency. Maybe you could take inspiration from the block chain and build a ledger of moves? It's still a delicate system when there are only two people involved.
Another concern about peer to peer is that you have just given someone access to someone else's computer with no intermediate. Once you know someones IP address, it's kind of like knowing their telephone number. Spam calls and everything.
TL;DR: peer to peer is scary and building your own backend solution is difficult.
Anyways, let me know if you have any more questions, or if I wasn't clear about anything. I've done this sort of work a couple times, but I am by no means an expert.
Thanks, this is really informative. You did hit on the one thing that really worries me about actually going peer-to-peer, that the players would be given each others IP addresses. I'm fairly confident about my ability to make the game entirely deter$$anonymous$$istic so the only reason for a desync would be a hacked client (or bug) which means that any player who desyncs significantly more than average could simply be banned from matchmaking. But I can't do anything to prevent a player from launching a DDOS attack on their opponent to force them to drop connection.
$$anonymous$$aybe when the game is earning enough money to pay for dedicated servers then I'll switch. Right now I don't have the money for that, and the game needs to have online running out of the gate. And matches can last as little as 30 seconds.
I've got the ELO system and matchmaking more or less figured out, I'm just a little lost on how to implement it. You're right that making my own backend solution is difficult, but which backend should I be looking for? There are so many networking plugins and backend services out there I don't know which one will give me the best value for my kind of game or offer the features I need. It's far from a standard FPS, and I really do need a fully cross-platform system. The single most important aspect of my game is the ability to play it on everything against anything.
Thanks for the Playfab recommendation, I'm checking them out. I also just found the App42 backend as a service and am looking into that, it's supposed to be fully crossplatform and seems to be what I'm looking for. Being so new to networked ga$$anonymous$$g is making this all very confusing.
Fortunately, DDOS'ing is expensive, and it would probably be easier and less illegal (DDOS bot clusters tend to be made of stolen devices, I think) to buy two devices, GPS spoof both devices to Saturn, and "Find Nearest $$anonymous$$atch" for an easy win. Regardless, sharing your players IP address with other players is still not a great idea.
A lot of these software packages blur the line between game servers and web/API servers. The client to client or client to server (aka game) communication is very different in nature from the client to web/API server communication. What I call the backend is the web/API server. You already have the game stuff working, from what I read in your post, so you just need this backend component.
There is this phenomenon called choice overload, where people find it hard to make decisions when based off of lots of parameters between lots of options. In the end, sometimes it's better to just pick one that works for you, and get a prototype working. After you have that done, you can compare and contrast other software that you could use to replace the prototype. After doing the whole backend integration process, you might also have more insight into what matters to you when picking a backend.
Also, backends all tend to be cross platform by nature- that is, they tend to be compatible with clients on any platform, since they just communicate to a client over http or some other standard protocol. The client/server game exe might be restricted to certain platforms, or the backend provider might give you a unity plugin or dll that is only compiled for windows or mac, but this is just an unfortunate side effect of the backend providers bleeding into providing client to server communication libraries. If you were to build a backend yourself, or look for a pure backend provider, you would probably have to find your own client to server communication library, and you probably wouldn't see the "Cross Platform!" sticker on the box, but that's okay.