How to use it
Three steps to a name that runs a sequence.
1 Turn on key injection, then write the macro.
2 Say the name.
! The one that stops people.
Why it works this way
Your own named sequences of ship actions. Say the name, and they run in order.
1 You write them down, not out loud.
2 It stops before it starts.
3 A macro can only say what you could already say.
4 A bad one is refused by name, with the reason.
The details
Your own named sequences of ship actions. Say the name, and Directive 47 runs them in order.
Ask for it
“docking prep” “run docking prep” “what macros do I have”
The name is whatever you called it. Both “the name” and “run the name” work, and neither needs the AI to be configured — a macro is the most closed vocabulary there is, because you wrote it.
Writing one
Macros are the one thing here you cannot set up by voice, and that is deliberate. Everything else Directive 47 does has a fixed list of words behind it; composing a new sequence does not, and it never can. So authoring happens in the panel or in the file.
In the panel: Settings → Macros → Edit macros. Each step is a drop-down of actions, a drop-down of on / off / toggle, and a pause in milliseconds. There is nothing to type but the name, so nothing you build there can be rejected.
In the file: data/macros.json, beside the executable like everything else Directive 47
writes.
{
"macros": [
{
"name": "docking prep",
"steps": [
{ "action": "landing_gear", "state": "on", "pauseMs": 200 },
{ "action": "lights", "state": "on" }
]
}
]
}
Both routes write the same file, and it is re-read while Directive 47 is running — a macro saved in a text editor is sayable a moment later, with no restart.
The pauses matter
Elite’s panels animate. Without a pause, the second keystroke of “open the right panel, then go down twice” arrives before the panel is there. 250 ms is the default and is usually enough.
What a macro is allowed to do
Only actions Directive 47 already has — the same list that “gear down” comes from. It cannot express a key that is not already reachable by asking out loud.
Two limits worth knowing:
- No weapons. The fire groups exist internally for the arrival honk, and macros cannot reach them. A macro is authored text, and authored text must not be a way around the rule that the AI never gets to open fire.
- No taking a name that already means something. A macro called “gear down” is refused, because otherwise two things answer to it and you cannot tell which one ran.
When something is wrong with one
A bad macro is never silently dropped — that would leave you saying a phrase with nothing to act on it for a week. It is refused by name, with the reason, in the editor and in “what macros do I have”:
- Refused: "combat" uses an action D47 does not have: shields_up.
One bad macro does not cost you the others. The rest of the file still loads.
It stops before it starts
Every step is checked before any of them is sent. If the fourth action is on your joystick, the macro does not run at all rather than pressing the first three and leaving the ship half configured in a state you did not ask for and have to work out for yourself.
Steps already in the state you asked for are skipped, so a macro that puts the gear down does nothing about the gear when it is already down.
Macros need Let Directive 47 press keys in Elite switched on — see Flight and navigation.
The tool surface, for contributors
list_macros
Report the Commander’s macros, their steps, and any that were refused. Takes no arguments.
{"type":"object","properties":{},"required":[],"additionalProperties":false}
run_macro
Run one of the Commander’s own named macros. Only names listed in the current game state exist; anything else comes back saying so.
{"type":"object","properties":{"name":{"type":"string","description":"The macro\u0027s name, as the Commander wrote it."}},"required":["name"],"additionalProperties":false}
The name is a free string rather than an enum, and that is not laziness. Macro names change whenever the file is edited, and a schema that changed with them would invalidate the entire cached prompt prefix. The names available now ride in the live game-state block below the cache breakpoint, and the handler enforces the list regardless of what the model asked for.
The model-free route needs the same trick from the other end: descriptors are registered once and never mutated, so macro phrases reach the keyword router through a function it consults rather than through the descriptor. A macro name never enters a schema, so nothing about caching is affected by letting that source change.