class: ActorLocator

Specialized locators for querying and interacting with spatial 3D objects in the Unreal world. Extends the base SpecterLocator and features native Gameplay Ability System (GAS) integration.

actor.getLocation

Retrieves the current 3D world coordinates of the actor.

Usage

const startPos = await enemy.getLocation();

Returns

actor.waitForGameplayTag

Waits until the actor possesses the specified Gameplay Tag. Useful for verifying status effects like stuns or buffs.

Usage

await player.waitForGameplayTag("Status.Stunned");

Arguments

  • tagstring
    The exact Gameplay Tag string to wait for.

Returns

  • Promise<void>

actor.triggerAbilityByTag

Locates an ability on the actor's Ability System Component that matches the tag and explicitly triggers it.

Usage

await player.triggerAbilityByTag("Ability.Slot.Q");

Arguments

  • tagstring
    The tag identifying the ability (e.g. Ability.Slot.Q).

Returns

  • Promise<void>

Transform & Spatial

Methods for interacting with the actor's 3D position and rotation in the world.

actor.getLocation

Retrieves the actor's current 3D world location.

Usage

const pos = await player.getLocation();
console.log(pos.x, pos.y, pos.z);

Returns

actor.getForwardVector

Retrieves the actor's normalized forward directional vector.

Usage

const forward = await player.getForwardVector();

Returns

actor.setLocation

Teleports the actor to a new 3D world location.

Usage

await player.setLocation({ x: 0, y: 0, z: 1000 });

Arguments

  • locationVector3
    The target {x, y, z} coordinate.

Returns

  • Promise<void>

actor.setRotation

Teleports the actor to a new rotation.

Usage

await player.setRotation({ pitch: 0, yaw: 90, roll: 0 });

Arguments

  • rotationRotator
    The target {pitch, yaw, roll} rotation.

Returns

  • Promise<void>

actor.setTransform

Teleports the actor to a new full transform (location, rotation, and scale).

Usage

await player.setTransform({ location: { x: 0, y: 0, z: 0 }, rotation: { pitch: 0, yaw: 0, roll: 0 }, scale: { x: 1, y: 1, z: 1 } });

Arguments

  • transformTransform
    The target transform object.

Returns

  • Promise<void>

State & Testing

actor.highlight

Visually highlights the actor in the engine using a debug wireframe and floating text. Extremely useful for debugging tests visually!

Usage

await boss.highlight("Target Acquired!");

Arguments

  • stateInfostring(optional)
    Text to float above the actor.

Returns

  • Promise<void>

actor.checkVisibility

Checks if the actor's mesh is actively rendering. If checkOnScreen is true, verifies it is within the camera frustum.

Usage

const isVisible = await boss.checkVisibility(true);

Arguments

  • checkOnScreenboolean(optional)
    Whether to require it to be on-screen.

Returns

  • Promise<boolean>

actor.isLocallyControlled

Returns a new narrowed locator that filters the current set of actors down to only those possessed by the local human player. Perfect for filtering out AI Bots in Lyra!

Usage

const localPlayer = world.actor('BP_Hero_Shooter').isLocallyControlled(true);

Arguments

  • locallyControlledboolean(optional)
    Whether to filter for locally controlled (true) or non-locally controlled (false).

actor.getPlayerId

Retrieves the unique Player ID associated with the actor's PlayerState.

Usage

const id = await player.getPlayerId();

Returns

  • Promise<number>

actor.getByComponent

Traverses down the hierarchy to find a specific component on this actor, returning a strongly-typed specialized locator (e.g. SkeletonLocator or MovementLocator).

Usage

const skeleton = player.getByComponent("Skeleton");
await expect(skeleton).toHaveBoneRotation("head", { pitch: 0, yaw: 90, roll: 0 });

Arguments

  • componentTypestring
    The component type key (e.g. 'Skeleton', 'CharacterMovement').
  • optionsobject(optional)
    Filters like name or exact UE class.

