Input macro (asset type)
The engine deliberately does NOT ship per-feature input recipes (walk, sprint, drive). Authors record or hand-write the macro they need; the playback primitive is type-agnostic.
When to use one
- You want to script an input sequence for testing (e.g. "walk forward 3 seconds, jump, look around").
- You're capturing a demo / repro of a user interaction sequence.
- You want deterministic input playback across runs.
If you need per-frame programmatic input (more than a fixed sequence
allows), drive the inputSim toolbox's key / click tools directly from
a script. If you need real input handling, that's the input API
(man input).
Where it lives
- Source:
/zero/source/.../<name>.inputMacro/ - Identity:
<name>(the.inputMacrosuffix strips). - Folder shape:
events.json— JSON array of{ t, op, arg }event tuples. Required..metadata— agent-editable tags + free-form fields. Required.
How to create one
Two paths:
-- Record a live sequence: recordMacro captures real input for
-- `duration` seconds and returns the recorded events; saveMacro
-- persists them as the asset.
local events = tools.use("inputSim", "recordMacro", { duration = 5 })
tools.use("inputSim", "saveMacro", "<name>", events)
-- Hand-author an empty macro scaffold and fill events in:
asset.create("inputMacro", "<name>")
The record path is preferred for sequences any human could perform; hand-authoring is for synthetic or precisely-timed sequences.
How it operates
- Event format.
events.jsonis a JSON array of triples:{ "t": 0.5, "op": "keyDown", "arg": "KeyW" }t: seconds since macro start.op: the name of aninputSimverb that drives input — the keyboard and mouse verbs (keyDown,keyUp,key,mouseDown,mouseUp,mouseMove,mouseMoveBy,click,scroll,lockPointer), the pad verbs (pad,padOff,padDown,padUp,padPress,padStick,padTrigger) and the touch verbs (touch,touchDown,touchMove,touchUp,stick,tapButton,drag,pinch).arg: that verb's arguments — the value itself when the verb takes one (a key code such as"KeyW", a mouse button index where 0 = LMB, 1 = RMB, 2 = MMB, a canonical pad button name such as"south"), or a table keyed by the verb's parameter names when it takes several ({ dx = 200, dy = 0 }formouseMove,{ stick = "left", x = 0, y = -1 }forpadStick,{ x = 714, y = 984, id = 1 }fortouchDown).
- Playback.
tools.use("inputSim", "macro", "<name>")schedules every event at itstoffset relative to playback start; events are played in order oft, and events sharing onetplay in the order the list writes them. The same tool takes an inline event list or anAssetRef<inputMacro>instead of a name. - Determinism. Macros are deterministic relative to engine state at playback start — same start state + same macro = same end state.
- Recording.
tools.use("inputSim", "recordMacro", { duration = n })polls live input state and returns the recorded events;tools.use("inputSim", "saveMacro", "<name>", events)writes them to/zero/source/<name>.inputMacro/events.jsonand returns the macro'sAssetRef.
Discovery
asset.list("inputMacro")— every registered macro.asset.inspect("<name>")— event count, duration, source, this type README.ls /zero/source/<name>.inputMacrolists the files the folder holds.tools.use("inputSim", "listMacros")— every registered.inputMacro.
Authoring conventions
- Start macros from a known state (call
layers.load("base")before playback) so determinism holds across runs. - Keep macros focused on one user-facing action sequence. Longer
macros are harder to compose and debug; chain shorter ones via
tools.use("inputSim", "macro", "a")thentools.use("inputSim", "macro", "b"). - Keep the expected start state and end state in mind when you name a macro: what scene / mode / focus the playback assumes.
Common pitfalls
- Non-deterministic start state. Playing a macro from a different starting scene produces different outcomes. Always lead with a scene load.
- Frame-rate dependence. Times are in seconds; the dispatcher schedules events relative to wall time, not frames. Effects that depend on per-frame logic may diverge across hardware.
mouseMoveargument. It carries a{ dx, dy }delta, the same shape the recorder emits. Check the recorded values match.
Related types
.tool— for agent-callable input wrappers that may invoke macros as part of larger flows..scene— macros pair with scenes for deterministic test setups.
In the Inspector
Events: how many events the macro records, when the last one fires, and the first 50 events in order (time, op, argument). Replaying it stays in Operations.