This is actually a pretty good solution, but it is still vulnerable to exploiters.
I’ll just do some testing on my own later today and see if I can find one of my past projects. If I do I’ll let you know.
Hey, I’m having the same issue with the same module. I’ll put this conversation at watching because I REALLY need solutions to this.
Just so you know, I’m working on this as I speak. Sorry it took me a few days to get to it, I had to deal with other stuff in life. Nevertheless, this problem is sort of fun. It’s a break from the usual problems I deal with. Anyways, I have done some initial testing, and I should have a solution later tonight. It turns out I was on the right track earlier when I provided the getPathfindPoint
function, but I took a wrong turn, as well as I didn’t account for the actual latency between the client and server.
I’ll post in an hour or two with the actual solution. Just know that with it, it will definitely require you to centralize your system. However, it can also be done with a single script in a character for demonstration purposes.
EDIT: Never mind, it’s going to be until tomorrow until I complete this. I decided to go the perfectionist route and create a new module that has functionality above what is required to make this work. Oh well.
I’m having this issue as well. I’m beginning to think this is an engine bug…
It’s not an engine bug, It’s caused by latency between the client and the server. The problem doesn’t show up in studio unless you go to the network settings in the studio settings tab and set the incoming replication lag to something above 0.
Also, just updating to let everyone else know I’m still working on this. The problem turned out to be a bit more complex, but I’m on the right path now and can get the NPC within 2-3 studs of the player. I should have it completed either today or tomorrow.
EDIT: I am now able to predict the position of the player rather accurately whenever the player walks in a straight line. However, I am dealing with an issue whenever they are turning. So now I’m modeling the player walk path along a curve, something I’ve never done before. This may take a few more days.
Alright, I’ve completed my testing. I’ll update this reply later with the finished product. As for now, all I can say is this. I’ve found a method for predicting the future position of the player, but it only works with low latency/ping. If the player has a relatively high ping (around/above 100) there is no reliable way to predict their current position. The latency is just too great. With that said, it should still work with those of a lower ping.
This solution isn’t bad, just beware that giving network ownership of the character models to the player will allow them to do anything physics related to their body and it will replicate.
E.g WalkSpeed and JumpPower.
Now I’m no like genius I’m just trying to put in an effort or attempt to help
But really the latency happening is the functions you have, although yes run and execution time of the functions still happen very fast
I didn’t make very hard changes, just some I feel like would improve
local RS = game:GetService("ReplicatedStorage")
local SS = game:GetService("ServerStorage")
local SP = require(SS:WaitForChild("SimplePath"))
local sprinter = script.Parent
local hum = sprinter:WaitForChild("Humanoid")
local HRP = sprinter:WaitForChild("HumanoidRootPart")
local path = SP.new(sprinter)
path.Visualize = true
local names = {}
for _, name in pairs(RS:WaitForChild("Enemies"):GetChildren()) do
table.insert(names, name.Name)
end
sprinter.PrimaryPart:SetNetworkOwner(nil)
local Target
local Blocked = true
local Distance
function findTarget()
local aggro = 200
local ThisTarget = nil
local ThisBlock = true
for _, character in pairs(workspace:GetChildren()) do
local human = character:FindFirstChild("Humanoid")
local RP = character:FindFirstChild("HumanoidRootPart")
if human and RP and human.Health > 0 and not table.find(names,RP.Parent.Name) then
local dist = (RP.Position - HRP.Position).Magnitude
if dist < aggro then
aggro = dist
ThisTarget = RP
local rayInfo = RaycastParams.new()
rayInfo.FilterType = Enum.RaycastFilterType.Blacklist
rayInfo.FilterDescendantsInstances = sprinter:GetChildren()
local hit = workspace:Raycast(HRP.Position, (RP.Position - HRP.Position).Unit * 200, rayInfo)
if hit.Instance == RP then
ThisBlock = false
end
end
end
end
Target = ThisTarget
Distance = (ThisTarget ~= nil and aggro) or nil
Blocked = (ThisTarget ~= nil and ThisBlock) or nil
end
function getPathfindingPosition(agent, target)
local agentPos = agent:GetPivot().Position
local targetPos = target:GetPivot().Position
local direction = (agentPos - targetPos)
local distance = direction.Magnitude
if distance < 5 then
local result = workspace:Raycast(targetPos, direction)
return if result then result.Position else (targetPos + direction)
elseif distance < 10 then
local humanoid = target.Parent.Humanoid
direction = (humanoid.MoveDirection*humanoid.WalkSpeed)
local result = workspace:Raycast(targetPos, direction)
return if result then result.Position else (targetPos + direction)
else
return targetPos
end
end
game:GetService("RunService").Heartbeat:Connect(function()
coroutine.resume(coroutine.create(function()
findTarget()
end))
if Target then
if not Blocked then
print("not blocked")
hum:MoveTo(getPathfindingPosition(sprinter, target), workspace.Terrain)
elseif Blocked then
path:Run(getPathfindingPosition(sprinter, target))
end
end
end)
You could give this try, obviously keep the code you have currently, as this is only just trial and error at this point and having older versions could lead to a solution
I also recommend maybe
when it does hum:MoveTo()
to just take the Target and do
local cf = Target.CFrame*CFrame.new(0,0,-3)
hum:MoveTo(cf.Position)
Just a heads up, I’m still experiencing issues with this. I’ve been keeping an eye on the thread for the past few weeks but haven’t posted because I’ve been out of town. I’m aware @BuilderBob25620 is working on something but if anyone has any more suggestions please let me know. So far, everyone seems to be more or less in agreement that it’s a latency problem.
It 100% is a latency problem. Without a doubt.
Oh, my bad! I had completely forgotten about this! Anyways, like I said earlier, I managed to get it working with lower latencies, but for players with a higher latency you should probably just hand the pathfinding off to their client. Despite the risk of this method due to exploiters, there’s no other way that I know of for high-latency players. Anyways, I’ll clean my code up today and have it ready for presentation by tomorrow.
UPDATE: Truly sorry I won’t be able to present this today. I broke my collar bone earlier today and as a result, all projects of mine, including this one, have been put on hold until I can type without pecking the keyboard. Again, truly sorry. I’ll have this as my first priority once I am healed enough to not do damage. I still had a few things I needed to get cleaned up, but if you want me to just post what
I have now and try and try to get it working yourself then just say so and I can.
That really sucks, hope you get better soon. Take as much time as you need; I’d rather you post it when you feel it’s complete so that I don’t have to spend time trying to figure out the incomplete parts when you already have them figured out but just can’t implement them because of the injury.
In the meantime, I’ll try to find other parts of the game that I can work on that don’t rely on the success of the pathfinding.
Oh my gosh, I’m having the exact same issue! I’ve spent the last 8 hours trying to fix it and now my script is real messed up… I hope you can find an answer to it because i do not want to make my AI slower than the player (no point of a sprint system otherwise)
Please @ me if you figure out a solution because I’m stumped at the moment too
Also hope you get better soon @BuilderBob25620!
I have surgery tomorrow, so I should be able to finish this sometime next week, after I get caught up on homework.
The solution is all about monitoring the players latency and assembly velocity and then adjusting from there. I actually became stumped at one point when trying to get the prediction for the characters estimated position, but I recently found the solution for that from another project I was working on.
Don’t stress yourself dude, I’m in no rush, and I might be ok with a bit of lag now that I’m adding the jumpscare code. So it might not matter that much, at least for me.
Also you sound like an absolute genius in coding and a great person!
Hope your surgery goes well, and that you’re back in good health soon
Don’t worry. I’m not so much stressed as I am engrossed. Also, I don’t think I worded the bottom paragraph correctly. What I meant to say was it will help me estimate their position for greater latencies.
This isn’t a client server latency issue. It happens to ai as well I made a helper NPC to kill ai zombies and the same issue occurs still.
I don’t have too much time and I’m away from my computer so I can’t test it, but isn’t there a delay with pathfinding? I’m pretty sure that computing a path yields the thread until a path is returned. I’m unsure how long that takes (I usually write my own pathfinding scripts) but that could be at least one source of delay. Might be too fast to notice though.
Try making it so it goes directly towards the player if you’re within a certain range of them to see if that fixes it.
Server-based entities will still have to deal with server to client latency of course, but this might be able to reduce the overall latency maybe.