Best way to handle ball mechanics to prevent lag in a mulitplayer game?

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)

Thanks in advance for your help!

1 Like

Hey! Here’s what I suggest: if the player already has ownership of the ball, you don’t have to keep spamming :SetNetworkOwner() for that player.

local currentowner = ball:GetNetworkOwner()
if currentowner ~= nearestplayer then
   ball:SetNetworkOwner(nearestPlayer)
end

Does your output show any error? I use the same script for my hockey game and never had any issue with it.

2 Likes

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.

Is the “ball” part welded to another part? Is it part of a model?

As for your question, I used it for the exact same reason you did (nearest player gets ownership of the puck).

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.

Yes, it is welded to another part of the object itself. Does this have an effect on performance?

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.

1 Like

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.

wasent aware this topic was solved, sorry

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.