How do i fix this client-server issue

I have an enemy NPC in my game, but on server it is a lot closer than it is on client, leading to random hits (hitbox is red part, FYI)


(if video doesnt appear: https://www.youtube.com/watch?v=y25cawiNZn8)

what do i do the fix the client-server issue

4 Likes

I want to say NetworkOwnership can play a role here, but I wouldn’t have expected it to cause a desync in rendering.. :thinking:

Assuming youre handling the NPC on the server, make sure that when it spawns you set the network ownership of all parts under the rig to nil so the server stays in control.

On the client, just make sure its not doing anything to the npc rig. If the client welds or created anything under the rig it may cause the rendering desync unless you made sure it has no way of interferring with the rig physics (i.e, you made anything the client created massless).

1 Like

I changed the code to constantly set the network ownership to nil, same result though.

Or is there something wrong with my code? Theres no errors AFAIK.

task.wait(3) -- makes sure parts are loaded, player shouldn't get to the enemy this fast anyway
const parts = script.Parent:GetDescendants() -- const so it doesnt change.

game.RunService.Stepped:Connect(function()
	for _,part in pairs(parts) do
		if part:IsA("BasePart") then
			part:SetNetworkOwner(nil)
		end
	end
end)

I used print(parts) and it worked, also.

Hey, please do not add the for loops inside of RunService, this is why your hitbox system isn’t quite working.

-- Removed the unnecessary RunService.
for _, part in parts do
	if part:IsA("BasePart") then
		part:SetNetworkOwner(nil);
	end;
end;

I hope that this solves the issue that you currently have.

still doesn’t work.

plus, it’s not like your using correct syntax either. Semicolons after every line? Really?

Not really, semi-colons are optional and they are a correct syntax, the compiler would ignore the semi-colons. These are just my personal preference.

Have you received any errors in the console?

if you turn the red hitbox into a distance check instead (or do a distance check when the player touches the hitbox on the server), then you could grab the ping of the user and add it to the distance between the player and the npc. saying this because i assume the issue is that there is a delay between the replication on the server to the client and vice-versa.

Still no. THe only errors are from unreleated scripts(i need to fix those, but i know how)

this happens likely because of server client desynchronization because i have experienced this in many roblox games and its probably caused by slow internet

Instead of setting every part to the server, just set the HumanoidRootPart to NetworkOwner.

Hopefully, that should fix the problem.

Setting the NPC’s network owner to the player will allow exploiters to freely move them however they like so be careful when doing that

Still didn’t fix it, I’m afraid :downcast_face_with_sweat:

Hello, this is cause by ping! Games fix this by making the NetworkOwner of the chasing enemy be the players that they are chasing. Hope this helps☕

This is not a network ownership issue, assuming you have normal character controls and the NPC uses MoveTo(). This is just normal client-server desync as others have explained…

In any Roblox game, other players you see on your screen are actually in the past due to ping since it takes time for the client’s position to replicate to the server then to other players. In your case, let’s say you have a 20ms ping, the server will see your position 20ms in the past, which explains why on the left side of your video, you’re actually closer to the NPC and thus taking damage.

Understanding the client-server model really helps with this. And this is one issue that Server Authority aims to fix using client prediction.

You can take a look at this video to understand more: https://www.youtube.com/watch?v=dYLzEeSxQ8k

Solution

The easiest way is to use magnitude checks (which you can manually adjust to account for ping, or calculate the player’s ping and adjust the final value). This is what a simple magnitude check looks like:

local DAMAGE_RADIUS = 7 -- how far from the npc players will start taking damage from

local magnitude = (plrHrp.Position - npcHrp.Position).Magnitude
if magnitude >= DAMAGE_RADIUS then
    -- use trig to calculate if the player is in front of the npc
    -- take damage
end

Also one tip: Don’t use Touched events for detecting moving objects - it will most likely always have a delay due to client-server replication.

1 Like

Sorry for late reply, but wouldn’t it be magnitude <= DAMAGE_RADIUS rather than magnitude >= DAMAGE_RADIUS

also i dont know triginometry

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