I stumbled upon this problem when creating Combat with Client-side Prediction. So in my game you have Client hit registration and Server hit registration.
I’m trying to calculate the HumanoidRootPart’s position on the Server from the Client.
I’ve attempted from creating a part on the Server set the CFrame of that Part to the HumanoidRootPart in a HeartBeat and when that gets replicated to the client it’ll show the ping delayed version of their HumanoidRootPart, but that wasnt reliant. It tend to be inaccurate.
I also made it one on the client where it created a Part and a Heartbeat function it’d task.wait(oneWayPing) (player:GetNetworkPing()) before setting the Part.CFrame to the HumanoidRootPart.CFrame
In this video, Damage is Server, Hit Effects are Client.
Remember there are two Hit Registrations, Client and Server.
Client focuses on Hit Effects (Blood)
Server focuses on Damage.
The first two hits are registered on the server, but not on the client. This is because the Client backed up and it didn’t update to the server in time.
Since I have moved back on the Client the Server doesn’t see this because of lag. It does the damage but because the client backed up in a split second, it doesn’t register effects on client.
The way to sync these two is the Client predicting it’s position on the server and uses that for Hit Effects.
The solution I’m trying to find is calculating HumanoidRootPart.CFrame on the Server using the Client and ping.
My reply might not fully answer your question but I’m giving it a shot. I understand you’re trying to predict the client’s position on the server so you can accurately display client-side effects, such as blood from the sword impact, but why do it like that?
Maybe I’m thinking too simple here, but couldn’t you just tell the client via RemoteEvent when they’ve successfully hit something then do the effects based on the received event?
They would have a delayed response. This is with using Events
The client side prediction reduces the delay by half. So what you see is a reduced version of the delay because the client-side prediction will compensate a little bit for it.
This is with using Client-side Prediction
My inputs have Client-side Prediction so when I click it doesn’t have a delay it does it instantly, same as the effects.
Here is with no Delay Compensation for Hit Registration
Tried making a script; looks like it works but I’m not sure. I multiplied GetNetworkPing by 2 because it was returning half of the ping displayed in the F3 menu but I don’t know if that was necessary. Local script parented to StarterCharacterScripts
local runService = game:GetService("RunService")
local player = game:GetService("Players").LocalPlayer
local humanoidRootPart = script.Parent:WaitForChild("HumanoidRootPart")
local predictionPart = humanoidRootPart:Clone()
predictionPart.Transparency = 0.5
predictionPart.Anchored = true
predictionPart.CanCollide = false
predictionPart:ClearAllChildren()
predictionPart.Name = "PredictionPart"
predictionPart.Parent = script.Parent
runService.RenderStepped:Connect(function()
local pingInSeconds = player:GetNetworkPing() * 2
local predictedPosition = humanoidRootPart.Position + humanoidRootPart.AssemblyLinearVelocity * pingInSeconds
local predictedOrientation = humanoidRootPart.Orientation + humanoidRootPart.AssemblyAngularVelocity * pingInSeconds
predictionPart.CFrame = CFrame.new(predictedPosition) * CFrame.Angles(math.rad(predictedOrientation.X), math.rad(predictedOrientation.Y), math.rad(predictedOrientation.Z))
end)
The script predicts where the player will be based on the ping by utilizing the velocity of the player multiplied by the ping in seconds. If the player has a ping of 1000ms (1 second) and a walkspeed of 16 studs/second, the predicted position will be 16 studs in the direction the player is walking because that’s the theoretical distance they will move in 1 second. This isn’t entirely reliable due to many factors. The script has no way of knowing if the player will stop going in that direction, whether or not any physical obstacles are in the way, or if something else changes their position on the server such as the player being knocked in a different direction.
That’s a good attempt. This script you made predicts where you will be in the future based on your ping. Not where you are currently on the Server. The client is always ahead, so the prediction should be behind you instead of in front.
It should look something similar to this, but this isn’t reliant.
In the video it predicts where you are on the Server, but not reliant. If the user’s ping is too high it is totally off prediction.
It uses Client-side Prediction, so the combat runs parallel on the Server and Client.
Hitboxes are Calculated on the Server and Client. Server focuses on damage, Client focuses on visual effects. Unreliable events would have delayed feedback on high ping players. As seen from a clip above.
The Client and Server are not meant to talk to each other as much. When they do it’s correction and rollback. Here is the Server and Client shared code
They would have to not talk to each other using events as soon as the server registers a hit. If they did it would provide significant delay. So they would have to predict each other.
function SwordCore:_registerHit(settings)
local character = self.Character
local humanoidRootPart: Part = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
settings = settings or {
Radius = 9.5,
Angle = math.rad(150),
RadiusAngleDecay = 1.05
}
local radius = settings.Radius
local dotProductAngle = mathCos(settings.Angle)
local humanoidRootPartCFrame = humanoidRootPart.CFrame
local originPosition, lookVector = humanoidRootPartCFrame.Position, humanoidRootPartCFrame.LookVector
local dotProduct = lookVector.Dot
local characters = collectionService:GetTagged("Character")
local radiusAngleDecay = settings.RadiusAngleDecay
local targets = {}
for i = 1, #characters do
local target = characters[i]
if target == character then continue end
local targetHumanoidRootPart = target:FindFirstChild("HumanoidRootPart")
if targetHumanoidRootPart then
local difference = (targetHumanoidRootPart.Position - originPosition)
local distance = difference.Magnitude
if distance < radius then
local targetProduct = dotProduct(lookVector, difference.Unit)
if targetProduct > dotProductAngle and distance < radius/(mathAcos(targetProduct) * radiusAngleDecay) then
targets[#targets + 1] = target
end
end
end
end
if #targets > 0 then
if isServer then
self:_damageTargets(targets, 15)
else
VisualEffects.Character:Emit("SwordBleed", targets, self.Sounds.Hit)
VisualEffects.Character:PlayAnimation(targets, self.Animations.Hit)
end
end
end
end
What the combat input (similar) looks like as a flowchart from Netcode - Wikipedia
Would this be okay? Also the particles might be delayed because I’m bad at making particles. robloxapp-20240702-1027024.wmv (387.8 KB)
(sorry for bad quality and incorrect format)
Also here’s the file if you want to see it. I rushed it so it’s not really organized. Basically I did client (input) → server which used a raycast hitbox module → client (effects) SwordTest.rbxl (98.0 KB)
This goes against Client-side Prediction Netcode. What you made is a problem that every game has.
Input’s should not be processed through the server.
These clips both have players on 2000 ping (2 seconds lag)
This is an example of the same technique you used but on High Ping
This is an example using Client-side Prediction to fix this issue
The problem I’m trying to solve is getting the HumanoidRootPart’s CFrame on the Server using the Client. The Client has to predict where It is on the Server which is ping second behind it’s actual character. It’s networking that i’m trying to solve.
Can you show an example when you’re actually hitting something? The videos are just showing the animations which can just be moved to the client. I see what you mean though, sorry for the misunderstanding.
The problem is that the Client and Server have differentHumanoidRootPart positions, this is because it takes times to send information from Client to Server (Network Ownership)
The Client backed up, before it registered the hit. So it didnt play the effects. The Server didn’t get the memo in timeso it registered the hit and did the damage.
You cannot use ordinary Event’s to address this issue, because they take time to send messages.
This here is an example using Events (Half Server Combat)
This here is an example using Client-side Prediction (Netcode) [Parallel Server and Client Combat]
The problem is in the First clip where when you move too much on the client, the server is delayed and doesn’t get the memo of the character movement in time.
Both players have 100+ ping, but are still synced with no delay. This is because of Client-side Prediction. The Hitboxes are inaccurate because they are calculated on the Server and Client (Client-side Prediction) The Client moves their humanoidrootpart in that 0.1 second time frame. The server within that 0.1 second time frame, hasnt seen the client moved yet because of their ping. It takes time to send information. So the problem is that the Client needs to predict where it is on the server.
I don’t think you understand. The Combat is mainly Client. If you modify the Server it wont change the clients, unless the Server fires events to update its client to the server (Server Reconciliation). If an exploiter were to exploit the client combat, they cannot because the server will not tell the other clients to update their screens.
There’s two combat classes. Client (You) and Server (Server) If you do something on the client, it’ll do it on the client. then send a message to the server while your still doing it. If you’re not allowed to then it’ll revert that movement. If you are the Server will try to copy and sync with you. This helps people with high ping. The combat CANNOT be exploited because if you try to do something your not, YOU have the copy of the server’s combat. So if the server tries to copy you but it cannot because of some arguments. Then it’ll revert you.
You don’t see this type of combat in other games because it is difficult to implement.
High difficulty, high reward.
I remind again, its client based combat with server validation (CLIENT SIDE PREDICTION) (NETCODE)
IT IS A NETWORKING ISSUE NOT A SKILL ISSUE (IM A VERY EXPERIENCED DEVELOPER)
All animations are already client-sided. Nothing you see is Server-sided. The server hides everything and only validates information. Mainly because it is (CLIENT-SIDE PREDICTION)
I repeat CLIENT-SIDE PREDICTION. There Server only validates information because that’s the most optimized thing it can do. The other clients worry about syncing and visuals.
I remind, you cannot use ordinary server combat code (What every game uses, IT DOESNT BENEFIT HIGH PING/LAG PLAYERS)
I have custom animation replication. So if an exploiter were to play an animation without permission it gets blocked by the other clients NOT THE SERVER other clients. It doesn’t get blocked by the server because it can be used for Anti-cheat/Punishment/Flagging
Almost every game uses Server-based combat. Mine uses Client-side prediction, this helps players with high ping not feel like they are on high ping. Very big companies use this technique such as Triple A Games (AAA).
Server-based combat means, animations is played on the server, server controls and does calculations while the client only sends inputs.
Client-side Prediction is where when the Combat is both ran on the Server and Client and they will sync each other up. If the client Attacks, the server validates then Attacks (Not shown) then sends other clients to Attack on their screen and sync.
What’s the latency of the client? If I’m reading things correctly, it seems most of the clips are taken with 400+ ping, which honestly, I think is a lost cause.