I’m in need of some help with preventing lag spikes in my multiplayer game. I have been working on this issue for some time now, and have tried various methods to no avail. I have a previous post regarding this issue, but it seems that I am still struggling to find a solution.
The issue that I am dealing with is that when players hit the ball, it doesn’t match up across all players. This results in players experiencing lag and a poor overall gameplay experience. I have tried a few different methods to fix this issue, but they all seem to generate more lag instead of preventing it.
First, I tried using SetNetworkOwnershipAuto, but this causes lags and is not a viable solution. I also tried giving the ball network ownership to the server, but this also generates lag and is not the solution. I even tried the solution provided in this post (Lag spikes in multiplayer game with physics using SetNetworkOwnershipAuto), but it generates the same amount of lag as the other methods, if not more.
I have provided a script and a video demonstration of the issue that I am dealing with. The script is the one I am currently using, and the video shows the problem in action. I’m hoping that someone here can help me find a solution to this problem, as it is greatly affecting the overall gameplay experience for my players.
local ball = script.Parent
local rs = game:GetService("RunService")
local players = game:GetService("Players")
local maxDistance = 10
rs.Heartbeat:Connect(function(step)
local nearestPlayer, nearestDistance
for _, player in pairs(players:GetPlayers()) do
local character = player.Character
local distance = player:DistanceFromCharacter(ball.Position)
if not character or
distance > maxDistance or
(nearestDistance and distance >= nearestDistance)
then
continue
end
nearestDistance = distance
nearestPlayer = player
end
if nearestPlayer then
ball:SetNetworkOwner(nearestPlayer)
else
ball:SetNetworkOwner(nil)
end
task.wait()
end)
That could be a solution. Did you use it for another script or something similar to this one? I doubt that my script with this will make any difference other than improving performance, the lag should probably still be present.
Furthermore, when the ´SetNetworkOwner´ function is executed, the client must send a request to the server, which would, from what I can see without testing, increase the lag.
You want the server to always have network ownership of the ball. Let each client interact with the ball, but ultimately make the server decide where the ball will go.
I don’t know too much about networking, but I’d highly recommend looking into how rocket league’s networking works. There’s a good chunk of this video (23:35-45:00) where it talks about how rocket league handles inputs from multiple clients and dealing with network lag.
Okay, I see. However, when I tried this, it still resulted in lag. I’ll watch the video you provided and see if I can think of a solotion. But even so, I believe it would be difficult to replicate what Rocket League has done in a Roblox game.
After watching the video @cartler recommended, I’ve come to the conclusion that implementing netcode and prediction for a game can be quite challenging. The concept of network management has become broader and more open, making it difficult to fully understand the best methods for implementation.
Netcode delay & Prediction
In order to ensure that actions replicate correctly on clients, the server must act as an unbiased entity. This means that the only thing limiting performance is the player’s ping to the server. To further combat lag, we can use prediction to anticipate the movement of the ball based on the physics of the player and the ball.
Limits & Desync
However, there are limits to how much the server can predict the client’s actions. For example, while it’s possible to predict that a player will continue jumping, running, or moving in a specific direction, it’s not possible to predict when a player will suddenly stop moving or make rapid changes in movement. This can result in desync, where the client’s state becomes out of sync with the server’s prediction.
Overall, while implementing netcode and prediction can be challenging, it’s important to keep in mind the limitations and potential for desync. If anyone has any ideas or methods for implementing these features in the game I mentioned, I would greatly appreciate your input.
Do you think the other part of object gets the network ownership too? If your ball is a model, then I’d suggest using the following function:
function setNetworkOwnerOfModel(model, networkOwner)
for _, descendant in pairs(model:GetDescendants()) do
-- Go through each part of the model
if descendant:IsA("BasePart") then
-- Setting the network owner
local success, errorReason = descendant:CanSetNetworkOwnership()
if success then
descendant:SetNetworkOwner(networkOwner)
else
error(errorReason)
end
end
end
end
setNetworkOwnerOfModel(ball, nearestPlayer) -- (ball, nil) for Server network ownership
This is the script I use to change the network ownership of Models.
I figured I’d just use the built-in physics system, but that’s not the best viable option. I still believe it would be better if you use the suggestion I made.