> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/core-engine-concepts/movement-agents-npcs.md).

# Movement Agents/NPCs

Use Movement\_Agent to move entities with pathfinding and navmesh constraints.

### Movement Agents

`Movement_Agent` is a movement helper component used for steering and pathfinding.

Most commonly, you use it to:

* Request a path toward a target (`set_path_target`)
* Constrain an entity to walkable space (lock to a `Navmesh`)
* Move through simple collider geometry

{% hint style="info" %}
This page covers movement and pathfinding. For building/querying navmeshes and collider trigger details, see [Navmesh & Collision](/core-engine-concepts/navmesh-and-collision.md).
{% endhint %}

### Movement\_Agent API reference

```go
Movement_Agent :: class : Component {
    Set_Path_Target_Result :: struct {
        success:        bool;
        next_point:     v2;
        move_direction: v2;
    }

    // Request a path toward target at a given speed.
    set_path_target :: method(target: v2, speed: float) -> Set_Path_Target_Result;

    // Constrain this agent to a navmesh (snap to it every frame).
    // Pass null to clear.
    set_navmesh_to_lock_to :: method(navmesh: Navmesh);

    // Common tuning/state
    movement_speed:   float;
    agent_radius:     float;
    friction:         float;
    velocity:         v2;
    input_this_frame: v2; // write-only from scripts; zeroed by the movement update before callbacks run (read player.input_this_frame instead)
}
```

### CSL movement physics and triggers

Movement\_Agent entities have a CSL physics path for simple ballistic movement.

Collision: the agent's enabled non-trigger colliders block against enabled non-trigger world colliders, taking `category_bits` / `mask_bits` filtering into account. Movement stops at the first hit and slides along the hit surface.

Two colliders interact only when each one's `mask_bits` contains the other's `category_bits` (both u32 bitmasks). Colliders default to `category_bits: 1`, `mask_bits: 4294967295`. The player's collider is `category_bits: 2` with `mask_bits` = everything except bit 2 (players do not collide with each other). Leave the defaults alone unless you need layers: a wall with `mask_bits: 1` or `category_bits: 2` does not block the player.

Trigger callbacks belong to the collider and do not require a `Movement_Agent`.

### Pathfinding (set a target)

Call `set_path_target` every frame while the entity should keep moving. A single call is not a persistent movement command.

```go
follow_target :: proc(agent: Movement_Agent, target_pos: v2) {
    result := agent.set_path_target(target_pos, agent.movement_speed);

    if result.success {
        // result.next_point: next waypoint
        // result.move_direction: normalized move direction (useful for facing/anim)
    }
}
```

{% hint style="info" %}
`set_path_target` is processed asynchronously with other agents. The returned result is the latest completed pathfind data, so the first frame you set a new target may not return `success == true`.
{% endhint %}

### Lock movement to a navmesh (stay on walkable space)

If an entity should never leave walkable space, lock it to a navmesh:

```go
agent.set_navmesh_to_lock_to(navmesh);
```

Call it with `null` to clear.

### Creating Moving NPCs

This is a minimal “follow the player” NPC using a movement agent:

```go
Follower_NPC :: class : Component {
    @ao_serialize agent: Movement_Agent;
    @ao_serialize target: Entity;

    ao_update :: method(dt: float) {
        if !#alive(target) return;

        result := agent.set_path_target(target.world_position, agent.movement_speed);
        if result.success {
            // Optional: face direction / set animation flags
            // dir := result.move_direction;
        }
    }
}
```
