AI chatbot and chat assistant for your Factorio server: ask a question in game chat and the AI answers in chat from your live save. Where things are, production rates, research, what changed since you died. Multiplayer, every team and force, follow-up questions. Bring your own key: Claude, GPT, DeepSeek, Gemini or any LLM on OpenRouter. Runs with a small agent program beside the server.
Providing the player with new tools or adjusting the game interface, without fundamentally changing gameplay.
Version: 1.0.5
Date: 2026-09-16
Changes:
- sweep: one tool for every "which team has the most" question. Name a metric and, if it
needs one, a subject; get one row per force, largest first, ranked by the service with the
leader and its margin on top. metric is a closed list the tool's own description carries, and
an unknown one answers with a card for each rather than an error. axis groups the rows by
surface, space platform, player or force-and-surface instead of by force. Every metric
delegates to a tool that already exists, so nothing is measured twice, and a sweep the
companion would have to cut is refused whole rather than ranked over whoever survived.
- sweep gained six more metrics, each delegating to a tool this mod already ships rather than
measuring anything a second time: item_made and item_rate (how much of one item a force has
made, ever or right now), pollution and evolution (per surface, and per force for
evolution), and robots and networks (logistic robots and logistic networks a force has,
summed over its surfaces by default). logistics_summary takes an additive contents=false so
robots and networks never pay for a network's item contents, the one expensive read that
tool does.
- Four new lookups, and a sweep metric for each: kills and built (how many enemies a force has
killed and lost, how many entities it has built and mined back, summed over every surface
unless one is named, with a largest-first breakdown of the kinds), fluid_rate (production and
consumption of one fluid, per minute, the fluid version of item_rate), and trains (how many
trains a force has, and how many are moving or under manual control right now). Each takes
all=true the same way rockets and entity_count already do, so "which team has killed the
most" or "how many trains does each team have" is one call.
- list_surfaces says which space platform a surface is, who owns it, where it is stopped and
what it is doing, so "which space ship" questions no longer guess an owner force by force.
- entity_count takes all=true and answers for every force that has players in one call, one row
each, largest count first, so "how many solar panels does each team have" is one lookup and
not one per team. Leave surface out and it reports each force's total everywhere from the
counter the engine already keeps, which costs nothing whether a server runs 4 teams or 40.
Name a surface when the answer has to be about that one place, and that path counts one pass
per force and refuses rather than half-answering if even that would be too many.
- entity_count's all=true also takes per_surface=true, breaking each force's count down by
surface instead of totalling it: one row per team-and-place that actually has some, empty
combinations left out, platform rows carrying the same owner, location and state columns
list_surfaces does. This is what makes "which space ship has most thrusters, where is it"
one call instead of a many-round search.
- Team names print in the colour the team mod gave them. A labels provider may colour a label,
the way a team mod colours its teams, and the companion used to strip every tag from it, so
a team name never once printed in its colour. The colour and font tags a label carries are
kept now, and a label the model copied out of a tool result prints in the colour too.
- Player names print in the player's own chat colour, the one the game prints their chat in.
No team mod is involved: every player has one, and the companion reads it when it renders.
- A space platform row, from sweep or from entity_count's per_surface, carries who owns the
ship, where it is stopped, and a gps at its hub on its own surface, so "which ship has the
most, where is it" is one row and one click.
- entity_count's per_surface walk skips a force that owns none of the entity anywhere, one
O(1) read instead of a pass per surface, and counts a platform for its owner only. On a
30-surface, 16-team save the thrusters question cost 480 passes and 1.26 seconds on the
game thread; it is a few dozen passes now.
- Agent program: the OpenRouter upstream host can be pinned, providers and allow_fallbacks
under model in aab.yaml. The hosts behind one model differ by about three times in answer
time and the prompt cache is per host, so a pinned host keeps answers fast and the cache
warm.
- Agent program: every answer is read back the way the player sees it and logged, and the log
says so when a second agent program is answering the same server.
Bugfixes:
- A line clipped in the middle of a colour tag printed raw, tags and all. The mod and the agent
program both close the span they cut now.
- top_items sorted its rows on the rounded rate, a number for a whole rate and a text for a
fraction, and Lua throws comparing the two, so "what do we make most" answered with an error
whenever one item's rate happened to be whole beside another's that was not. Sorted on the
raw rate now, rounded only on the way out.
- list_forces hid the asking force whenever nobody had joined it. Forces nobody has ever joined
are left out as empty slots since 1.0.3, and on a server with no one connected that is every
force, the asker's included: "what forces are there" answered with none. The asker's own
force is always listed now, whoever has joined it.
- list_forces counted the engine's own enemy, neutral and player forces as empty team slots,
so "how many teams" reported three slots more than the server had, and a listing with
include_empty=true let the model count them again for itself. empty counts only team slots
now, either way, and the engine's rows carry engine=true so they are never mistaken for one.
- list_surfaces returned 20 rows by default, sorted by name, and a space platform is named
platform-N, so every platform sorted after every planet and fell off the end. On a server
with 25 surfaces the reply held no platform at all, which is why "which space ship has most
thrusters" guessed a platform name before it had seen one and then spent a round listing
again with a limit. The default is the cap now.
- list_surfaces said nothing about who owned a platform or where it was stopped, so seeing a
name in the list still left a 5-platform, 14-force cross product to search by hand. A
platform row now carries platform, owner, location and state. scheduled_for_deletion is a
tick count, not a boolean, so a platform mid-deletion reads as an ordinary row rather than a
half-built one.
- find_entities carried no cost tier, so the trace that started this release answered a
counting question with fifteen position walks and zero entity_count calls. find_entities is
tier 2 now; entity_count, which asks the engine for a number instead of walking positions,
stays tier 1.
- rockets with all=true sorted its rows by force name before cutting them to the row cap, so a
server with more forces than the cap discarded the biggest launcher first, on the one tool
whose purpose is naming the biggest. Largest first now, force name only as a tiebreak.
Version: 1.0.4
Date: 2026-09-14
Changes:
- list_players takes all=true and answers for every player on every force in one call, so
"who is online" is one lookup, not one per force.
- rockets takes all=true and answers for every force that has players or has launched a rocket
in one call, so "how many rockets has each team launched" is one lookup, not one per force.
Item lists stay a single-force answer.
- The tools op, which reads the whole catalog at once, is capped at 32 KB rather than 8 KB,
the room the manifest op has always had. The companion's own catalog had grown to within
13 bytes of the old cap, where one more sentence of tool description would have turned
every catalog read into a refusal.
Bugfixes:
- find_entities named a product or recipe but no type scanned every entity the force owns on
the surface, capped at 2000, which on a busy server was belts and inserters discarded by the
filter before a crafting machine was ever reached. "Where are we making red ammo" answered
that no machine made it on a server with six. A search naming a product or recipe but no
type now asks for the three crafter types instead.
Version: 1.0.3
Date: 2026-09-11
Changes:
- list_forces leaves out forces that have never had a player, the team slots a scenario mod
makes in advance and the engine's own, unless asked with include_empty; the reply counts
what it left out. An agent asked about "each team" no longer sees twenty empty slots.
- current_research takes all=true and answers for every force that has players or is
researching in one call, so "what is each team researching" is one lookup, not one per
force.
Version: 1.0.2
Date: 2026-09-11
Changes:
- A force's total production no longer depends on guessing its surface: production_since
takes the surface as optional and, without one, counts every surface the force has made
the item on, with a per-surface breakdown. Since tick 0 the count is exact, from the
game's own lifetime counters.
- The production tools say plainly which is a rate and which is a total, so "how much has
team 2 made" is answered with a total and "how fast" with a rate.
- Every lookup accepts a force's display name where it expects a force name, "Team 02" for
team-2, resolved through the team mod's labels, so an agent that read a name in a tool
result and passed it back still reaches the right force.
- A comparison with a blank column name prints a letter in its place rather than nothing.
Version: 1.0.1
Date: 2026-09-11
Changes:
- Compare teams on their own clocks: on a Multi-Team Support server the agent now reads
each team's online and elapsed hours from the team mod, and the game clock is named as
the server's clock, so "how am I doing compared to Team Ace" compares fairly.
Bugfixes:
- Fractions (rates, progress, evolution, hours) reached the model as fifty-digit numbers,
because the game's JSON writer prints a non-integer double at full precision. They now
leave as short decimals, "1.79", and whole numbers stay numbers.
Version: 1.0.0
Date: 2026-09-11
Features:
- Ask the AI in chat: /ask a question, or a chat prefix of your choice, and the answer prints
back in chat a few seconds later, pulled from the live save at that moment.
- Follow-up questions share a session. /ask new starts over, /ask #name opens a named session
others can join, /ask sessions lists what is open.
- Any player may ask about any force. Team chat privacy and team names come from mods that
have them (Multi-Team Support), so a team in team-only chat gets private answers.
- Answers with item icons, clickable item and recipe tags when you ask about a thing itself,
and map pings you can click for "where" questions, ghosts included.
- Seventeen lookups on the live game: forces, players, surfaces, research and the queue,
production rates and totals since a tick, logistic networks, entity counts, evolution,
pollution, rockets, game time, where entities are, where a player is; plus history
(deaths, joins, chat, research, rockets) from the event log.
- Other mods add their own lookups by exposing one function; the mod never needs to know them.
- Safety: the rpc command runs for RCON only, asking is rate limited per player and per
server, refusals are private, every lookup is a bounded read.
- The mod is the game side of an open protocol over RCON. The agent program on GitHub uses
your own OpenRouter or Anthropic key and any model you pick; anyone can write another.