I tried adding navigation to the NPC characters in null using NavigationAgent2D and ran into a weird problem where _physics_process(_delta) was never being called whenever I had a value for target_position that I wanted to use. As it turns out, I forgot to use call_deferred("actor_setup") when waiting one physics frame in _ready().

Incorrect usage of await in _ready():

In this example, _physics_process will never be called because await was called directly from _ready()

func _ready():
	navigation_agent.velocity_computed.connect(move_character)
	actor_setup()
 
func actor_setup():
	if target != null:
		# Wait for the first physics frame so the NavigationServer2D can
		# sync before setting the target position.
		await get_tree().physics_frame
		navigation_agent.target_position = target.global_position

Correct usage of await in _ready():

To await in a ready, you must use call_deferred() so that the await happens after _ready is done.

func _ready():
	navigation_agent.velocity_computed.connect(move_character)
 
	# Make sure to not await during _ready.
	call_deferred("actor_setup")
 
func actor_setup():
	if target != null:
		# Wait for the first physics frame so the NavigationServer2D can
		# sync before setting the target position.
		await get_tree().physics_frame
		navigation_agent.target_position = target.global_position

Not sure why awaiting in _ready() causes this problem. It might be worthwhile looking into that later.