Docs Menu
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
| Name | Type | Description |
|---|---|---|
| xAxis | string | The X axis name (e.g. 'Gamepad_LeftX'). |
| yAxis | string | The Y axis name (e.g. 'Gamepad_LeftY'). |
| startTimeMs | number | When the circle should begin in the timeline. |
| durationMs | number | How long the circle should take to complete. |
| rotations | number | Number 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
| Name | Type | Description |
|---|---|---|
| axis | string | The axis name (e.g. 'Gamepad_RightTrigger'). |
| startValue | number | The initial value (e.g. 0.0). |
| endValue | number | The final value (e.g. 1.0). |
| startTimeMs | number | When the sweep begins. |
| durationMs | number | How 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
| Name | Type | Description |
|---|---|---|
| startTimeMs | number | When the combo should start. |
| frameDelayMs | number | The 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
| Name | Type | Description |
|---|---|---|
| timeMs | number | The exact timestamp for this frame. |
| state | Object | The state of the inputs, e.g. { axes: { ... }, buttons: { ... } }. |
Returns:SpecterInputSequence (this)