In ALLFATHER, enemies move and attack on a shared clock while the player fights in real time. Tommy McKay explains why he rebuilt their navigation around a grid.
ALLFATHER builds its dungeon from rooms assembled at the start of each run. Enemies need to find the player, get through narrow doorways and make room for one another during combat.
Tommy McKay first put the assembled rooms under one
NavigationRegion3D and gave each enemy a
NavigationAgent3D. He added navigation links at doorways, where closed doors left gaps in the baked mesh. It worked, but baking each new layout before spawning enemies would delay the start of a run.
In combat, enemies jittered when changing direction, crowded the same route to the player and struggled in narrow hallways. Their continuous steering also clashed with ALLFATHER’s deliberately stepped animations.
Tommy replaced that setup with DungeonGrid. The player still moves freely, but enemies travel between cells one meter apart. The grid comes straight from the room data the generator already has, so there is no navmesh to bake or need for raycasts to find walkable space.
Godot’s AStar3D finds routes between neighboring cells in four directions. Closing a door blocks its cells; opening it frees them. Other obstacles can change the grid during a fight too.
Enemies make movement and attack decisions on a shared tick of about 0.333 seconds. An enemy claims its next cell and crosses it in one tick. It moves toward the cell’s center every frame with move_and_slide(), so the travel stays smooth. Once a move starts, it has to finish; stopping halfway made enemies snap back.
Attacks and recovery take whole ticks too. A basic swordsman strikes for one, recovers for one and waits three more before swinging again. The player never waits for that clock: input, damage and hit reactions happen immediately.
To keep a crowd from attacking all at once, an EngagementManager gives enemies different roles. Some circle at a distance, a smaller group holds positions near the player, and only a few are allowed to swing. Tommy can adjust how many enemies fit in each group for a given dungeon.
Doorways exposed one more problem. At first, an occupied cell was blocked completely, so one enemy in a narrow doorway stopped everyone behind it from finding a path. Occupied cells now cost more to route through. Followers keep their route, wait for the next cell to clear, then move forward.
The grid supports other parts of combat too. Fire and lava make cells less attractive to path through, while one boon pulls enemies inward a cell at a time. Tommy can build those rules into the same grid that controls movement.
Godot’s navigation tools are suited to smooth steering. Tommy needed enemies whose movement, spacing and attacks followed ALLFATHER’s combat timing, and the grid gave him control over all three.
Building a Godot game of your own?