So i’ve made a little setup for an FPS game, but the client-side and server-side bullets almost never seem to be in the right place. The server’s bullet is always a little behind the client’s bullet even when running on a local dedicated server.
Just curious if i’m doing something wrong or not, because if someone has a ping or like 4(which is what i’m getting on a local dedicated server) there shouldn’t really be a difference.
Here’s the basic blueprint for shooting.
Client shoots and +Fire is called on the server and they both execute the same code that does a line-trace using the controller’s rotation and the camera’s position and hits something. Very simple and straight forward code.
But this is the result while strafing.
Am i missing something is the server’s +fire supposed to have some sort of delay based on something? This also gets really bad if you flick and shoot, both the server and client are running at 90fps/ticks so… i’m kinda stumped and i don’t want to do something like send location and rotation of the shot with every bullet fired, because that seems like a massive waste of bandwidth, not to mention the cheating possibilities.
Red: server
Blue: Client
Strafing Right
So the server’s event gets called early or something, or the player’s position on the server is not in-line with the client which on a local server really shouldn’t be the case.
For firing, I think it’s handled by first firing on the local client and then passing the location and direction of the local fire to the server through an RPC. Then using that information on the server’s fire. The client and server are probably not going to be in sync if you’re moving so you need to make sure the bullet also fires from the same location and direction on the server.
Well i’m replicating inputs rather than exact position and rotation of the shot being fired. Mostly from source modding usually call a +fire input and it replicates the input to the server and back, but maybe with unreal i need to come up with a better replication method. Though sending the server every shot fired seems like a bit of a waste of bandwidth, but i’ll just have to do that for the time being until i figure out a solid way of replicating inputs.
Right now it replicates the input and the server AND client both run the code ‘at the same time’ and when the client sends a hit registry, the server checks it’s own data to validate it, but a lot of my calls are not being validated because of this weird delay or whatever is happening that the server’s shot it trailing behind the client. My thought sofar is that axis inputs trail behind a little on the server, but with a local server that has like 4ms it really shouldn’t be that big of a difference. So meh, for the time i’ll just waste bandwidth and send position/rotation of the controller with every shot being fired (which is a lot with automatic weapons having more than 900 shots per second for some) but i guess i’ll bite the bullet for this one and waste some bandwidth while the project is still a prototype.
So I ended up doing this:
Basically every time the client files a projectile, it tells the server and it does it on it’s end also and does some very basic checks to legitimize the shot, before multicasting it to everyone else. let me know if there’s a better way to do this. Because sending info on every shot from the client seems a little wasteful to me, but maybe that’s the way it has to be, in order to get accurate shots.
I use server authoritive hit detection. on the client when the player fires a bullet weapon, i run the muzzle flash, recoil, sound fire effects and then tell the server that the local player started firing as well as a timestamp (that is a replicated float sent from server to client) of when the player started. This timestamp is compared with the timestamp on the server to see how far behind the client staryed firing. On the server, I have a trail of capsule component which follow the character which pick up the delay and validate clients actual hit. So i dont have to replay events backward.