I could be wrong also XD but I want to say—server-side checks can feel ping-dependent because the server processes the last known positions of players, which might be slightly outdated if a player has high ping. However, the actual distance calculations themselves aren’t affected by ping—it’s just the data being used (player positions) that can cause discrepancies.
To make it feel more responsive, you can run the initial detection on the client and then validate the tag on the server. This way, the tagging feels instant on the client side, while the server ensures fairness.
I want to say The distance calculations (whether via .Magnitude or bounding box checks) are lightweight mathematical operations that the server is already performing as part of its normal physics and gameplay updates.
- So No Extra Work: By performing calculations like
.Magnitude or bounding box checks, you’re simply using data that the server already has in memory. - No Redundant Data: The server doesn’t fetch new data or perform additional network calls for these calculations—it uses the existing
CFrame or Position properties of the players’ characters.
I really should of used bounding box instead of . magnitude, magnitude is slightly better performance wise if i remember correctly but its negligible if i remember correctly so XD
No worries on the inconvenience, i’d like to give this one more shot at least hopefully this other method fits your desired goals better.
---Client Script local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local TagEvent = ReplicatedStorage:WaitForChild("TagEvent") -- RemoteEvent for tagging local player = Players.LocalPlayer local character = player.Character or player.CharacterAdded:Wait() local humanoidRootPart = character:WaitForChild("HumanoidRootPart") local tagCheckFrequency = 0.1 -- Throttle checks to every 0.1 seconds local hitboxPadding = Vector3.new(1, 1, 1) -- Adjust hitbox size -- Function to check bounding box overlap local function isOverlapping(partA, partB, padding) local sizeA, posA = (partA.Size + padding) / 2, partA.Position local sizeB, posB = (partB.Size + padding) / 2, partB.Position return (math.abs(posA.X - posB.X) <= sizeA.X + sizeB.X) and (math.abs(posA.Y - posB.Y) <= sizeA.Y + sizeB.Y) and (math.abs(posA.Z - posB.Z) <= sizeA.Z + sizeB.Z) end -- Periodic tagging checks while true do for _, otherPlayer in ipairs(Players:GetPlayers()) do if otherPlayer ~= player and otherPlayer.Character then local otherHumanoidRootPart = otherPlayer.Character:FindFirstChild("HumanoidRootPart") if otherHumanoidRootPart and isOverlapping(humanoidRootPart, otherHumanoidRootPart, hitboxPadding) then -- Notify the server of a potential tag TagEvent:FireServer(otherPlayer) end end end task.wait(tagCheckFrequency) end
---SeverScript local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local TagEvent = Instance.new("RemoteEvent", ReplicatedStorage) TagEvent.Name = "TagEvent" local tagCooldown = 1 -- Cooldown in seconds local taggedPlayers = {} local hitboxPadding = Vector3.new(1, 1, 1) -- Ensure server validation matches client padding -- Function to check bounding box overlap local function isOverlapping(partA, partB, padding) local sizeA, posA = (partA.Size + padding) / 2, partA.Position local sizeB, posB = (partB.Size + padding) / 2, partB.Position return (math.abs(posA.X - posB.X) <= sizeA.X + sizeB.X) and (math.abs(posA.Y - posB.Y) <= sizeA.Y + sizeB.Y) and (math.abs(posA.Z - posB.Z) <= sizeA.Z + sizeB.Z) end -- Handle tag requests TagEvent.OnServerEvent:Connect(function(player, targetPlayer) if taggedPlayers[targetPlayer.UserId] then return end -- Check cooldown local character = player.Character local targetCharacter = targetPlayer.Character if character and targetCharacter then local rootPart = character:FindFirstChild("HumanoidRootPart") local targetRootPart = targetCharacter:FindFirstChild("HumanoidRootPart") if rootPart and targetRootPart and isOverlapping(rootPart, targetRootPart, hitboxPadding) then -- Perform tag logic print(player.Name .. " tagged " .. targetPlayer.Name) -- Add cooldown for the tagged player taggedPlayers[targetPlayer.UserId] = true task.delay(tagCooldown, function() taggedPlayers[targetPlayer.UserId] = nil end) end end end)
Enhancements
1. Hitbox Padding
- By adding
Vector3.new(1, 1, 1) to the HumanoidRootPart size in the bounding box check, the hitbox becomes slightly larger to account for animation variations or ping-induced discrepancies.
2. Client-Side Throttling
- The
tagCheckFrequency limits the client-side loop to run every 0.1 seconds instead of every frame. This reduces the load on the client and the number of remote events fired.
3. Client-Server Hybrid Approach
- The client handles the initial detection to make the game feel responsive, while the server validates the tag for accuracy and fairness.
4. Cooldown System
- Prevents multiple tags from being registered in a short period, avoiding abuse or unintended behavior.
5. Server Validation
- The server ensures that only valid tags are registered, protecting against client-side manipulation or false positives.
XD hope this does it, these new enhancements should all bet much better. I can explain why to the best of my ability if it helps.