[HN Gopher] Fast-Paced Multiplayer (Part I): Client-Server Game ...
       ___________________________________________________________________
        
       Fast-Paced Multiplayer (Part I): Client-Server Game Architecture
        
       Author : mkl95
       Score  : 107 points
       Date   : 2021-10-26 17:54 UTC (5 hours ago)
        
 (HTM) web link (www.gabrielgambetta.com)
 (TXT) w3m dump (www.gabrielgambetta.com)
        
       | Sohcahtoa82 wrote:
       | I used this guide when implementing my own real-time multiplayer
       | platforming game.
       | 
       | It really understates the importance of _authority_. It blows my
       | mind how many games, especially FPSes, give a lot of authority to
       | the client. Lag compensation for shooting is one thing, but
       | clients should not be able to shoot through walls or speed hack.
       | These types of cheats are _easy_ to prevent server-side, but
       | developers don 't because .... ? No idea. I've always guessed
       | that it's to reduce server-side CPU load, but that's all I can
       | guess.
        
         | mathgladiator wrote:
         | I believe part of the problem is that it is hard enough to
         | build a game in the first place, and networking is a deep skill
         | within itself.
         | 
         | I've been doing large scale distributed systems for a decade,
         | and I still feel like I'm learning especially as I retool for
         | games.
         | 
         | The way that I'm trying to make this simple is by inventing a
         | new platform for "serverless game hosting" using my programming
         | language (Adama : http://www.adama-lang.org/ ).
         | 
         | My focus on board game is the ultimate in server's role on
         | authority since board games are more transactional between
         | players and staggered (I play this card, that card enables
         | another play to react, that reaction enables another play to
         | augment, etc).
         | 
         | I'm looking into what it could mean to escape the board-game
         | pit, and one thing that I'm thinking about is latency. The
         | question that I'm looking at is whether or not I can have a
         | programming model be differentiated such that the client
         | prediction code can be generated.
         | 
         | A trivial way to exploit my language is to bring edge computing
         | into the mix such that the edge compute runs a copy of the
         | entire game, and then ships deltas quickly which will be
         | overwritten from the authoritative server. This will work on
         | updates to existing data (i.e. moving position), but it will
         | fail at creating new items unless I move unique id generate to
         | clients (which, is less than happy for me).
        
         | skipants wrote:
         | Hell, I can forgive it in games -- it seems pretty easy to
         | forget a detail that can accidentally give too much authority
         | to a user in that space, especially when you're trying to
         | crunch your frame time.
         | 
         | What really surprises me is how how often I see this mistake in
         | web development. "No, Bob, you should not increase the user's
         | bank account based on that number passed in from the frontend
         | React app."
        
           | tshaddox wrote:
           | I'm not sure exactly what you mean. If it's a web API request
           | from a web client that says "transfer $1,000 between account
           | A and account B," then what choice do you have but to "trust"
           | that number? Obviously you have to check whether the request
           | is authenticated and is authorized to transfer between those
           | accounts, and check if account A has $1,000, but what about
           | the _client origin_ of the request do you need to check?
        
             | nend wrote:
             | They're just saying to validate user input.
        
             | skipants wrote:
             | > and check if account A has $1,000
             | 
             | It was a convoluted example for examples sake, but I'm
             | pretty much referring to them missing this important check
             | here.
        
             | Tainnor wrote:
             | I mean since we're talking about banking:
             | 
             | - Generate a transaction number and associate that number
             | with the respective transaction details
             | 
             | - Send this number to the customer's mobile phone with all
             | those details, or other configured device
             | 
             | - the transfer is only authorised if the customer has
             | entered the transaction number
             | 
             | That way, the customer is very likely to have verified the
             | details of the transfer.
        
         | Thaxll wrote:
         | > should not be able to shoot through walls or speed hack.
         | These types of cheats are easy to prevent server-side, but
         | developers don't because ....
         | 
         | "easy" so you think veterant c++ dev that invented those
         | concepts are dumb or lazy and it's a solved problem?
         | 
         | It's not easy and not solved because those are very complicated
         | issues.
        
           | jbluepolarbear wrote:
           | It is easy to prevent wall hacks and speed hacks. Prediction
           | input resolution, server keeping an authoritative
           | representation on the server, and limiting the synced objects
           | to the current view of the player are all easy when done
           | individually. Thinking about all these concepts at the same
           | time can be confusing for people new to the topic, but each
           | subject is relatively easy to understand and implement.
           | 
           | I'd say that this article handles the speed hack issue
           | because of authoritative server state, but doesn't go far
           | into limiting what is sent to the player or not. The issue
           | arises when you didn't make your game multiplayer from the
           | start and adding prediction and sync visibility isn't an
           | option, that's where you get player authoritative states that
           | share their states with the other players. Client
           | authoritative is easy to implement, impossible to prevent
           | cheating.
        
           | Sohcahtoa82 wrote:
           | Baloney.
           | 
           | Why is it hard to add server-side detection for line-of-sight
           | when a player shoots at another player? The client should not
           | be telling the server "I shot Player 2 and did X damage".
           | Instead, the client should be saying "I shot in X direction
           | at Y time" and the server should be reconstructing the world
           | at Y time (As described in the Lag Compensation page of the
           | article) to determine a hit. The server should be performing
           | line-of-sight checks.
           | 
           | In a game like PUBG, there's no reason a player should be
           | popping headshots against players a mile away when there's a
           | hill and/or several buildings between them. But the game
           | allows clients to decide when they score a hit. At least, it
           | did in the past.
        
             | gameswithgo wrote:
             | pubg doesn't allow shooting through things, the server
             | checks if the shot was possible. instances where it feels
             | like that are just due to lag. in pubg you can get hit
             | after moving, with server side hit detection instead you
             | miss when it looked like you hit.
        
             | Thaxll wrote:
             | You should read this:
             | https://technology.riotgames.com/news/demolishing-
             | wallhacks-...
             | 
             | In anycase it does not work like it should in Valorant.
        
             | Matheus28 wrote:
             | Because of client-side interpolation and prediction, the
             | client isn't on the same game state as the server, just an
             | approximation of it. It's the tradeoff you have to make for
             | a smooth game experience.
             | 
             | The server can do a best effort attempt at rewinding the
             | game state and take into account how the client is
             | interpolating the world, but it gets very complicated as
             | game complexity goes up.
             | 
             | Someone correct me if I'm wrong, but I believe the Source
             | engine does that for the attacker and the victim, but
             | ignores all other entities for the ray casting (so it can
             | only really prevent shooting through the map walls)
        
               | Animats wrote:
               | Yes. There are two issues here - "don't trust the
               | client", and hiding lag. Not trusting the client is
               | mostly about re-doing some checks the client supposedly
               | already did. It's work, but it's not conceptually hard.
               | 
               | Hiding lag requires guessing about what moving objects
               | are likely to do. This works best for systems with a
               | limited set of moving objects, such as players and
               | bullets. As the author points out, bullets are handled as
               | a very special case.
               | 
               | I've done some work on this inside a Second Life / Open
               | Simulator viewer. That's a very general system - anything
               | can potentially move. You can make guns and shoot things,
               | but the system has no idea of "bullet", just physics. The
               | server is authoritative about everything except which way
               | an avatar is facing. So turning is fast, but movement
               | only happens after one round trip to the server. Round
               | trip delay is typically 40-200ms. The problem is hiding
               | that.
               | 
               | The server sends the viewer updates with
               | position/rotation, velocity/rotational velocity, and
               | linear acceleration. That last makes projectiles describe
               | an arc under gravity without server side updates.
               | 
               | When an update comes in, the moving object has to be
               | yanked back to where the server says it is. There are
               | situations in which the predictor isn't very good,
               | especially in the presence of jitter. And, the worst
               | case, a region crossing, where there are no updates for
               | 500ms-2000ms during the server handoff. The original
               | predictor would sometimes put vehicles far into the air
               | or into the ground for one update cycle. The predictor
               | was using the last velocity, which is noisy as a vehicle
               | bumps along a road following the outputs from the physics
               | engine. As in real life, there's vibration. The last
               | velocity, intended to be used only for 1/45 second, was
               | being extrapolated to 500ms-2000ms, or sometimes as much
               | as 100x the time it was intended for. So, low-pass
               | filtering and a error metric was added to make vehicle
               | movement look sane. The illusion can be maintained
               | reasonably well up to about 200ms of lag, but beyond
               | that, it shows as "rubber banding".
               | 
               | Shooters just don't work well in a system this general.
               | Archery is sort of OK.
        
             | munk-a wrote:
             | If lag exists this creates a fair - but really unfair
             | feeling game. Clients will constantly be reporting shots at
             | enemies that were quite accurate when the shot was taken
             | but are now extremely off the mark.
             | 
             | As the article mentions - fully server authoritativeness
             | works great in lan situations and for single player content
             | but can really fall on its face in multiplayer.
             | 
             | If I, as a user, am constantly moving in random directions
             | and have a lower ping than you (and thus my movements are
             | reported to the server before you can actually observe them
             | on your machine) then you should _never_ hit me except
             | through pure blind luck - in fact accurate shots could be
             | the only shots that are guaranteed _not_ to hit.
             | 
             | Games want to feel bad at a range of reasonable pings - and
             | reasonable pings usually stretch into the range of 100 or
             | 150 ms - that leads to up to a half a second of lag between
             | when I dodge left and you, as a shooter, would have the
             | earliest chance to actually register a shot with the server
             | at my new position.
             | 
             | Additionally, the server can reconstruct what it thinks we
             | saw at a given moment in time - but the server doesn't know
             | what data has been lost[1] and whether the client might
             | think it was right - or even whether the client might be
             | misreporting dropped packets to engineer an advantageous
             | game state. Also, this whole time we've been discussing
             | latency as if it's a fixed number - but it is constantly
             | changing and the reporting of the latency is something you
             | need to trust to a client since clients can always
             | artificially inflate latency figures.
             | 
             | Due to lag correction either you're able to shoot me
             | _after_ I duck behind cover, or you 're never able to shoot
             | me - and both options suck for one half of the players
             | involved.
             | 
             | 1. See the two generals problem - proof of delivery is
             | actually a _hard_ problem.
        
               | thezilch wrote:
               | You're not speaking to server authority but lag
               | compensation.
               | 
               | Your "behind cover" example describes best your concern
               | with lag comp. It works both ways. You having lower
               | latency can suffer when attempting to take cover.
               | However, you have the advantage when exiting cover; you
               | will see others first.
               | 
               | It's as fair as it can be. As for feel, it definitely
               | feels fairer than no lag comp.
        
               | munk-a wrote:
               | People with a higher ping can only benefit from it if
               | there is lag compensation in place - that said... lag
               | compensation isn't an on-off switch - it makes things
               | unfair to users with that unfairness switching sides
               | depending on how much compensation you offer since higher
               | levels of lag compensation will result in unresponsive
               | "muddy" controls where you may often be teleported back
               | in time to die after locally taking an action you thought
               | compensated for it.
               | 
               | All these factors are pretty heavily interwoven in how
               | the game ends up feeling to players.
        
         | mysterydip wrote:
         | Latency and performance, if you have to wait for the server
         | every time you move or fire. It's a tradeoff which things are
         | client and which are server.
        
         | gameswithgo wrote:
         | there are fun types of gameplay that can't happen without
         | client authority. you can make an aimbot either way so it isn't
         | a huge deal. like you i had a hard time accepting that pubg
         | using client aide hit detection maee any sense, but after
         | playing it a lot and thinking hard about it I changed my mind.
         | That game is all about pixel perfect aiming. Lag compensation
         | wouldn't cut it.
        
         | flohofwoe wrote:
         | One important reason is that P2P games that only require
         | central services for matchmaking but not for the actual
         | gameplay sessions are a lot easier and cheaper to scale to high
         | player counts.
        
         | judge2020 wrote:
         | Maybe if you just have a flat world where you move in any
         | direction with a max speed, but this sort of anti-cheat becomes
         | incredibly difficult once you add features like terrain,
         | physics, vehicles, things like gliders (in BR games), speed
         | boosts, etc. It's possible, but takes a lot more effort.
         | 
         | For example, in Fortnite, if you toggle a lagswitch (as in,
         | block Fortnite UDP for some time), then reconnecting to the
         | server will return you to the same position you were at when
         | you disconnected, assuming you were just trying to run on the
         | ground. However, if you toggle a lagswitch in a vehicle, the
         | servers don't want to do expensive, complicated physics server-
         | sided, so your client becomes authoritative to your position
         | and the sanity checks are simply making sure you're not
         | teleporting around large chunks of the map in seconds. If you
         | were to hack your client and give your vehicle moon gravity,
         | the server generally wouldn't care about that.
        
           | jbluepolarbear wrote:
           | I'm pretty sure the car uses dead reckoning. So you position
           | in the car is static (the last place you where), but the car
           | is moving at speed and will continue even if you disconnect.
        
             | judge2020 wrote:
             | Sure, but I'm talking about the control you have over the
             | car when in the car. During the start of this battle pass
             | season there was immense server issues, which I guessed was
             | the tick rate dropping to super low values due to some bad
             | code. During a few games where the servers degraded in this
             | way, moving would be extremely slow on the ground as it
             | kept pushing you back (since the server isn't processing
             | your 'move forward' commands as often) but getting in a car
             | gave back free movement since I assume it's a direct
             | broadcast that doesn't hit the game loop and doesn't have
             | any position-correcting sanity checks running.
        
               | jbluepolarbear wrote:
               | I'm saying a car is easier to predict because of dead
               | reckoning. With less frequent updates your actions still
               | feel fluid because the cars momentum can't change a whole
               | lot between updates.
               | 
               | Say you're driving a car in a straight line, there's very
               | good odds that in .25 seconds you'll still be going
               | straight so your predicted line will be very close to the
               | real line. With players you can't guarantee that, they
               | could zig zag, turn around, jump, etc much more likely to
               | change and require prediction reconciliation.
        
               | meheleventyone wrote:
               | Cars and vehicles in general are actually much harder
               | because player simulation is much simpler, usually not
               | happening in some middleware physics engine and is much
               | more bounded in terms of the accelerations and speeds
               | involved.
               | 
               | Straightforward extrapolation as with dead reckoning does
               | poorly with both cases.
               | 
               | Then once you've mastered the art of getting cars not
               | looking wonky you have to deal with collisions between
               | them when they're moving at speeds where typical gameplay
               | latencies make it easy for discrepancies between clients
               | to cause mispredictions which result in complete misses
               | or large interpenetrations that physics engines have a
               | bad time with.
        
       | tshaddox wrote:
       | I highly recommend this hour-long video from a Call of Duty
       | developer discussing not only methods they use to transmit game
       | states between client and server, but also some interesting ways
       | that they measure true perceived latency (like using high-speed
       | cameras and LCD monitors to compare true input-to-display
       | latencies between different builds).
       | 
       | https://www.youtube.com/watch?v=EtLHLfNpu84
        
       | ggambetta wrote:
       | Hey, I wrote that thing! Always a pleasant surprise and a weird
       | feeling to open Hacker News (for the 14308560234th time today)
       | and read my name like that :)
        
         | dested wrote:
         | I can't tell you how many times I find myself back on this page
         | while working on multiplayer games. From the bottom of my heart
         | I really can't thank you enough for this tutorial.
        
         | adamrezich wrote:
         | since you're here, it looks like the second paragraph under the
         | second heading in the second article is an unfinished thought
         | :) great work otherwise though!
        
       | nightpool wrote:
       | > Here's the crucial step. Since the server gets all the input
       | with timestamps, it can authoritatively reconstruct the world at
       | any instant in the past. In particular, it can reconstruct the
       | world exactly as it looked like to any client at any point in
       | time.
       | 
       | Isn't there a really obvious exploit here? The client could lie
       | about the timestamps and use that to take advantage of future
       | information in making its decisions. For example, in a simplified
       | fighting game where you have two attacks (top and bottom) and two
       | blocks, it could always choose the perfect block to apply
       | _before_ the opponent attacks--simply by seeing the incoming
       | attack packet, and then immediately sending a block packet with
       | an  "older" timestamp. This doesn't entirely break the concept of
       | an authoritative server, but it seems to diminish it
       | significantly. I know lots of fighting games use this "rollback-
       | type" netcode, maybe they've developed workarounds for this?
        
         | reitzensteinm wrote:
         | This absolutely is a concern with rollback networking (I have
         | done a bunch of games in it).
         | 
         | There are two ways you can cheat. Because you have the full
         | simulation state and input, there is no possible precaution
         | against map hacks.
         | 
         | Some FPS games just won't send exact player positions until the
         | client is about to be able to legitimately observe them. Not
         | possible here.
         | 
         | The other way is, as you say, you can build fake inputs.
         | 
         | To do the timing attack as you describe, all of your input
         | would have to be pretending to be slow. You can't send a t=10
         | I'm idle packet, then a t=8 I blocked.
         | 
         | You'd need a fantastic connection to the server, because the
         | delay you're exploiting is there to protect you from your lag.
         | 
         | Your oponent would also need a fantastic connection, because
         | you aren't seeing their current inputs, you're seeing their
         | past inputs.
         | 
         | My feeling is that it would be very challenging to blend human
         | like behavior with superhuman reflexes when doing automated
         | responses.
         | 
         | But there's nothing you're missing. The attack is definitely
         | possible.
        
       | hesdeadjim wrote:
       | Highly recommend Glen Fiedler's articles for this topic.
       | 
       | https://gafferongames.com/
        
         | jbluepolarbear wrote:
         | I'd also recommend this write up from JMP Waveran (really
         | anything by JMP)
         | 
         | https://mrelusive.com/publications/papers/The-DOOM-III-Netwo...
        
         | lux wrote:
         | His writing has been such a great learning resource. Can't
         | recommend highly enough!
        
       | adamrezich wrote:
       | wow, that interactive example at the end is fantastic and does a
       | great job of visually explaining the concepts of the articles!
        
       | Raphaellll wrote:
       | Another problem of predicting the movement of other players is
       | that if they stop before you can see them, the trajectory would
       | be interpolated further such that you can see them around the
       | corner for a split second, knowing they are waiting there.
        
       ___________________________________________________________________
       (page generated 2021-10-26 23:00 UTC)