class: SpecterInputSequence

A builder class used to generate mathematically accurate timelines of input data. Instead of firing simple one-off keys, SpecterInputSequence allows you to define complex patterns (like joystick circles or fighting game combos) and stream them frame-by-frame to Unreal Engine using Specter's high-resolution execution loop.

How it Works

Once you build an input sequence, you can play it on the entire world or localized to a specific actor using world.playSequence(seq) or actor.playSequence(seq). The framework yields to the Node.js event loop using performance.now() to guarantee hyper-accurate delivery of input frames to the engine.

sequence.addAxisCircle

Generates a perfect analog circle using Math.sin and Math.cos on two axes.
import { SpecterInputSequence } from '@specter/test';

// Does two full circles on the left thumbstick over 1.5 seconds
const spinAttack = new SpecterInputSequence()
    .addAxisCircle('Gamepad_LeftX', 'Gamepad_LeftY', 0, 1500, 2);

await world.playSequence(spinAttack);

Arguments

NameTypeDescription
xAxis stringThe X axis name (e.g. 'Gamepad_LeftX').
yAxis stringThe Y axis name (e.g. 'Gamepad_LeftY').
startTimeMs numberWhen the circle should begin in the timeline.
durationMs numberHow long the circle should take to complete.
rotations numberNumber of 360-degree rotations to perform.
Returns:SpecterInputSequence (this)

sequence.addAxisSweep

Smoothly interpolates an analog axis from a start value to an end value over time. Perfect for triggers or racing games.
const accelerate = new SpecterInputSequence()
    // Squeeze the right trigger from 0% to 100% over 2 seconds
    .addAxisSweep('Gamepad_RightTrigger', 0.0, 1.0, 0, 2000);

await playerCar.playSequence(accelerate);

Arguments

NameTypeDescription
axis stringThe axis name (e.g. 'Gamepad_RightTrigger').
startValue numberThe initial value (e.g. 0.0).
endValue numberThe final value (e.g. 1.0).
startTimeMs numberWhen the sweep begins.
durationMs numberHow long the interpolation lasts.
Returns:SpecterInputSequence (this)

sequence.addCombo

Strings together an array of button states with precise delays between them. Perfect for fighting game inputs.
const hadouken = new SpecterInputSequence()
    .addCombo(0, 100, [
        { 'Gamepad_DPad_Down': 'Pressed' },
        { 'Gamepad_DPad_Down': 'Released', 'Gamepad_DPad_Right': 'Pressed' },
        { 'Gamepad_FaceButton_Bottom': 'Pressed' }, // Punch!
        { 'Gamepad_FaceButton_Bottom': 'Released', 'Gamepad_DPad_Right': 'Released' }
    ]);

// Play the combo and loop it 3 times!
await world.playSequence(hadouken, { loops: 3 });

Arguments

NameTypeDescription
startTimeMs numberWhen the combo should start.
frameDelayMs numberThe time delay in milliseconds between each step of the combo.
keyframes Array<Record<string, string>>An array of key states (e.g. { 'Gamepad_DPad_Down': 'Pressed' }).
Returns:SpecterInputSequence (this)

sequence.addKeyframe

The low-level base method for defining procedural patterns. Adds a single explicit state of inputs at a specific timestamp.
// Example of creating a custom procedural easing curve
const customAim = new SpecterInputSequence();

for (let t = 0; t <= 1000; t += 16) {
    const easeInQuad = (t / 1000) * (t / 1000);
    customAim.addKeyframe(t, { axes: { 'Gamepad_RightX': easeInQuad } });
}

Arguments

NameTypeDescription
timeMs numberThe exact timestamp for this frame.
state ObjectThe state of the inputs, e.g. { axes: { ... }, buttons: { ... } }.
Returns:SpecterInputSequence (this)