- Home /
Can't think of a way to get slow moving projectiles to sync across a network.
I have been working on a small top down multiplayer shoot'em up. My problem is that I want my bullets to be slow moving so the standard raycast tricks that are normally used in multiplayer games don't apply in my case.
Normally I would just use a flashy effect on the client when the fire button is pressed and wait for the server to give the actual command to fire but because my game is top down this doesn't disguise anything and the delay is easily visible.
I do have a system for hit detection that is handled by the server but this results in bullets hitting on the server and damaging a player but on the clients screen the bullet was no where near them making it effectively impossible to dodge and results in the player feeling cheated quite frequently.
I know the battlefield series uses a physics based projectile system and it seems to do hit detection on the client and then verify on the server but even with this the projectile would look fine to the client shooting the projectile and it can be fixed on the server to look fine but would still appear very strange on the other clients.
I've been thinking on this for a few weeks now and still have no good solution for it. I keep thinking they do it with the bio gun in the unreal series but that's an fps and I'm not sure if what they did will even be applicable to my game.
Any help with this is greatly appreciated.
Generally you want the client to predict what the server is going to do. Usually these predictions are then kept in a queue, so that when the server sends an update back, the client can see whether it's predictions were accurate, or whether it needs to perform corrections.
On the other clients you can also preform predictions, but of course this is limited to things you already know about and can accurately predict (like projectile physics).
What type of game you have is irrelevant. $$anonymous$$ost projectile based multiplayer games use the same concepts. Just because Quake is an FPS doesn't mean you can't learn from it and apply the same thing to your topdown shooter...
Hi @Benproductions1, what does 'predicting slow moving projectiles' exactly mean in this case? Predicting whether or not the projectile hits something at the moment of fire? Checking if the player is allowed to trigger it when the server receives the request for the client? Predicting the optimal initial flying moving vector or velocity? Predicting (pre-calculating) the trajectory piecewisely by the server tick and checking possibilities if it will hit players (based on players' moving history) throughout its life time? It the last one even possible?
I don't think you really understand what my problem is. Yes there are always things I can learn from other game types but in this case the way they handle things like this in quake/unreal will not work in my game. Those games use a large muzzle-flash/effect to obscure the screen so you as a player don't notice the time between when you pressed the fire button and when the game actually spawned the projectile.
This will not work in a top-down shoot'em up without looking ridiculous. To clarify the problem is when client A fires it predicts the projectile's movement, once the server gets the command it creates the actual projectile and syncs with the client that fired it based on the amount of latency between the server and client A. Then client B receives the RPC call to create the projectile and also syncs its position but client B is predicting its players movement, so even if client A hits client B on client A's screen and on the server, what client B see's is a projectile impact mid air because it hit somewhere in client B's past. So how am I supposed to predict where client B is going to be so I can create an accurate rendering of the projectile on client B's screen?
@StrykerS. I don't think you really read my comment. I already gave advice on how you could do it.
Also, maybe "those games" used a muzzle-flash to hide the effects of latency, but that was around 15 years ago.
To reiterate what has already been said: Use client-side prediction
@StrykerS adding to what you've already been given:
When you press fire you can send the network message to yourself also, rather than creating the bullet locally - this works well with Tasharen Networking, haven't tried it on Unity Networking. The effect here is that all players have the bullet exist in the same network frame so predictions and movement are much easier.
If you need the bullet to issue from an exact point then you can record the network time that the bullet was created and "slightly" accelerate the bullet on the other player's games so it reaches its real position over a few frames (only a few $$anonymous$$d or the ability for the other players to predict its path is impeded).
Answer by StrykerS. · Mar 02, 2014 at 10:52 AM
Okay I finally made my project run adequately and this may not be the best way to do this but I wanted to share my solution so I will be answering my own question. This one will probably be long since my hope is this will almost be a kind of guide for others trying to do something similar.
First I have the server keep track of all players recent locations (this was later changed to make all clients keep track of their own players movement as well). A new entry is created every frame. These entries are modeled after the snapshot system in the source engine. Each snapshot contains a time-stamp (this is server time not local time) and the location of the player at that time.
Now when a player fires a projectile the projectile object is spawned locally and starts it's animation. Then an RPC call is sent to the server which verifies the player can indeed fire the projectile, then another RPC is sent from the server to all other clients telling them to create the projectile. Once created the projectile is moved smoothly over a short period of time to match the current position of the original projectile. This is not perfect currently in my system because the position I'm moving to uses the latency of the last RPC call as part of the interpolation calculation but I think this can be improved upon.
So far the systems above are fairly standard and when I submitted my question all of the systems described thus far had been implemented and it worked fairly well. The only remaining problem was making the projectiles catch up with each clients predicted movements. Without this the projectile would collide with a player on the server but on that players screen it would show the projectile disappear in mid air because each client is predicting their own movement locally.
So my solution was to yes again predict as @Benproductions1 suggest in the comments. To do this I added a time-stamp to the RPC call that instantiates the projectile on the server and other clients, then while calculating the position the projectile needs to move to during the interpolation stage I use the time-stamp on the RPC to look through the players past movements and calculate how much the player has moved since the time-stamp and in what direction, then I add that data into the target position the projectile is about to move to.
This again does not work perfectly as there are still rare circumstances where the projectile might be a bit out of sync with the original but I feel like I can iron this out with some more experimentation and it still works well enough that I can continue development.
Thanks for the comments and suggestions. I hope this helps someone in the future as this one gave me no end of grief.
This is a very good standard solution for projectile and general multiplayer character control. Good answer!
Assu$$anonymous$$g I understand your situation, WhyDo has mentioned the core of the matter:
"record the network time that the bullet was created and "slightly" accelerate the bullet on the other player's games..."
The fundamental problem is you have to make all your bullets/etc slide around in time based on the latest information "be here at time X"
(or ideally like: "at time X, be at such and such, with such and such velocity etc")
as a first rough and for debugging just "snap" the items to those new position/physics at the given time
Once you do that the rest is easy and obvious (so to say!), just send lots of "be here at time X" messages
Fattie, that was not the issue at all. The issue was finding the correct position to move the projectile to. For the client that fired the projectile and the server its a simple matter to predict where the projectile should move to but all the other clients are running input prediction on their local machines so they are 100+ms in the future and their movement can not be predicted by the server. So the real issue was getting the projectiles new position as you say, to be relative to the clients local player.
Hi Stryk!
When you say "The issue was finding the correct position to move the projectile to."
just TBC do you mean, finding the COPOTO$$anonymous$$OTO on (A) the person shooting, (B) the server or (C) the ODP (Other Damned Players)?
Also, sorry if I didn't get this: as you know there are two possibilities: Say you have a game going with four iPads. Then in (server-situation-P1) you can be using a "server server" for your multiplayer game (Hence - that would be SmartFox or the like, or your own custom code, running on a "server" (ie a unix box) on the cloud somewhere.) OR (server-situation-P2), one of the iPads is the "boss" of the game, the "host" of the game, and that's the "server". In Server-P2 there is no Smartfox server or other server involved, only the four iPads and one of those is the game "server" or host.
So for example "PocketTanks" (superb game BTW) uses "Server-Situation-1" for $$anonymous$$P games, whereas, oh, AirHockey ($$anonymous$$P) uses "Server-Situation-2".
{I find this ter$$anonymous$$ology causes confusion! heh. it has often been discussed on here what is the best term for "internet-server-server" versus "boss-host-iPad-server")
Just TBC I don't know whether your "server" situation is "Server-situation-1" or "Server-situation-2".
(TBAC, it makes no difference at all to the logic if you are "Server-situation-1" or "Server-situation-2" .... I'm just curious! Heh.)