Returns

  • ComponentLocator

Actor-Scoped Widgets (UI)

Methods for locating 3D/Screen-space UWidgetComponents and their hosted UMG widgets directly on this actor.

actor.widget

Scopes down to any UMG widget hosted on this actor (via a UWidgetComponent or widget property). If no class name is provided, matches the primary hosted widget.

Usage

// Grabs the widget from Steel's UWidgetComponent:
const healthBar = steel.widget();
await expect(healthBar).toBeVisible();

Arguments

  • widgetClassOrNamestring(optional)
    The specific UMG widget class to find.

Returns

  • WidgetLocator<W>

actor.widgetComponent

Scopes to a specific UWidgetComponent by its Unreal component name and returns its underlying UUserWidget.

Usage

const healthBar = steel.widgetComponent("HealthBarComponent");

Arguments

  • componentNamestring(optional)
    The Unreal component name (e.g. 'HealthBarComponent').

actor.getByRole

Traverses directly into the actor's hosted widgets to find child elements by semantic role ('image', 'button', 'text', 'progressbar', etc.).

Usage

const healthImage = steel.getByRole("image", { name: "HealthBarImage" });
await expect(healthImage).toBeVisible();

Arguments

  • roleWidgetRole
    The semantic UI role.
  • optionsWidgetRoleOptions(optional)
    Role options like { name: 'HealthBarImage', exact: false }.

actor.pin

Resolves any dynamic query (such as .last(), .first(), .nth()) once on the engine, attaches a unique tag, and registers it into the engine's O(1) fast-path lookup table. Returns an ActorLocator pinned to that exact actor instance.

Usage

// 1. Resolve and pin the current last minion in the level:
const targetMinion = await world.actor("BP_MinionRange").last().pin();

// 2. High-frequency polling now executes in O(1) ~0.001ms time:
await expect(targetMinion).toHaveLocation({ x: 100, y: 200, z: 92 });

// 3. Spawning new minions will not hijack targetMinion:
await world.spawnActor("BP_MinionRange");
await targetMinion.highlight("Still Original Minion");

Returns

actor.destroy

Explicitly programmatically destroys the targeted actor in the Unreal Engine world.

Usage

await fireHazard.destroy();
await expect(fireHazard).toBeDestroyed();

Returns

  • Promise<void>

actor.getControllerInfo

Retrieves comprehensive controller and possession state information for the actor.

Usage

const info = await actor.getControllerInfo();
console.log(info.isPossessed);        // true
console.log(info.isPlayerControlled); // false (AI bot)
console.log(info.controllerClass);    // "BP_BossAIController"

Returns

  • Promise<ControllerInfo>

actor.isPossessed

Checks whether the Pawn is currently possessed by any active Controller (AI or Human).

Usage

const possessed = await minion.isPossessed();

Returns

  • Promise<boolean>

actor.isPlayerControlled

Checks whether the Pawn is possessed specifically by a human player (PlayerController) rather than an AI Controller.

Usage

const isHuman = await player.isPlayerControlled();

Returns

  • Promise<boolean>

Gameplay Ability System (GAS)

actor.getAttributeValue

Reads the current float value of a GAS Attribute.

Usage

const health = await player.getAttributeValue("HealthSet", "Health");

Arguments

  • attributeSetstring
    The Attribute Set class name.
  • attributeNamestring
    The specific attribute name.

Returns

  • Promise<number>

actor.hasGameplayTag

Checks if the actor's Ability System Component currently possesses the specified Gameplay Tag.

Usage

const isStunned = await player.hasGameplayTag("Status.Stunned");

Arguments

  • tagstring
    The tag to check.

Returns

  • Promise<boolean>

actor.getGameplayTags

Returns all Gameplay Tags currently owned by the actor's Ability System Component via IGameplayTagAssetInterface.

Usage

const tags = await enemy.getGameplayTags();
console.log(tags); // ['Status.Stunned', 'Status.Burning']

