How to use it
Three steps to being told what you want and nothing else.
1 Turn callouts on, then pick the ones you want.
2 Or just say it.
! The one that stops people.
Why it works this way
The things Directive 47 says without being asked, and what earns the right to interrupt.
1 NPCs announce themselves. It listens.
2 It matches on the message id, never on the words.
3 Urgent cuts in. Everything else waits its turn.
A warning arriving after Directive 47 has finished reading you a commodity list has arrived too late to be one. And a thing is said once as it happens: your shields going down is news; your shields still being down half a second later is not.
4 The model may ask what it is watching for. It may not switch one off.
One measured refusal worth knowing: Directive 47 never repeats Elite's own Material Content grade while prospecting. Across 1,633 prospects, Low and High rocks have the same distribution — and 45% of the rocks holding a material at 40% or more are graded Low. Passing that on would fly you past the best rock in the cluster.
The details
What Directive 47 says without being asked: danger, fuel, route progress, arrivals, material milestones, and an attack somebody has announced but not yet made.
All of it comes from the files Elite already writes, as they change. Nothing here waits on the language model, so a warning arrives when the thing happens rather than after something has finished thinking about it — which for an interdiction is after it is over.
Ask for it
“what are you watching for” “stop calling things out” “start calling things out”
I speak up about:
danger: on
announced-attack: on
fuel: on
route: on
long-jump: on
arrival: on
materials: on
rival-territory: on
Route progress every 3 jumps.
Home system is Shinrarta Dezhra.
What it speaks up about
Danger
Interdiction, shields down, hull damage, overheating, and a full cargo hold.
Said once as it happens rather than repeatedly while it lasts — your shields going down is news; your shields still being down half a second later is not. Submitting to an interdiction was your decision and is not read back to you as an emergency.
An urgent warning cuts in rather than waiting its turn. A warning that arrives after Directive 47 has finished reading you a commodity list has arrived too late to be one.
Every urgent one is preceded by an alarm, so you know what kind of trouble it is before the sentence has finished arriving. There are two, and which you hear tells you where to look:
| Sound | What it means | The answer |
|---|---|---|
| Falling three-note tumble | Somebody is hurting you — shot at, shields gone, hull opened | Fight, run, or high-wake |
| Three pulses on one note | The ship is cooking itself | The throttle, not the trigger |
Being pulled out of supercruise uses the same sound as the warning that one was coming, because it is the same situation a moment later.
The lines that are not emergencies stay quiet. A full cargo hold and the rebuy screen are worth saying and are not worth an alarm, so neither gets one.
Two alarms of the same kind seconds apart sound once. A pirate announcing an interdiction and then interdicting you is two warnings, both worth saying — but only one of them is worth a noise, because by the second one you are already looking. The words still come; the sound does not repeat.
Announced attacks
NPCs say what they are about to do before they do it. Directive 47 listens for that and tells you while there is still time to act:
Pirate lining up an interdiction. Boost or high-wake now.
Across 912 real journals, that line came a median of six seconds before the first shot and was right 88% of the time. A pirate demanding cargo gives eight seconds and is right 67%. Each situation gets its own sentence and its own sound, so you can tell an interdiction from a cargo demand from somebody who is here for you before the sentence has finished.
A hitman who has found you warns too, and shares the bounty hunter’s sound — because the answer is the same one, and cargo will not buy either of them off. That was measured the same way as the rest: the family that fires when a hunter spots you is followed by an attack 7 times out of 7, the strongest signal in the whole corpus.
Being hunted, which is not an emergency
Two other hitman families are a hunter talking about you rather than closing on you — the one that produced “the eagle is in the nest” is followed by an attack only 15% of the time. Warning you about those would be crying wolf six times in seven, so Directive 47 does not.
It does not ignore them either. Being hunted is a situation rather than an event, so you get a remark on it in your core’s own voice — no alarm, never interrupting, and once every ten minutes however much chatter arrives. It will not tell you why somebody is hunting you: the journal does not say, and inventing a reason is the one thing it must not do.
Directive 47 matches on Elite’s message ids, never on the words. That is not tidiness — it is the difference between a useful warning and an unusable one. The obvious approach, warning about anything that sounds hostile, was measured: one such message fires 2,399 times to catch 30 real attacks, and another is wrong 48 times out of 48. A hundred false alarms per real event is a warning you switch off within the hour and then do not have when it matters.
It is also what keeps it safe. In-game chat can be written by anyone in range, and matching on the text would mean matching on a string somebody else chose. The ids come from a fixed list, only NPC chatter is considered, and nothing the message says is repeated, shown, or passed to the language model — the spoken line is chosen by which id arrived and is otherwise a constant.
Fuel and range
Low fuel is the easy half. The half that matters is this one:
Route warning. Hyades Sector DB-X d1-112 is class T and cannot be scooped, and the jump beyond
it is 61.2 light years against a maximum range of 52.3. Replot before you jump.
That is not a low-fuel warning — your tank can be nearly full when it becomes true — and without it the first you know is when you are parked at a brown dwarf with no way out.
Every number in it came from your own game: the route and star classes from the route file, your jump range from your ship’s loadout, your fuel from the status file, and how much you actually burn per jump averaged from the jumps you have already made this session. Nothing is looked up anywhere.
Fly without a Fuel Scoop and none of this is said. Every line of it is about scooping — this star cannot be scooped, and here is what that costs you — and if you cannot scoop at all then the star being singled out is not the exception, it is every star on the route. Directive 47 goes quiet rather than rewording it. The low-fuel warnings stay, because those are about your tank, and flying without a scoop is when you want them most. It takes a loadout Directive 47 can see — and since it remembers what every ship of yours was last carrying, joining a session already in flight no longer means it cannot see one. Only a ship it has never watched you fly leaves it warning you as before.
Route progress
Jumps remaining, what is next, and what is coming:
14 jumps remaining. Next is Wredguia WD-K d8-30, scoopable.
Ahead on the route: Praea Euq QI-T d3-3 (a neutron star).
A hazard on the very next jump is always mentioned, whether or not it was a reporting jump. Arriving unprepared at a neutron star is the thing this exists to prevent, and every-five-jumps would miss it four times out of five.
Whether a star can be scooped is worked out properly rather than from the first letter of its class. The KGBFOAM rule gets two cases wrong in opposite directions, and both matter: Herbig AeBe stars start with A and cannot be scooped, while orange giants carry a suffix and can. A class Directive 47 does not recognise is called unknown rather than unscoopable — routing you around a star that would have refuelled you is its own kind of harm.
Fly without a Fuel Scoop and the clause is dropped entirely, so the line is just 14 jumps
remaining. Next is Wredguia WD-K d8-30. Reworded is no better than said: “scoopable” promises fuel
you cannot take, and “not scoopable” would imply the rest of the route would have been. It takes a
loadout Directive 47 can see, and the one it remembers for the ship you are in answers when this
session’s has not arrived — so only a ship it has never watched you fly leaves the clause as
before.
Long jumps
A little conversation during a longer-than-usual jump. It starts once you are actually in hyperspace, not when the drive begins charging — throttle up and cancel and you will hear nothing.
Arrivals
Your home system, where your carrier is, ships you have stored where you have just arrived, and stations that offer engineering.
There is no built-in list of which engineer lives where. That kind of list goes stale every game update, and inventing one is exactly the confident wrong answer Directive 47 is built not to give. Engineering is recognised from what the station itself advertises when you dock — which also means it keeps working when a new engineer is added.
Material milestones
Your first unit of a material, then a quarter, half and three-quarters full, a running count after that, and full.
Start Directive 47 after Elite and it catches up on the session so far first, so materials you already had do not all announce themselves as firsts.
Elite never reports how much of a material you can carry — the game simply stops accepting more — so the percentages come from a table of material grades built from the community-maintained id list that Coriolis and EDEngineer use, rather than from anyone’s memory. A material too new for that table still announces your first unit; the percentages stay quiet rather than being counted against a number nobody checked.
Rival Power territory
If you fly for a Power, Directive 47 tells you when you drop into normal space somewhere another Power controls:
Yuri Grom controls this system, and you fly for Edmund Mahon. You are exposed here.
Said once as you enter the condition, then silent for as long as it lasts. And explained once
per day, full stop — across restarts and whichever core is aboard, remembered in
view-state.json. Every exposure after the first that day, whoever controls the space, is four
words rather than the lecture:
Hostile territory. Be on guard.
It began as once per Power per session, and a day of re-launching proved the fourth hearing was not information either. One name is trimmed for the ear: the journal writes A. Lavigny-Duval, and a voice reading “A.” is reading punctuation, so she is spoken as Lavigny-Duval.
It waits until you are in normal space rather than saying it as you arrive, because arriving happens in supercruise and nothing can reach you there — that is measured, not assumed: across every Power security contact in 912 journals, none of them happened in supercruise and two thirds happened in normal space.
It also stands down for anything dangerous. A remark about enemy territory arriving as somebody opens fire is worse than silence, so if you are already being shot at, interdicted, or have just been told an attack is coming, this one is dropped rather than delivered late.
Your pledge is followed as it changes rather than read once at startup, so defecting does not leave Directive 47 calling your new Power’s space hostile.
What this is not. What you actually want is a warning when a Power Security ship shows up in your contacts panel — and no third-party app can see that. There is no event for a ship appearing, no file listing your contacts, and every signal about another ship requires it to have already done something to you. The message a Power’s security sends does exist and does name the Power, but it arrives about a second before the shot, which is a caption rather than a warning. So this says the thing it actually knows — that where you are is hostile — instead of implying somebody is close.
Checklist changes
Two moments from your checklist, both of which happen while you are doing something else.
A plan item the journal has changed its mind about. Selling the engineered multi-cannon un-completes the item that was tracking it, and Directive 47 says so — once, because the new verdict is written down as it is announced:
"Grade 5 Overcharged on Hardpoint 1" is no longer done. Nothing is fitted in Hardpoint 1.
A computed tick going backwards is information rather than a glitch to hide. You would otherwise find out by reading a list that had silently changed under you.
The last unit a plan needed. Netted across every live plan, because storage caps are shared and a shopping trip is a trip for everything:
That is the last Cadmium your plans needed. 12 of 12.
Switching this off silences both. It does not freeze the list — the verdicts stay up to date and the panel keeps showing them; a setting that did two things, one of them invisible, would be the wrong setting.
High grade emissions
When you arrive somewhere that could be running High Grade Emissions, which grade 5 materials would be in them:
Shinrarta Dezhra could be running high grade emissions for Core Dynamics Composites,
Proprietary Composites and Pharmaceutical Isolators.
Every row is the system’s allegiance plus a population over a million, and four of them add a state — which is the controlling faction’s, not any faction’s:
| The system | Emissions hold |
|---|---|
| Federal | Core Dynamics Composites, Proprietary Composites |
| Imperial | Imperial Shielding |
| Independent, controlling faction in Civil Unrest | Improvised Components |
| Independent, controlling faction in War or Civil War | Military Grade Alloys, Military Supercapacitors |
| Independent, controlling faction in Boom or Expansion | Proto Heat Radiators, Proto Light Alloys, Proto Radiolic Alloys |
| Independent, controlling faction in Outbreak | Pharmaceutical Isolators |
Alliance systems yield nothing, and systems under a million people are not mentioned at all. A minority Federal faction in an Independent system does not make it Federal — that reading once had Core Dynamics Composites announced in Oppi.
A system can still offer two unrelated groups, when its controlling faction is in two states at once. Civil Unrest and Expansion gives you Improvised Components and all three Proto materials.
Nothing is said about a material you are already full of, and a system whose materials are all full says nothing. So once you have finished gathering, this goes quiet on its own without your switching it off. Where D47 does not know a material’s cap it says it anyway rather than guessing you are full.
Said once per system, and never for the backlog D47 reads at startup — the only jump in that backlog you could still act on is the last one.
Nothing is said at all to a ship with no limpet controller fitted. The materials come out of an emission by limpet or not at all, so this is the same rule as the full hold at the other end of the same job. A Multi Limpet Controller counts, whichever kind it is — D47 does not work out which limpets each one carries, because going quiet on a ship that could have collected costs more than one sentence does to a ship that cannot. It takes a loadout D47 can see, and the one it remembers for the ship you are in answers when this session’s has not arrived — so only a ship it has never watched you fly leaves it telling you anyway.
And nothing is said with no limpets in the hold either, controller or no controller. A rack
with nothing in it collects exactly as much as no controller does, so the callout treats the two the
same rather than naming the emissions and adding a note about your hold. It needs a Cargo.json D47
has read, and one written for the ship rather than for the SRV under it — an unread hold is not an
empty one.
Limpet reminders
Off by default — this is for Commanders who fly limpets, and one who never does should not have to switch it off.
When you dock somewhere that sells limpets, with a big enough hold and few enough aboard:
No limpets aboard, and this station sells them. You have 256 tonnes to fill.
Limpets are bought through Advanced Maintenance, not the commodity market — which is why D47 looks for the station’s re-arm service rather than reading its market. Most stations have it; the ones that do not are on-foot settlements, small outposts, and carriers whose owner has not fitted it. Your own carrier may not be recognised, which is a known and accepted gap rather than a fault: of 136 limpet purchases measured, three were at a carrier that reported no re-arm service.
No price is quoted. Limpets are nearly always 101 credits and occasionally not, and D47 has no reading of this station’s price until after you have bought some.
Only remind me about limpets above
Cargo capacity, in tonnes. Default 64. Below it you are not running a limpet operation and the reminder is noise.
Remind me when limpets are under
A percentage of your cargo capacity. Default 5, so twelve limpets in a 256 tonne hold is low and thirteen is not.
Prospector results
What a prospector limpet found, spoken in the ring so you can keep your eyes on the rock instead of the panel. Richest material first:
Platinum, 58.3%.
Tritium, 23.5%, plus Liquid oxygen at 5.1%.
Platinum, 66.7%. Best you have found this session.
Directive 47 never repeats Elite’s own Material Content grade, and that is deliberate. Measured
across 1,633 prospects, Low and High rocks have the same distribution of best-material proportion
— medians of 19.9% and 20.3% — and 45% of the rocks holding a material at 40% or more are graded
Low. The example above, at 58.3% Platinum, is one of them. That grade is about the
engineering-material fragments a collector limpet picks up, not the commodity you are refining: two
different questions sharing a word. Passing it on would fly you past the best rock in the cluster.
“Best you have found this session” is relative, and says so. There is no fixed percentage that means “good” — Platinum’s median of 26.6% is above Water’s 90th percentile — so a single threshold would be wrong per material and silently so. What you have actually seen this session needs no table and adapts to whatever you are mining. The first rock is never announced as a best, because it is the only one.
A prospect arrives every 48 seconds at the median, which is about seventy-five lines in an hour of mining. That is why this has its own switch, separate from the one below.
Core asteroids
Core asteroid. Alexandrite.
Its own setting, because a core is 3 in 1,633 prospects. Turning the running commentary off must not cost you the one announcement you are actually mining for.
It is spoken as a routine line rather than an urgent one — urgent speaks over the top of whatever is being said and is reserved for danger and fuel. A core is exciting; it is not a safety matter, and announcing one across a hull warning would be the priority exactly backwards.
Sampling progress
Each organic specimen as it lands, with the distance you covered to get it:
Stratum Paleas, 2 of 3. 556 metres from the last one. 1 to go.
Stratum Paleas analysed. That run is complete.
The distance is what the callout is for — you can see the genus and you can count to three, but nobody can judge four hundred metres across a ridge, and getting it wrong wastes the sample. Directive 47 says how far you moved and never whether it was far enough: that figure is in the species’ Codex entry in-game, and no table of it ships here. See Exobiology for why.
Picking up where you left off
One line at the start of a session — a greeting on your own clock, and a readiness:
Good evening, Commander. Ready to go.
That is the whole of it, since 2026-08-21. It used to carry how long you had been away, the engineer in the system you were sitting in, and the top three items of your checklist read out in full — “Top of your list: Grade 5 Efficient Weapon on 2F Pulse Laser on Hammer (Type-11 Prospector); then…” — which is long, and arrives while you are still putting the headset on. If you want to know about your checklist, ask; it is all still there.
It waits a few seconds after launch so the journal backlog has been folded, says its line once, and does not speak again for the life of the process.
The first sentence is written by Directive 47. Where a persona is on, the core finishes the second — “Ready to reconcile the ledger”, “Ready to go, for the last time, again” — in a few words of its own and changes nothing else; with personality off it is “Ready to go.”
Adventure beats
A beat of the story you are following, said when you reach the place it waits for (list.md Phase 47). An adventure is a story the ship’s AI tells you across a flight — a spine, a handful of beats, each anchored to a real place by the one thing the journal can prove: you arrived in a system, docked at a station, landed on or scanned a body, or were promoted. The Adventures tab is where you write one or ask for one; this is the voice it reaches you by.
A short acknowledgement lands the moment the beat fires — “That’s it.”, “There it is.”, one of ten — so you know at once that you did the thing, rather than sitting through the wait below wondering. It is a stock line, never written by a model and never rewritten by one: a round trip is the delay it exists to arrive ahead of. The beat itself follows when it is ready.
The beat waits twenty seconds after it fires, so the line is not read over the jump it arrived on and three beats in a minute are not three model calls. A beat that comes due while you are being interdicted or the game says you are in danger is dropped rather than said late — the story is still in the conversation, so ask and the core picks it up. The opening, said when you accept a story, does not wait: you just pressed Begin.
With a language model configured the core aboard says the beat in its own voice, keeping every fact in it and adding none; without one, or with personality off, the authored line is read as written. The core knows what you know: the story’s premise and stake ride with every turn, the turn and the ending arrive only when their beats fire, and the beats ahead never do — so it can foreshadow, because the lines it was given do, and it cannot spoil what it has not been told.
Ossen's Lantern. The nebula is what is left of the star this white dwarf used to be. Scoop here.
Off leaves the story in the conversation and stops it being read out — the acknowledgement with it, since both belong to this callout.
While a beat is between firing and being said, the Adventures tab shows that the core is composing, on the desktop window and in the headset alike.
Community Goal sales
After every sale of the Community Goal commodity, where that leaves you this session, net of what the cargo cost (#296). The total rather than the sale, because the sale’s own figure is on your screen at that moment and the running position is not.
That's 2.1 million up this session.
The commodity is the one the saved Community Goal search names — Palladium unless you change it on the Routing tab’s Community Goal page — and the figures come from the ledger described on the community goals page. Nothing is said while d47 is catching up on a journal it did not watch being written. Switching this off stops the sentence and nothing else: the ledger keeps counting for the page and for “how have I done today”.
Settings
Speak without being asked
Off means Directive 47 only ever answers. Every warning above stops with it; everything else keeps running.
“stop calling things out” “start calling things out”
Route progress interval
In jumps. The right answer depends entirely on the trip: every 3 jumps is reassuring over 20 and
unbearable over 300. Set it to 0 to silence the progress line while keeping the hazard warnings.
Long jump threshold
In seconds, counted from entering hyperspace.
Home system
Where you consider home, for the arrival callout. There is no default — no journal event reports that.
The model can ask what Directive 47 is watching for; it cannot switch a warning off. Every toggle here is changeable from the panel, by a bound key, or by saying one of the phrases above — and not by anything the model calls. Directive 47 reads in-game messages from anyone in range, and a model that could disable the interdiction warning is one that could be told to by the Commander doing the interdicting.
In Ship chatter
Who it is: your ship’s AI and your crew — the voices inside your ship, as against the NPC chatter below, which is everybody outside it. Only the AI speaks unasked; your crew answer when you address them.
The occasional in-character line to you, said because nothing has happened. Everything else on this page speaks because something did. Spoken to you rather than narrated, on purpose: the brief tells the core it is talking to its Commander, not describing the view, so a remark is a dry aside in the cockpit and never a scene from a novel.
Three rules keep it from being noise. It waits out an interval — and that interval is a range, not a tick: each gap lands somewhere between the least and the most time rows, five to ten minutes out of the box, because the same voice arriving on a beat is the most clocklike thing this app could do. Setting the two equal pins it; 0 on the least silences it. In seconds rather than minutes because the interesting end of the range is finer than a minute. It waits for the situation to have settled for ninety seconds rather than firing on the transition, because Status.json flips several times a minute during an approach and a remark about being docked that arrives as you are lifting off is worse than silence. And it never remarks on the same situation twice running.
A fourth rule is not this feature’s own: a line from inside your ship and an exchange from outside it are never spoken back to back. That one is a rule between the two, and it is explained under NPC chatter below.
Seven situations are covered: docked, landed, supercruise, normal space, fuel scooping, in the SRV, and on foot.
The core aboard writes every remark itself and it is genuinely theirs — Chart will tell you about the sky, the Quartermaster about what the run cost. It also knows who it is flying with: your character sheet goes with every remark, and your About Me story with about one in four, so the remarks differ by who is flying and not just by wording.
Chatter is model-written or it is nothing. With no language model configured there are no In Ship chatter at all, and these rows are absent from this page — a switch governing something that cannot happen would be a switch that does nothing. The ten authored lines per situation are what the model is shown as a sample of the register, never a stand-in read out in its place: a remark the model did not write for this moment is not spoken.
The drive note has not changed in some minutes. That is what it sounds like when it is right.
NPC chatter
Who it is: anybody outside your ship — as against In Ship chatter above, which is your own AI and crew.
Made-up radio traffic from people who do not exist: two crews on the local channel about their own small business, the dock telling an invented pilot off when you are docked somewhere, and — about one exchange in four — one line said to you over the open channel. Statements only, never a question: nothing here is ever answered, by you or by the ship’s AI, and none of it enters the conversation or the comms record. It is theatre, heard once.
Parked on your own carrier, it knows whose deck it is standing on. Its tower controller and its captain are cast as real people rather than invented, and everyone in the scene is told how to regard you: your own crew are not surprised you are aboard, and write it as deference or an easy grumble made to you; a visiting pilot docked at somebody else’s carrier is the one who can be surprised, careful, or embarrassed to have been overheard. Ownership colours at most one exchange per visit as the thing actually being talked about — the rest may show it without a line remarking on it — and none of this fires at all until you are actually on the carrier’s deck.
This is not the game’s own NPC traffic. Elite’s real messages — station chatter, pirates, your wing — are re-voiced under Speech → Speak incoming messages, and they are somebody else’s words. NPC chatter is Directive 47’s own fiction, on its own switch, so you can have either without the other.
Each invented speaker gets their own voice from the NPC pool for as long as you stay in the system, the same way the real traffic is cast — and keeps it through the exchange even when the model shortens Courier Vance to Vance on his next line, because the two spellings are read as one person before either is voiced. The exchange is written by the model against where you actually are; with no language model configured there is no chatter and these rows are absent, the same rule as the In Ship chatter above — there are no canned conversations, on purpose.
The gap between exchanges is a range, not a tick: each wait lands somewhere between the least and the most time rows — five to ten minutes out of the box — because overheard traffic on a fixed cadence stops sounding overheard. Setting the two equal pins it; 0 on the least silences it. The two pairs carry the same numbers on purpose, so the two kinds of chatter arrive at the same rate and what varies is the mix.
And the two are kept apart from each other. They used to be timed independently and blind to one another — two clocks, neither able to see the other — so nothing stopped a remark from inside the ship and a four-line scene from outside it arriving nose to tail. Worse, the two were due on the same tick at the start of every session, by construction. Now there is a floor of ninety seconds between any two unprompted lines, whichever kind either of them is, and the two schedules no longer move together.
Three things about that floor are worth saying plainly. It never reaches anything urgent — danger, fuel and the rest exist to interrupt, and none of them ever waits on chatter. It is never longer than the shorter of your two “least time” rows, so it cannot overrule a setting: turn either kind down to twenty seconds and the floor is twenty, both ways round. That matters in both directions — a voice you have set to speak every twenty seconds cannot claim ninety seconds of quiet behind it, because it would be breaking that quiet itself long before it was up, and the other kind would go silent instead of being spaced out. And the one that does not go is held rather than lost — it arrives as soon as the air clears, keeps its turn, and costs nothing, because an exchange stopped this early is never written in the first place.
When both fall due at the same moment the exchange goes and the remark waits, because a remark will be along again shortly and an exchange will not.
It is not a settings row, for the same reason the beat inside an exchange is not one: it is something to get right rather than something to adjust. What you set is the rate.
The lines of one exchange are spoken with air between them — somewhere between six tenths of a second and one and seven tenths, and never the same gap twice, because two people who never once leave a pause read as a script being performed rather than as traffic overheard. It is not a settings row on purpose: the beat is something to get right rather than something to adjust. An urgent callout waiting behind an exchange cuts those pauses short, so a fuel or danger warning is never held up by a courier chatting.
Talking to Directive 47 ends the exchange. The moment you open the microphone, the chatter line being spoken is cut off mid-word and the rest of the exchange is dropped rather than kept for afterwards — you are asking, so the answer comes first, and losing half an overheard remark does not matter. It happens when you start talking rather than when the answer arrives, because transcription and the model together take several seconds and an exchange runs to its end inside them. And chatter stays shut off until the answer is done and the loop is quiet again, because the next speaker is written and voiced while the first is still talking, and would otherwise arrive a second after you cut them off. Nothing else goes with it: a message the game sent you and a callout you switched on both keep their place in the queue and are still spoken. And only you do this — an unprompted line of Directive 47’s own waits its turn like anything else.
“stop calling out npc chatter” / “start calling out npc chatter”
Switching personality off silences these entirely, which is the one place that switch reaches a callout. It is in that item’s own acceptance criteria: plain answers, no flavour, no chatter of either kind.
Set the interval to 0 if you want the switch without finding the switch.
The tool surface, for contributors
get_callouts
Read-only. Takes no arguments.
{"type":"object","properties":{},"required":[],"additionalProperties":false}
Two sources feed the warnings, deliberately. The journal reports transitions — shields went
down, hull was hit — and Status.json reports conditions — shields are still down. A
warning built on events alone goes quiet the moment the game stops repeating itself; one built on
conditions alone cannot tell a new emergency from an ongoing one. Conditions announce on the edge
into the condition, because Status.json is rewritten several times a second and announcing on
the level would be a warning per tick.
The material grade table is derived, not written. tools/gen-material-grades.py generates
MaterialGrades.g.cs from EDCD/FDevIDs material.csv. The
generator is not part of the build and the app never runs it or reaches the network for it; its
output is committed and regenerated when Frontier adds or reclassifies a material. This is not
academic: the first draft of the tests asserted Antimony was grade 5, from memory. The derived
table said grade 4, and it was right — raw materials come in categories of four graded 1–4, so no
raw material is grade 5 at all. A hand-written table would have shipped that error, and it would
have surfaced as a milestone firing at the wrong count with nothing reporting a problem.
The grade-to-capacity rule — 300/250/200/150/100 for grades 1–5 — lives beside the generated table rather than in it: five numbers that do not change when Frontier adds a material, so regenerating cannot disturb them.
The tick loop is synchronous and must not block, so a callout does not speak. It returns an
Announcement, the engine queues it, and the app drains that queue onto the thread pool.
Announcements are spoken one at a time in the order queued — two synthesised concurrently would
arrive in whichever order the network returned them, and “shields are down” is not
interchangeable with “route complete”. An urgent one silences the queue before speaking, on the
Alert channel above Speech in the one audio arbiter.
Condition-based warnings carry a cooldown keyed by what they are about, coarse enough that a repeat is suppressed and specific enough that a different warning is not. A callout that throws is logged and skipped and the rest still run: one broken callout must not take the danger warnings down with it.
An announcement may also name an alert cue — a short sound played immediately ahead of it, on
the same channel, so the queue orders the two. Cue names are bound to the AlertCue members the
same way loop-state cues are bound to LoopState: the file is named for the member and the library
asserts the shipped set matches the enum, so a member added without a clip fails at startup rather
than going wrong as silence. That matters more here than it does for the loop states, because a
warning that did not fire and a warning whose cue would not load sound identical.
The measurements behind both Phase 15 warnings — every id group’s follow-through rate and lead time, the groups measured and deliberately not shipped, and what the journal does and does not report about Powerplay — are in docs/spikes/journal-corpus-warnings.md.