@ferret/ai
NavMesh queries, crowd agents, steering and the small behaviours and trees NPCs run.
Classes
Attention class
class Attention extends Component<AttentionParams>Stops and turns to face a target that comes near (the player), resumes when it leaves; startTalk / endTalk hold the character in place regardless of distance. Roam is paused while attending. Emits ai:attend and ai:resume.
attending: boolean | |
talking: boolean | |
onAttach() | |
startTalk() | |
endTalk() | |
onFixedUpdate() |
packages/ai/src/behaviours.ts:59
AutoWalk class
class AutoWalkWalks a character along a NavMesh path to a point, on the fixed step, through the same movement code a person uses. It fails when the capsule falls through the ground, sticks in a wall or does not get there in time. This is the regression test of a level's collision.
constructor(private world: World, private character: () => Walker | null) | |
get active() | |
buildNav(o: { agentRadius?: number; agentHeight?: number; maxClimb?: number; maxSlope?: number; cellSize?: number }): NavService | A NavMesh of the whole level for walking (the level's own may cover only the volume of its NavMeshBoundsVolume). |
go(nav: NavService, goal: BABYLON.Vector3, timeout = 60): Promise<WalkResult> |
packages/ai/src/autowalk.ts:15
BehaviorTree class
class BehaviorTreereadonly bb: Blackboard | |
lastStatus: Status | |
constructor(readonly root: BTNode, bb: Blackboard = {}) | |
update(dt: number): Status | |
reset() |
packages/ai/src/tree.ts:107
BTNode class
abstract class BTNodeabstract tick(ctx: TreeContext): Status | |
reset(): void | called when a running node is interrupted by a higher-priority branch |
packages/ai/src/tree.ts:11
Follow class
class Follow extends Component<FollowParams>Walk after an entity and stop distance short of it.
onAttach() | |
onFixedUpdate() |
packages/ai/src/behaviours.ts:109
Roam class
class Roam extends Component<RoamParams>Walk to random points within a radius of home, wait a while at each, repeat. Needs a NavAgent.
home: Vector3 | |
active: boolean | a game or another behaviour may switch roaming off (talking, a cutscene) |
onAttach() | |
onFixedUpdate(dt: number) |
packages/ai/src/behaviours.ts:14
Functions
collectGeometry function
function collectGeometry(meshes: BABYLON.AbstractMesh[]): { positions: Float32Array; indices: Uint32Array }World-space triangles of the meshes, in the flat arrays recast takes.
packages/ai/src/nav.ts:193
cutBoxes function
function cutBoxes(g: { positions: Float32Array; indices: Uint32Array }, boxes?: NavExcludeBox[])remove the parts of the geometry inside each box: a triangle is split by the box's six planes and the pieces outside are kept
packages/ai/src/nav.ts:230
fireActuator function
function fireActuator(world: World, actuator: string): BTNodeRun an actuator from the start: one impulse or one cycle (a stroke).
packages/ai/src/actuate.ts:19
setCommand function
function setCommand(world: World, actuator: string, value: number | ((bb: Blackboard) => number)): BTNodeSet an actuator's command (a throttle, a lever); the value may be read from the blackboard.
packages/ai/src/actuate.ts:14
switchActuator function
function switchActuator(world: World, actuator: string, on: boolean): BTNodeSwitch an actuator on or off.
packages/ai/src/actuate.ts:24
worldPos function
function worldPos(n: BABYLON.TransformNode): BABYLON.Vector3The world position of a node, up to date even when nothing has rendered since it moved (Babylon caches the matrix per render id).
packages/ai/src/agent.ts:6
Interfaces
AttentionParams interface
interface AttentionParamstarget?: string | the entity to look at: found by name or tag (default tag "player") |
radius?: number | closer than this the character stops and turns to the target |
leaveRadius?: number | stays interested until the target is this far (hysteresis; default radius * 1.3) |
packages/ai/src/behaviours.ts:46
FollowParams interface
interface FollowParamstarget?: string | |
distance?: number | keep this far from the target |
tolerance?: number | re-plan when the target moved more than this |
packages/ai/src/behaviours.ts:100
RoamParams interface
interface RoamParamsradius?: number | roam within this distance of the home point (default: where the entity starts) |
home?: [number, number, number] | |
pause?: [number, number] | seconds to wait at each stop: [min, max] |
packages/ai/src/behaviours.ts:5
TreeContext interface
interface TreeContextbb: Blackboard | |
dt: number |
packages/ai/src/tree.ts:9
Walker interface
interface WalkerWhat the walk drives: a character's mesh (position), its yaw and its move input (CharacterMovement fits).
mesh: BABYLON.AbstractMesh | |
yaw: number | |
setMoveInput(dir: BABYLON.Vector3, run: boolean): void |
packages/ai/src/autowalk.ts:5
WalkResult interface
interface WalkResultgoal: number[] | |
reached: boolean | |
reason: 'reached' | 'stuck' | 'fell' | 'no path' | 'timeout' | |
seconds: number | |
position: number[] | |
distanceLeft: number |
packages/ai/src/autowalk.ts:9
Types
Blackboard type
type Blackboard = Record<string, any>packages/ai/src/tree.ts:7
Status type
type Status = 'success' | 'failure' | 'running'A small behaviour tree runner (the equivalent of UE's Behavior Tree + Blackboard): composites, decorators and leaves tick every update and answer success, failure or running. A running leaf is resumed where it was. The blackboard is a plain object shared by the nodes. Pure logic, no Babylon.
packages/ai/src/tree.ts:6
Vec3 type
type Vec3 = { x: number; y: number; z: number }packages/ai/src/nav.ts:35
Constants
bt const
const bt: { action: (fn: (ctx: TreeContext) => boolean | void | Status) => BTNode; condition: (fn: (bb: Blackboard) => boolean) => BTNode; sequence: (...kids: BTNode[]) => BTNode; selector: (...kids: BTNode[]) => BTNode; wait: (seconds: number | ((bb: Blackboard) => number)) => BTNode; not: (kid: BTNode) => BTNode; succeed: (kid: BTNode) => BTNode; guard: (cond: (bb: Blackboard) => boolean, kid: BTNode) => …packages/ai/src/tree.ts:82