Returns

  • Promise<string[]>

actor.waitForGameplayTag

Waits asynchronously for a Gameplay Tag to be added or removed from the actor.

Usage

// Wait for the stun tag to be applied
await boss.waitForGameplayTag("Status.Stunned", true);

Arguments

  • tagstring
    The tag to wait for.
  • expectedStateboolean
    True to wait for addition, false to wait for removal.
  • timeoutnumber(optional)
    Timeout in milliseconds (Default: 5000).

Returns

  • Promise<boolean>

actor.waitForAttributeValue

Waits for a Gameplay Attribute to reach a specific value, tracking its history.

Usage

const result = await player.waitForAttributeValue("HealthSet", "Health", 0);
console.log("Health dropped to 0! History:", result.history);

Arguments

  • attributeSetstring
    The Attribute Set class name.
  • attributeNamestring
    The specific attribute name.
  • expectedValuenumber
    The value to wait for.
  • timeoutnumber(optional)
    Timeout in milliseconds (Default: 5000).

Returns

  • Promise<{ finalValue: number, history: number[] }>

actor.triggerAbilityByTag

Triggers a Gameplay Ability on the actor by its input tag.

Usage

await player.triggerAbilityByTag("Ability.Attack.Melee");

Arguments

  • inputTagstring
    The ability input tag.

Returns

  • Promise<void>

actor.triggerAbilityWithTarget

Triggers a Gameplay Ability and passes a target data payload (either an ActorLocator or a Vector3 location).

Usage

await player.triggerAbilityWithTarget("Ability.Spell.Fireball", boss);

Arguments

  • abilityTagstring
    The ability tag.
  • targetSpecterLocator | Vector3
    The target locator or 3D coordinate.

Returns

  • Promise<void>

actor.applyGameplayEffect

Directly applies a Gameplay Effect class to the actor's Ability System Component.

Usage

await player.applyGameplayEffect("/Game/Effects/GE_Damage_Poison.GE_Damage_Poison_C");

Arguments

  • effectClassPathstring
    The class path of the Gameplay Effect.
  • levelnumber(optional)
    The effect level (Default: 1.0).

Returns

  • Promise<void>

actor.hasActiveGameplayEffect

Checks if a specific Gameplay Effect class is currently active on the actor.

Usage

const isPoisoned = await player.hasActiveGameplayEffect("/Game/Effects/GE_Damage_Poison.GE_Damage_Poison_C");

Arguments

  • effectClassPathstring
    The class path of the Gameplay Effect.

Returns

  • Promise<boolean>

Input Simulation

actor.playSequence

Plays a mathematically accurate frame-by-frame SpecterInputSequence directed at this actor's input component.

Usage

import { SpecterInputSequence } from '@specter-automation/test';

const accelerate = new SpecterInputSequence()
    .addAxisSweep('Gamepad_RightTrigger', 0.0, 1.0, 0, 2000);

await playerCar.playSequence(accelerate);

Arguments

  • sequenceSpecterInputSequence
    The input sequence to play.
  • optionsObject(optional)
    { loops?: number } The number of times to loop the sequence.

Returns

  • Promise<void>

actor.pressKey

Simulates a raw hardware key press directed at this actor's input component.

Usage

// Quick press
await player.pressKey("SpaceBar");

// Hold the button for 500ms
await player.pressKey("Gamepad_FaceButton_Bottom", { holdMs: 500 });

Arguments

  • keyUnrealKey
    The UE key name (e.g. 'SpaceBar', 'Gamepad_FaceButton_Bottom').
  • optionsObject(optional)
    { holdMs?: number } How long to hold the key before releasing it.

Returns

  • Promise<void>

actor.injectAxis

Injects a raw analog value directly into this specific actor's Input Component. Ideal for simulating fine analog movements like slightly tilting a gamepad thumbstick or partially pulling a trigger.

Usage

// Pull the right trigger 10% on a specific player's controller
await playerActor.injectAxis('Gamepad_RightTrigger', 0.1);

