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.