SelinaDev / Godot-Roguelike-Tutorial

Yet Another Roguelike Tutorial in Godot
MIT License
74 stars 10 forks source link

Bug where the enemy moves with probability more than one grid unit in a turn #17

Closed Pastque closed 6 months ago

Pastque commented 6 months ago

An enemy move with "hostile_enemy_ai_component.gd" will move more than one grid unit in a turn with probability. To facilitate observation, I increased the number of enemies and expanded the field of view, keep entities visible at all times.

My test method is to add this code to "movement_action.gd" -> perform()

...
    if offset.length() > 2:
        entity.modulate = Color.BLUE
        print(offset.length())
    entity.move(offset)
...

"map.gd" -> update_fov()

...
func update_fov(player_position: Vector2i) -> void:
    field_of_view.update_fov(map_data, player_position, 20)

    #for entity in map_data.entities:
        #entity.visible = map_data.get_tile(entity.grid_position).is_in_view
...
SelinaDev commented 6 months ago

Thank you for mentioning this, I'll look into it when I get the chance. Although I have to admit I have no idea where this could originate. When checking the code I did realize that I forgot to specify the heurisic for the pathfinder, meaning it still uses euclidean. But that still should result in a path of consecutive tiles. I'll see what I can find out.

SelinaDev commented 6 months ago

Looking more into this I believe this might be caused by units not being in sight of the player and being blocked for a turn by another unit. The way the Hostile AI currently works is that it will try to follow the player to the last seen position by following the last valid path, consuming one path segment per turn. However, that does not take into account whether that path segment is currently valid, i.e., if another entity is blocking the destination of the path the entity will consume that path segment regardless, while the resulting move action will check the destination and not move the entity. The turn after the entity would just get the next path segment, which is now two tiles away.

There are two solutions I am currently thinking of. One is to check the destination tile before popping the next step of the path. This would be the simpler fix. The other is to not remember the path, but the position an enemy last saw the player at, and always generate a new path to that position. This would lead to better pathfinding if the environment changes due to movement of other entities, so better handling of crowds. However, if my assumptions are correct the pathfinding would only improve outside the player's view, so it might not be worth the extra effort. I'm currently leaning towards the first option. I'll try implementing it soon.

Pastque commented 6 months ago

@SelinaDev, I accidentally hit the wrong close button😂. Thank you so much for your wonderful Godot-Roguelike-Tutorial ! ! ! I am still trying to learn, even on the other side of the world, still makes me feel warmth😊

SelinaDev commented 6 months ago

I deployed a fix now, which I also included in the tutorial itself. Please test if you can produce the bug. I tried it a couple of times, under the same circumstances as before, and cannot reproduce the bug now. However, of course it's hard to prove the absence of a behavior that occurs rarely. Thank you again for pointing me to this issue.

Pastque commented 6 months ago

I deployed a fix now, which I also included in the tutorial itself. Please test if you can produce the bug. I tried it a couple of times, under the same circumstances as before, and cannot reproduce the bug now. However, of course it's hard to prove the absence of a behavior that occurs rarely. Thank you again for pointing me to this issue.

Thankfully, after testing, the issue was resolved and the bug does not appear again