Arguments

  • axisNamestring
    The name of the axis binding (e.g. 'Gamepad_RightTrigger').
  • valuenumber
    The float value to inject (typically -1.0 to 1.0).

Returns

  • Promise<void>

actor.type

Simulates typing a string of text sequentially by sending Pressed and Released events for each character.

Usage

await player.type("Hello Specter!");

Arguments

  • textstring
    The string of text to type.
  • delayMsnumber(optional)
    Optional delay between keystrokes.

Returns

  • Promise<void>

Enhanced Input

Methods for querying and triggering UE5 Enhanced Input Subsystem actions and mapping contexts.

actor.triggerInputAction

Triggers a UE5 Enhanced Input Action (UInputAction) on the actor's Enhanced Input Local Player Subsystem.

Usage

// Trigger a digital jump action
await player.triggerInputAction('IA_Jump', true);

// Trigger a 2D analog movement vector payload
await player.triggerInputAction('IA_Move', { x: 0.0, y: 1.0, z: 0.0 });

Arguments

  • actionstring
    The Input Action asset name or path (e.g. 'IA_Jump', 'IA_Move').
  • valueboolean | number | Vector3
    The input action value payload.

Returns

  • Promise<void>

actor.hasInputMappingContext

Checks whether a UE5 Input Mapping Context (UInputMappingContext) is actively applied to the player's Enhanced Input Subsystem.

Usage

const hasIMC = await player.hasInputMappingContext("IMC_DefaultPlayer");

Arguments

  • contextstring
    Short context asset name (e.g. 'IMC_DefaultPlayer') or full asset path.

Returns

  • Promise<boolean>

actor.getInputActionValue

Retrieves the current evaluated value of a UE5 Enhanced Input Action.

Usage

const info = await player.getInputActionValue("IA_Sprint");
console.log("Bool state:", info.boolValue);

Arguments

  • actionstring
    Short action asset name (e.g. 'IA_Sprint') or asset path.

Returns

  • Promise<{ value: number, boolValue: boolean, vector: Vector3 }>

Camera & FOV

Methods for querying and controlling camera properties, field of view, and camera shakes.

actor.getCameraFOV

Retrieves the current Field of View angle from the actor's camera component, player camera manager, or the actor's own camera.

Usage

const fov = await player.getCameraFOV(); // default: 90

Returns

  • Promise<number>

actor.setCameraFOV

Sets the Field of View angle on the actor's camera component, camera manager, or the actor's own camera.

Usage

await player.setCameraFOV(110);

Arguments

  • fovnumber
    The FOV angle in degrees.

Returns

  • Promise<void>

actor.isCameraShaking

Checks whether the actor's PlayerCameraManager currently has any active camera shakes playing.

Usage

const shaking = await player.isCameraShaking();

Returns

  • Promise<boolean>

actor.getCameraViewTarget

Returns the name of the actor currently being viewed through this actor's camera.

Usage

const target = await player.getCameraViewTarget();

Returns

  • Promise<string>

AI & Navigation

Methods for querying AI pathfinding state and navigation goals.

actor.isAINavigating

Checks whether the actor's AI Controller is currently navigating along a path (PathFollowingStatus is Moving). Automatically resolves from Pawn to Controller.

Usage

const navigating = await aiPawn.isAINavigating();

Returns

  • Promise<boolean>

actor.getAINavGoal

Retrieves the current navigation destination from the actor's AI Controller's PathFollowingComponent.

Usage

const goal = await aiPawn.getAINavGoal();
console.log(goal.x, goal.y, goal.z);

Returns

Team System

Methods for querying the Generic Team Agent Interface (IGenericTeamAgentInterface).

actor.getTeamId

Returns the Generic Team ID of the actor. Checks the actor first, then the pawn's controller. Returns 255 for NoTeam.

Usage

const teamId = await player.getTeamId(); // 255 = NoTeam

Returns

  • Promise<number>

