Client vs Server Effects

Howdy developers,

Today I come to you seeking advice on some server vs client shenanigans. In my game there will be multiple ‘attack types’, from fireballs to various particles to bullets. Currently however, I’m working on a bullet. I’d like for the bullet to travel smoothly, but I’d also like for the bullet impact/speed to be consistent across all clients. The goal is for the bullet to travel as a beam along 2 attachments up to 100 studs at a rate of 50 studs/second, taking raycasts as it goes and dealing damage to the first player it contacts. Doing this on the Server seems to make the bullet look a little laggy, but doing this strictly on the client could lead to lag/hacking issues too. What would you recommend doing in this case?


obligatory image

And sticking with the theme, what would you recommend for future ‘attack moves’ that may be in my game? Should I do hit detection for melee attacks on the server or the client? Should the effect of a ‘wave of flames’ for example be server or client? My goal is to make the game look as smooth and crisp as possible, but also to keep it consistent across all clients.

I appreciate any and all responses!

4 Likes

There are several different methods you can implement, depending on whichever one you think is best for your game.

For most methods, you wanna have separate code that controls the visuals of the bullet for all of the clients vs code that controls the hit detection on the server. What you’ll have to think about is how you want to have the server validate the bullet firing and make sure nobody is cheating. One possibility:

  1. Client tells server I want to fire a bullet in this direction
  2. Server tells clients to show the bullet for all other clients based on those initial conditions
  3. Then you can either have the server determine who if anybody takes damage, or have the client determine who takes damage, then just have the server determine whether or not the shot was possible and made sense.

You can look up “multiplayer gun interpolation” to see how other games handle this problem. There is never a 100% perfect solution, because of the nature of the internet and the delay between machines, but you can get pretty close.

3 Likes

Visuals should be always be on the client, the main issue isn’t exploiting rather it should be syncing all the clients together. Since I don’t really bother with syncing the server and clients much I’m not sure how I would approach that, but if you manage to somehow obtain a way to get the delay time to get to the client or is able to almost sync the clients and servers then this would be quite simple.

Assuming you’ve figured out how to synchronize the server and clients, the actual hit box should be a progressive raycast using os.clock() for precision, with this no matter how much exploiters tinker with the bullet it wouldn’t matter since the server is handling it. The bullet should spawn on the clients and if you figure out the delay you can spawn the bullet further away (to be in sync) with the server hitbox. The bullet should definitely be done on the client.

In my personal opinion, if you don’t plan having anti cheats to speed hacking or teleportation then just do it on the client because exploiters could just teleport instead, if you do plan having an anti cheat it’d be best to do it on the server in sacrifice for the delay.

Overall, the issue is mainly having synchronized timing across the clients, try to find out how to long it took for the client to receive the signal (on the client) to position the bullet.

One method I can come up with right off of my head is when input occurs, cache os.clock() where accessible for the local script that handles the bullet visuals. You can then compare os.clock() the cached os.clock() (assuming you :FireServer() then :FireAllClients()) to get a rough estimate of how long it took to come back to the client. Of course, this would only work for the local client firing the projectile.

EDIT: One more option is just to disregard potential latency, If I were a player with high ping I wouldn’t be expecting the game to be functioning well with my internet.

4 Likes

Hello!

I would try setting the Setting the Network owner Tom the client who made it. (As it’s that person who is going to see it most)

Also I would recommend Tweening there is a lot of modules that can do cross replicated tweening. eg. That the server send a request to the client to do the tween instead of the server.

1 Like

So, this is a great question and a great example of server/client shenanagons. Here are some different conclusions and answers:

  1. We don’t care what the client does with the visual bullet but the bullet hit must be protected.
    • Effect on client, Process shot on server.
  2. We care about protecting the visual bullet & bullet hit but don’t care about slight lag.
    • Process both on server.
  3. We care about removing visual lag but protecting visual and hit.
    • Process both on server as well as visual on client (requires deleting server visual on client).

Note: You can always process stuff on the client if you’re happy writing complex sanity checks on the server - This is done (from my understanding) on games like Phantom forces where it’s processed on both, reads client result, compares to server - if it’s acceptable/possible accepts.

1 Like

Here is what I normally like to do.

Send over bullet trajectory & other stuff too server, along with visualize the bullet here. (If it’s a FPS game then calculating if it hit or not can also be done here, after it’s been sent too the server, can’t spend all day waiting for the bullet to calculate after all/)

The server then scans over the information too see if it’s legit, if it is then they send it over for all the other clients too visualize.

Other clients pick it up and visualize it.

With slower-moving projectiles, like fireballs, you will definitely want too implement a clock system too make sure the visuals line up across the player server boundary. You’ll also probably want too not have the owner process the visuals until the server has checked because then there will be de-syncing.

Fast paced fps games, speed is key (you don’t want your players getting bored or frustrated), slower games, having the server do more of the work will avoid hackers.

(Interesting that your not working on fixing overcast’s major issue.)

My game uses a hobbled-together system adapted overtop of a terribly-written base that uses actual parts and .Touched events for hit detection, and even it seems pretty good with the ol’ “send the shot direction to clients” method:

Client requests the shot. The firing client simulates its own projectile for visual feedback purposes. The server processes and validates the client’s request, then sends out the ray and projectile type data to the non-firing clients. The other clients then produce their own projectiles for visual effect.

The effect works for high-speed projectiles. For slower projectiles, or if targets themselves are very fast, you would need a system to synchronize time keeping between clients and the server. Once synchronized, you can interpolate shots from where the client generates them to where they should be at the time the client is rendering them. This technically means that the projectile will be moving at a variable rate for however long your interpolation period is, but it will sync things up.

Ultimately, though, if it still looks like players hit their target, complicated interpolation isn’t really necessary. Running the effects on the client should smooth out any visual jitter.