forgottenserver icon indicating copy to clipboard operation
forgottenserver copied to clipboard

Update pathfinding call

Open NRH-AA opened this issue 2 years ago • 22 comments

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.

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:

NRH-AA avatar Aug 31 '22 02:08 NRH-AA

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

Zbizu avatar Sep 04 '22 17:09 Zbizu

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

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.

NRH-AA avatar Sep 04 '22 20:09 NRH-AA

@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

Zbizu avatar Sep 04 '22 20:09 Zbizu

@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()

NRH-AA avatar Sep 04 '22 21:09 NRH-AA

@Zbizu I am pretty sure with these last changes it was fixed. I can't see the issue on my side.

NRH-AA avatar Sep 04 '22 21:09 NRH-AA

@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

Zbizu avatar Sep 05 '22 16:09 Zbizu

@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?

NRH-AA avatar Sep 05 '22 18:09 NRH-AA

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

Zbizu avatar Sep 06 '22 00:09 Zbizu

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

NRH-AA avatar Sep 06 '22 06:09 NRH-AA

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 avatar Sep 07 '22 14:09 Zbizu

@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?

NRH-AA avatar Sep 09 '22 09:09 NRH-AA

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.

NRH-AA avatar Sep 09 '22 09:09 NRH-AA

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

ranisalt avatar Sep 09 '22 10:09 ranisalt

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?

NRH-AA avatar Sep 09 '22 10:09 NRH-AA

Cool effort, keep it up!

marcingoralski avatar Sep 11 '22 03:09 marcingoralski

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?

Tofame avatar Sep 11 '22 18:09 Tofame

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

Zbizu avatar Sep 12 '22 00:09 Zbizu

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

NRH-AA avatar Sep 13 '22 06:09 NRH-AA

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

Zbizu avatar Sep 13 '22 16:09 Zbizu

https://youtu.be/YuKYgnYujAo @Zbizu

NRH-AA avatar Sep 13 '22 19:09 NRH-AA

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.

NRH-AA avatar Sep 17 '22 04:09 NRH-AA

https://youtu.be/YuKYgnYujAo @Zbizu

When summons stand diagonal they are closer as just as Zbizu explained.

diag

soul4soul avatar Sep 17 '22 15:09 soul4soul

summon follow pattern: 4123

emil92b avatar Sep 29 '22 01:09 emil92b