Hello!
In my game, Mini Cup, there are around 16 players in game. They are divided into 4 teams of 4 and play soccer against each other in turns. And in like any soccer (football) game, they try to kick the ball into the oppositions net.
However it is hard to play with much precision because the latency makes it so that the opposing players look far away from the ball when they kick it, when in reality, on their end of the game, on their screen, they are already touching the ball. But to you, you are actually closer to the ball and they are still miles away.
On the other hand, when you kick the ball, it takes a while before the server actually received the input and performs the kick.
If you play one match in this game you will see the issue yourself:
So now my issue is how do I fix this?
I’ve been trying for months but have come to no solution.
(I’ve changed velocity types, added a cooldown, set network owner to nil
and everything I’ve heard of)
This is the current server script which is parented to the ball and is replicated from ServerStorage to the Workspace as needed.
local Players = game:GetService("Players") -- Get the Players service
local Debris = game:GetService("Debris") -- Get the Debris service
local Ball = script.Parent -- Get the ball object
local KickSound = Ball:WaitForChild("Kick") -- Get the kick sound
local bounce = false -- Set a flag to prevent multiple touches from being registered
local gameModule = require(game.ServerStorage.Modules.GameModule)
Ball.Touched:Connect(function(t) -- Connect to the Touched event on the ball
if t.Name == "PlayerHitBox" then
local character = t.Parent -- Get the character that touched the ball
if not character then return end -- If there is no character, return
local player = Players:GetPlayerFromCharacter(character) -- Get the player associated with the character
local humanoid = character:FindFirstChildOfClass("Humanoid") -- Get the humanoid of the character
local rootPart = character:FindFirstChild("HumanoidRootPart") -- Get the root part of the character
if not player or not humanoid or humanoid.Health <= 0 or not rootPart then return end -- If any of these are missing or the character is not alive, return
local ballVelocity = Ball.AssemblyLinearVelocity -- Check if the ball already has a velocity
if bounce == false and not player:GetAttribute("kicked") then -- If the flag is set and no other touches have been registered
player:SetAttribute("kicked", true)
print("Bounce is true")
bounce = true -- Set the bounce flag to prevent further touches from being registered
local direction = rootPart.CFrame.LookVector -- Get the direction the character is facing
if direction.Magnitude < 0.001 then return end -- If the direction is very small, return
Ball:SetNetworkOwner()
local kickForce = humanoid.WalkSpeed -- Get the character's walk speed
Ball.AssemblyLinearVelocity = (direction.Unit * kickForce * 1.95) + Vector3.new(0, kickForce * 1.15, 0) -- Set the velocity of the ball based on the direction and walk speed of the character
KickSound:Play() -- Play the kick sound
-- Set the attributes for the last and second-to-last player to touch the ball
if Ball:GetAttribute('LastTouch') ~= nil then
if Ball:GetAttribute('LastTouch') ~= player.Name then
local previousTouch = Ball:GetAttribute('LastTouch')
Ball:SetAttribute('LastTouch', player.Name)
Ball:SetAttribute('SecondTouch', previousTouch)
else
-- Do nothing if the current player is the same as the last player to touch the ball
end
else
Ball:SetAttribute('LastTouch', player.Name)
end
print("Sending For KickTimer")
gameModule.kickTimer(player)
print("Kicktimer Returned")
task.wait(0.6) -- Wait for 1/2 second
print("Debounce is false")
bounce = false -- Reset the bounce flag to allow for future touches to be registered
-- Increment the touch count for the player's team in the "Standings" folder
local teamName = player:GetAttribute('TeamName')
if game.ServerStorage.GameFolder.Standings:FindFirstChild(teamName) ~= nil and game.ServerStorage.GameFolder.Standings:FindFirstChild(teamName):GetAttribute("Touches") ~= nil then
game.ServerStorage.GameFolder.Standings:FindFirstChild(teamName):SetAttribute('Touches', game.ServerStorage.GameFolder.Standings:FindFirstChild(teamName):GetAttribute('Touches') + 1)
end
end
end
end)
At this point I think it requires an advance solution which I do not have the knowledge to implement. Any ideas or answers would help greatly!
I am also willing to hire an expert who can solve (or at least greatly remedy) the issue as a one time commission.