forgottenserver
forgottenserver copied to clipboard
Update pathfinding call
Pull Request Prelude
Monsters update follow path only when onThink() occurs. This causes a lag that makes monsters easy to get away from. This pull will make them update their path whenever the path they need to get to changes.
- [x] I have followed proper The Forgotten Server code styling.
- [x] I have read and understood the contribution guidelines before making this PR.
- [x] I am aware that this PR may be closed if the above-mentioned criteria are not fulfilled.
Changes Proposed
Remove path update onThink() Add a check to when the creature walks to see if it needs to update its path. If the position it needs to get to hasn't changed it will not update its path.
Watch path update behavior here: https://youtu.be/TYV4qFLHr-Q
Creature Keep Distance: https://youtu.be/2FkE23HkhS0
Issues addressed:
there is one more problem: monsters stop when you walk to them, they hit you and you run away expected behaviour: black square will lit up and monster will start chasing instantly observed: monster stands still until he received new instruction from onThink/checkCreatures
I tried to add updateCreatureWalk
at the end of doAttacking
, but it didn't change anything
there is one more problem: monsters stop when you walk to them, they hit you and you run away expected behaviour: black square will lit up and monster will start chasing instantly observed: monster stands still until he received new instruction from onThink/checkCreatures
I tried to add
updateCreatureWalk
at the end ofdoAttacking
, but it didn't change anything
What monster are you trying this on? I don't completely understand the problem.
Should the black square stay on? Is the monster not following fast enough? when you run away?
Testing some things I noticed when you first walk into the range of the monster If you run into him he has a delay before he starts walking to you.
It also doesn't show the black square until he walks up and hits you (that is with non-ranged monsters) Ranged monsters will show the black square whenever they shoot at you.
@gigastar I mean melee monsters.
expected:
https://user-images.githubusercontent.com/5205079/188333341-7b108b31-9c20-4407-b998-a89bd179ebd8.mp4
observed:
https://user-images.githubusercontent.com/5205079/188333347-c649d54c-a779-4c47-9711-2f77162607ac.mp4
@gigastar I mean melee monsters.
expected:
2022-09-04.22-50-06.mp4 observed:
2022-09-04.22-57-56.mp4
So it looks like they are missing swings maybe? Its still hard to see xD. Can you slow down your GM character so its closer to the same thing. Also, try the new changes from the pathfinding itself and the changes here in the pathfinding call.
local TalkSetSpeed = TalkAction("/setspeed")
function TalkSetSpeed.onSay(player, words, param)
if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then
return false
end
if param == "" then
return false
end
local t = param:split(",")
local target = t[1]
local amount = t[2]
if not amount then
amount = tonumber(param)
target = Creature(player)
else
amount = tonumber(amount)
end
target = Creature(target)
if not target then
target = Creature(player)
end
target:changeSpeed(-target:getSpeed())
target:changeSpeed(amount)
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "You have set "..target:getName().."'s speed to "..amount..".")
return false
end
TalkSetSpeed:separator(" ")
TalkSetSpeed:register()
@Zbizu I am pretty sure with these last changes it was fixed. I can't see the issue on my side.
@gigastar the issue is that monsters stand still for a moment (they shouldn't)
updating monster direction should make them start walking towards target immediately (it doesn't, they just stand still until next checkCreatures cycle - up to 2 sec)
adding this
g_dispatcher.addTask(createTask([id = getID()]() { g_game.updateCreatureWalk(id); }));
at the beginning of onCreatureMove
and at the beginning of updateLookDirection
seems to decrease monster idle time, but it's probably not very cpu-friendly solution
@gigastar the issue is that monsters stand still for a moment (they shouldn't)
updating monster direction should make them start walking towards target immediately (it doesn't, they just stand still until >next checkCreatures cycle - up to 2 sec)
adding this
g_dispatcher.addTask(createTask(id = getID() { g_game.updateCreatureWalk(id); }));
Is this something that didn't happen before? That will help me find a solution. If it was a bug already I think it is linked to something else.
I found a solution. The only thing im wondering is... If the monsters turn a direction, but need to turn again before facing the correct way. On real tibia do they walk anyway or do they take an extra second to turn the correct way, then start walking?
I found a solution. The only thing im wondering is... If the monsters turn a direction, but need to turn again before facing the correct way. On real tibia do they walk anyway or do they take an extra second to turn the correct way, then start walking?
it is very hard to make a monster stand still in rl by walking to him and running away. I only managed to do it once (beginning of first recording, wolf north of my char), as you can see the wolf takes 0.5-1 sec pause at best. Tfs monsters take 2 sec and they do it far more often.
sry for no review and not responding to whole comment, it's late and I'm going to sleep
After some testing it is actually better updating the paths this way. It also fixes the problem zbizu showed.
It was less cpu expensive because instead of updating onWalk where you can have 1000 monsters walking at the same time pushing all those path updates over and over it is a set time. I tested this with at least 300 monsters chasing me and did see a better result.
Check it out https://youtu.be/_0CgRjGHhC0
I forgot to answer this one earlier:
Is this something that didn't happen before? That will help me find a solution. If it was a bug already I think it is linked to something else.
It was bugged in tfs for years. I just thought it to be worth mentioning here because it is very closely related to your changes. Seems to be working better now. Monsters still get stuck for a while occasionally, but for much shorter durations now (imo acceptable right now).
@Zbizu If you change: static constexpr int32_t EVENT_CREATURE_PATH_INTERVAL = 20;
To 10 the monsters will be even more responsive when turning. You can play with that depending on how powerful your server is to modify how fast the pathing happens. I think that's good yeah?
This was an issue brought by ralke:
Hi there! I've just updated everything, saw this post and started the testings. I have found a little issue already, when I use >utevo res "any creature, the creature doesn't follow the player. This started to happen, after applied the commits, is it related >to the latest changes? Regards!
Edit: Found another one, when I click on a stair from far distance (with right click, to use it), it says "There is no way". The same >thing happens when I try to use any object from far distance... Here you can see how I applied the whole code.
Both issues were addressed in the last few commits.
Just want to add something super weird that Cipsoft Tibia has (I think it is a regression and should not be considered).
A monster will not walk to the player if the distance to cover is larger than half the viewport size (i.e. distance between the center and the edge). In this video, the distance the Orc Warlord would span over 7 sqm, so it simply did not attack me until it was close enough.
Just want to add something super weird that Cipsoft Tibia has (I think it is a regression and should not be considered).
A monster will not walk to the player if the distance to cover is larger than half the viewport size (i.e. distance between the center and the edge). In this video, the distance the Orc Warlord would span over 7 sqm, so it simply did not attack me until it was close enough.
Screencast.from.09-08-2022.11.03.52.AM.webm
That probably is part of their system to suppress pathfinding calls mixed with making monsters/situations a little easier for the kids.
It could also just be their opinion on how monsters should behave based on their sight 0.0 can they see/smell/hear you?
Cool effort, keep it up!
Im not sure where should I leave this comment here, or on the other thread of the pathfinding. And also I'm not sure if this was intended or not, but thinking that maybe it wasn't I will post. Summon follows his master while always keeping 1 distance. However, if the master approaches him he stays still. Shouldn't he back off 1 cell?
Im not sure where should I leave this comment here, or on the other thread of the pathfinding. And also I'm not sure if this was intended or not, but thinking that maybe it wasn't I will post. Summon follows his master while always keeping 1 distance. However, if the master approaches him he stays still. Shouldn't he back off 1 cell?
You're correct. I have a code working like this on a public repo, but it's not compatible with the one in this pr and I don't remember the commits I made anymore.
@ranisalt my guess is they're using dijkstra algo with range limits also either the monster path has reset when you moved or changing walk direction has extra cost
Im not sure where should I leave this comment here, or on the other thread of the pathfinding. And also I'm not sure if this was intended or not, but thinking that maybe it wasn't I will post. Summon follows his master while always keeping 1 distance. However, if the master approaches him he stays still. Shouldn't he back off 1 cell?
Im not sure where should I leave this comment here, or on the other thread of the pathfinding. And also I'm not sure if this was intended or not, but thinking that maybe it wasn't I will post. Summon follows his master while always keeping 1 distance. However, if the master approaches him he stays still. Shouldn't he back off 1 cell?
You're correct. I have a code working like this on a public repo, but it's not compatible with the one in this pr and I don't remember the commits I made anymore.
@ranisalt my guess is they're using dijkstra algo with range limits also either the monster path has reset when you moved or changing walk direction has extra cost
Fixed in A* pull
Fixed in A* pull
pretty sure he meant this (summons should always stand in dist_x + dist_y = 2 distance from player, 2 tiles away in a straight line, 1 tile away diagonally): https://github.com/OTAcademy/forgottenserver/blob/master/src/creature.cpp#L1694
https://youtu.be/YuKYgnYujAo @Zbizu
I have been working on updating all the code for this. A lot of the code can be changed or removed. Paths only update if the last path is no longer possible so we don't need any extra code for getting paths that don't use the A* path finding. With the changes to A* it essentially costs nothing 90% of the time and costs a fraction at the more complex path ends.
We can use A* as a bool to tell us if we should be doing a dance step or not as well as a random step if we need it.
https://youtu.be/YuKYgnYujAo @Zbizu
When summons stand diagonal they are closer as just as Zbizu explained.
summon follow pattern: