How to optimize pathfinding to the player

Godot Version:

4.2.1 Mono


I have a large number of monsters, by running a number of tests I found out that performance crashes at the point of calculating the path from the monster to the player, here is the code:

private Vector2 directionToPlayer => (player.GlobalPosition - entity.GlobalPosition).Normalized();

public override void _PhysicsProcess(double delta)
    if (healthComponent.Alive)
        movementComponent.Direction = directionToPlayer;
        if (attackTimer.IsStopped() && attackComponent.HasOverlappingAreas())
            attackComponent.EmitSignal(AttackComponent.SignalName.Attack, attackResource);

The logic of the code is simple if the character is alive (HealthComponent.Alive), we get directions to the player and move it. If he will be in the attack zone and the attack timer is stopped, i.e. the recharge has passed, then we also hit the player.

But this code very much eats performance, if at 350 enemies I already have <60 fps, then without this piece of code I can have more than 500 enemies at fps >144.

I think the problem is in the calculation of the path to the player, is there any way to optimize it or if I’m wrong and the problem is different, how can I optimize it differently?

If it is just a direction move the “pathfinding” itself will not eat any reasonable amount of performance.

What more likely is eating the performance here is the physics use. The physics process in general (runs up to 8 times a frame) and the physics overlap check (costs more and more to update with more “monsters” and other physics objects in proximity).

Especially Area2D does not scale with a large amount of objects as it is super-height cost for what it does due to all its internal book-keeping for convenience. If you replace it with a “real” PhysicsServer area just for overlap checks you can have like 30+ for the same cost.

Anyway, I think you’re right, I’m already climbing the wall and I don’t know what to do. My computer is not powerful i5 8th generation and gtx 1050, but I think that such a 2D game should safely start and run even on it. I disabled monitoring on hitbox, disabled monitorable on attackArea, changed physics engine to godotPhysics2d, but it doesn’t get better :frowning:

I was thinking about using physicsServer directly, but… I’m not comfortable with that. Once I tried to write a C++ game without an engine, my nervous system couldn’t take it any further than an ordinary platformer.