actor.getTeamAttitudeTowards

Evaluates this actor's team attitude towards another actor using the Generic Team Agent Interface.

Usage

const attitude = await player.getTeamAttitudeTowards(enemy);
// Returns: 'Friendly' | 'Hostile' | 'Neutral'

Arguments

  • otherActorActorLocator
    The other actor to evaluate attitude towards.

Returns

  • Promise<string>

Visual Debugging & Overlays

Real-time viewport overlays, motion trail ribbons, direction arrows, and auto-updating stats billboards.

actor.drawTrail

Draws a real-time persistent 3D ribbon connecting the actor's positions as they move through the world.

Usage

await player.drawTrail({
  duration: 6,           // How long trail recorder runs (seconds)
  color: 'cyan',         // 'cyan' | 'magenta' | 'yellow' | 'red' | 'green' | hex (#RRGGBB)
  thickness: 4.0,        // Line thickness in viewport
  segmentDuration: 12.0  // Persistence of each drawn ribbon segment
});

Arguments

  • optionsTrailOptions(optional)
    Configuration object: { duration?: number, color?: string, thickness?: number, segmentDuration?: number }.

Returns

  • Promise<void>

actor.drawDirectionArrow

Draws a 3D arrow indicating the actor's forward facing direction or instantaneous velocity vector.

Usage

// Forward facing vector arrow
await player.drawDirectionArrow({ length: 200, color: 'cyan', duration: 5 });

// Velocity vector arrow
await player.drawDirectionArrow({ length: 200, color: 'yellow', duration: 5, useVelocity: true });

Arguments

  • optionsDirectionArrowOptions(optional)
    Configuration object: { length?: number, color?: string, duration?: number, useVelocity?: boolean, arrowSize?: number, thickness?: number }.

Returns

  • Promise<void>

actor.showStatsBillboard

Spawns a billboarded 3D text panel floating above the actor that rotates to face the active camera in real time, automatically re-querying live GAS attributes and UProperties every tick as stats change.

Usage

// Live auto-updating stats billboard floating above actor
await marshmallow.showStatsBillboard({
  attributes: ['Health', 'ToastLevel', 'MoveSpeed'],
  properties: ['bCanBeDamaged'],
  duration: 15,
  color: 'yellow'
});

Arguments

  • optionsStatsBillboardOptions
    Configuration object: { attributes?: string[], properties?: string[], duration?: number, color?: string, offset?: Vector3 }.

Returns

  • Promise<void>

actor.updateStatsBillboard

Reconfigures the active stats billboard on the actor on the fly, updating tracked attributes, properties, or display color.

Usage

// Reconfigure stats tracked on the fly
await marshmallow.updateStatsBillboard({
  attributes: ['Health', 'ToastLevel'],
  color: 'red'
});

Arguments

  • optionsStatsBillboardOptions
    Updated billboard configuration.

Returns

  • Promise<void>

actor.clearDebugVisuals

Instantly removes all persistent debug lines, motion trails, direction arrows, and stats billboards attached to this actor.

Usage

await player.clearDebugVisuals();

Returns

  • Promise<void>

Interfaces

ControllerInfo

interface ControllerInfo {
  isPossessed: boolean;
  isPlayerControlled: boolean;
  isLocallyControlled: boolean;
  controllerClass: string;
  controllerName: string;
}

StatsBillboardOptions

interface StatsBillboardOptions {
  attributes?: string[];
  properties?: string[];
  duration?: number;
  color?: string;
  offset?: Vector3;
}

TrailOptions

interface TrailOptions {
  duration?: number;
  color?: string;
  thickness?: number;
  segmentDuration?: number;
}

Vector3

interface Vector3 {
  x: number;
  y: number;
  z: number;
}

Rotator

interface Rotator {
  pitch: number;
  yaw: number;
  roll: number;
}

Transform

interface Transform {
  location: Vector3;
  rotation?: Rotator;
  scale?: Vector3;
}