Routes players between the servers of a split Factorio world. This server handles one planet (or the space platforms); the manager tells it what the others are.
Lua libraries for use by other mods and submods that are parts of a larger mod.
Version: 0.41.0
Date: 2026-11-08
Major:
- runtime manager traffic now uses the generic udp-net library. The connector-call console
command and remote interface are removed.
- connector ledger support: absolute per-item startup application and a one-item-per-second
runtime probe.
- freshness reset is now every 1 second (60 ticks), still connector hubs only.
- narrow server-connector-bootstrap pause|unpause command for a save that opens tick-paused.
Fixed:
- the boot ready event is gated on the manager identity.
Version: 0.40.8
Date: 2026-11-08
Fixed:
- removed the space-server Nauvis startup clear. The server log shows it deleting 3312 entities and 113 chunks on the same tick the client was catching up, immediately before the first CRC failure.
- reverted the 0.40.6 live-write gate and the 0.40.7 periodic-sweep removal; neither was the cause.
Version: 0.40.7
Date: 2026-11-08
Fixed:
- the periodic freshness sweep is disabled. It could run while a client was still connecting (before connected_players included them) and caused a CRC desync on space join. Freshness is now reset only during configuration/startup and while the fleet is empty.
Version: 0.40.6
Date: 2026-11-08
Fixed:
- automatic request-group writes are deferred while any player is connected, and the freshness sweep also waits for an empty fleet. Live script writes to hub groups/inventories were not client-replicated and caused space joins to desync after a landing-pad edit.
Version: 0.40.5
Date: 2026-11-08
Fixed:
- freshness reset no longer aborts on the first non-spoiling item. `spoil_ticks` is optional and is now read defensively, so the sweep actually reaches the eggs and other spoilables.
Version: 0.40.4
Date: 2026-11-08
Fixed:
- freshness reset now rewrites spoil_tick as well as spoil_percent. Resetting only the percentage left an expired absolute timer that could still convert the stack.
Version: 0.40.3
Date: 2026-11-08
Fixed:
- the first configuration change after loading an older save resets connector freshness immediately, before the first normal spoilage tick, instead of waiting up to 10 seconds.
Added:
- connector_spoilage diagnostic returns the spoil percentages from both copies of every planet connector.
Version: 0.40.2
Date: 2026-11-08
Fixed:
- freshness reset now covers both copies of every planet connector: the planet hub and the matching space-side hub. Real platform hubs are untouched.
Version: 0.40.1
Date: 2026-11-08
Fixed:
- a mod update no longer destroys and recreates every connector platform, and no longer clears connector hub inventories. That reset wiped the cargo-bay layout and every item in the hub, which looked like a random loss.
Added:
- connector_spoilage is a read-only diagnostic for reproducing freshness issues.
Version: 0.40.0
Date: 2026-11-07
Added:
- planet connector hubs reset every spoilable stack to 100% freshness every 10 seconds. The space-side copies are not touched.
- the space server clears every entity and generated chunk from its unused Nauvis surface on startup, once no player is connected.
Changed:
- platform requests with no import planet (missing, empty, any or all) are no longer copied into every planet's automatic Outgoing group.
Version: 0.39.9
Date: 2026-11-06
Fixed:
- the in-game Checks window now reports items present in Buffer as well as Incoming/Outgoing, so a buffer/incoming duplicate no longer goes undetected.
Version: 0.39.8
Date: 2026-11-06
Added:
- connector hubs enforce `providing_to_other_platforms = true` every second, so every planet connector supplies the other platforms.
Version: 0.39.7
Date: 2026-11-06
Fixed:
- request/cargo read-back verification summed one stack per item instead of all repeated stacks, so a correct hub inventory could never verify and inventory sync retried forever.
Version: 0.39.6
Date: 2026-11-06
Changed:
- generated connector platforms use a leading tilde (~Space Platforms) and all generated request groups use a leading tilde, so they sort below player-created items.
- existing connector platforms and groups are renamed in place.
Notes:
- no routing or request semantics changed.
Version: 0.39.5
Date: 2026-11-06
Added:
- solo mode: an identified server with an empty topology behaves as a Single Server. It keeps UPS/RAM/player/speed telemetry and set_speed/set_paused, but creates no planet connectors, server selector, custom surfaces or fleet research.
Fixed:
- the identity push and configuration change no longer run fleet surface conversion on a solo save.
- the solo branch of the server menu no longer calls close_checks before it is defined.
Version: 0.39.4
Date: 2026-11-05
Added:
- platform_detail(index): read-only platform name, location, pause state, bay count, hub contents, requests and schedule when the build exposes it.
- platform_hub_dump(index, cursor, limit): the paged hub read the manager's platform store already expects.
- player_detail(name): read-only player server, surface, body and inventory contents.
- the research state now carries the ordered research queue.
Notes:
- no new writes; every call above is a read for the manager's runtime pages.
Version: 0.39.3
Date: 2026-11-04
Fixed:
- the ten-event replay made push_pod a local defined after the handlers that call it, so they saw a nil global, and it stored each event with its own replay list, nesting until the stack overflowed. The helper is a global now and stores a shallow copy without the replay list.
Version: 0.39.2
Date: 2026-11-04
Added:
- every connector_pod push carries the last ten pod events, so one dropped datagram cannot lose a delta; the receiver dedupes by id.
Changed:
- the rotating cargo sweep is removed. The mirror runs on pod events only.
Version: 0.39.1
Date: 2026-11-04
Fixed:
- connector_set_item applied a delta computed from a probed count, so a hub that already held the item had the whole amount inserted again (every over-item read exactly 200%). It now reads the inventory that holds the item, removes that many, inserts exactly the requested count, and reports before/after.
Version: 0.39.0
Date: 2026-11-03
Added:
- connector_set_item: set one item's count in a connector hub exactly, inventory only, requests untouched.
- connector_cargo_page: one sorted page of a hub's contents, for the mirror's slow sweep.
Version: 0.38.14
Date: 2026-11-03
Fixed:
- the debug trace added in 0.38.10 called debug.emit inside pod.lua, where that name is not the mod's debug module, so every cargo-pod event threw and pod tracking stopped. The trace is removed; pod handling is untouched otherwise.
Version: 0.38.13
Date: 2026-11-03
Fixed:
- the rocket trace read the silo's rocket inventory after the rocket had left, so it reported cargo=0. It reads on the launch order instead, while the cargo is still there.
Version: 0.38.12
Date: 2026-11-03
Added:
- debug-only trace on a rocket launch: the silo, every stack the rocket carried, and the total.
Version: 0.38.11
Date: 2026-11-03
Added:
- connector_clear: empties a connector hub's inventories in place, without destroying the platform, and returns how many items were removed.
Version: 0.38.10
Date: 2026-11-03
Added:
- debug-only trace on a cargo pod launch: every stack it carries, the destination hub's total contents at that moment, and the pod's total. Guarded by the existing debug flag.
Version: 0.38.9
Date: 2026-11-03
Fixed:
- a rebuilt connector never got its base grid back, because the queue is only filled from creation and ensure passes, and a load can run those before the identity is known. Any connector with no bays is queued once a minute.
Version: 0.38.8
Date: 2026-11-03
Fixed:
- the one-shot connector reset retried and logged every tick on an instance with no connector, because the flag only stuck when something was removed. It sticks when there is nothing to do as well.
Version: 0.38.7
Date: 2026-11-03
Changed:
- diagnostic build: the connector platforms are rebuilt from scratch once on the first load after this version, which starts their inventories at zero. The mod recreates them on the next ensure pass.
Version: 0.38.6
Date: 2026-11-03
Fixed:
- the one-shot hub clear consumed its flag before doing the work, so a pass that matched no hub cleared nothing and never retried. The flag now sticks only when a hub was actually emptied, and every pass logs what it saw.
Version: 0.38.5
Date: 2026-11-03
Changed:
- diagnostic build: the connector hubs are emptied once on the first load after this version, so the request cap can be observed from zero.
Version: 0.38.4
Date: 2026-11-02
Fixed:
- the one-shot hub clear ran before the identity was known, so no hub was ever recognised. It runs from the tick that waits for identity now.
Version: 0.38.3
Date: 2026-11-02
Fixed:
- the same item was written into more than one request group on one hub, so the game filled every row and a hub received a multiple of the requested amount. Incoming now wins and the duplicate is removed from Outgoing and Buffer.
Changed:
- connector hub contents are emptied once on the first load after this build, so the request cap can be watched from zero.
Version: 0.38.2
Date: 2026-11-01
Fixed:
- a cargo pod delta applied twice. The manager's de-duplication is in memory, so every restart re-applied the events the mod was still re-sending, and a lost reply re-applied one. The event id now travels with the apply and the mod ignores a repeat.
Version: 0.38.1
Date: 2026-11-01
Fixed:
- the Checks window missed a request with no planet set when that request was platform-sourced, and reported the game's automatic construction entries instead. It reads import_from only, in manual sections.
Version: 0.38.0
Date: 2026-11-01
Added:
- a Checks button beside Servers. It reports request loops (the same item in a planet hub's Incoming and Outgoing group) and planet-sourced requests with no planet set on real platforms. It only reports; nothing in the world is changed.
Version: 0.37.9
Date: 2026-11-01
Fixed:
- the join button was still greyed out with "Server is offline" after the join itself stopped refusing an offline server. The online flag now only decorates the row.
Version: 0.37.8
Date: 2026-11-01
Changed:
- joining another server no longer refuses when the manager reports it offline. The address is enough to try; a stale online flag was blocking joins.
Version: 0.37.7
Date: 2026-11-01
Changed:
- planet hubs are named "~[planet=x] X Hub" so the platform list sorts them to the bottom. An existing connector is renamed in place, and both names are recognised.
Fixed:
- the Servers button comes back as soon as the identity arrives; the identity call refreshes every player's window instead of leaving it removed.
- a platform request made on the space server is moved to the planet it names, instead of sitting there and never launching.
Version: 0.37.6
Date: 2026-11-01
Fixed:
- the derived hub groups attributed a request to a planet by request_from, so once a platform was set to request from platforms every one of its requests vanished from the planet hubs' Outgoing groups. Attribution is import_from.
Version: 0.37.5
Date: 2026-11-01
Fixed:
- a call that answers with a plain value (set_server_status answers true) failed to encode its reply, so the manager got nothing and the mod logged a -call failure every time.
Version: 0.37.4
Date: 2026-10-31
Added:
- every connector hub gets a free base grid of 320 cargo bays (18x18 bays, the hub in the middle 2x2), on foundation tiles. The bays cannot be mined and are not part of the mirrored layout.
Fixed:
- a planet server no longer deletes pending platform requests or native platforms in ensure_all. A native platform is reported to the manager and then removed.
- the wrong-planet request move runs (it was never scheduled), is live by default, and uses destroy(1).
- a platform created on a planet server is carried to the space server with its starter pack, quality, a request id and an ack; a name collision gets a suffix instead of merging.
Version: 0.37.3
Date: 2026-10-31
Fixed:
- a space platform created on a planet server was destroyed there and never rebuilt, because the adoption path was never called. The request is carried to the space server with the same name and the same planet, and re-sent until it lands. A platform created on the space server is left exactly as it is.
Version: 0.37.2
Date: 2026-10-31
Fixed:
- the Servers button never came back for a player who joined before the identity arrived. The topology push refreshes every connected player now, not only the ones with the window open.
- outbound research threw on every tick because main_force was not in scope, so no research progress was ever pushed.
Version: 0.37.1
Date: 2026-10-31
Fixed:
- peaceful mode is set on the space server's nauvis body only. It was applied to every surface, and the cease-fire was a force-pair setting, so the platforms' turrets stopped firing at asteroids.
Added:
- the body's freshly generated chunks are swept for ten seconds after a join, keeping the player's 3x3 chunk block. The body has no chunks of its own and regenerates around whoever stands on it.
Version: 0.37.0
Date: 2026-10-29
Changed:
- the hubs' Incoming and Outgoing groups are derived. Incoming comes from the landing pads, Outgoing from the space platforms. Both are recalculated in full whenever a request changes.
- a platform request with no planet selected counts for every planet's hub, at its full count.
Added:
- a Buffer group per hub, mirrored between both hubs and never recalculated.
- sync_* read and apply calls for the manager's startup sync; protocol number 2 in connector_ready.
Removed:
- the platform positions/meta/hub dump/audit streams and their calls; the landing pad is no longer written by the mod.
Version: 0.36.91
Date: 2026-10-29
Fixed:
- the server window no longer rebuilds itself on every status push; live values update in place and the 60-tick map poll is gone.
- connector platforms have asteroid and asteroid-chunk entities destroyed directly; the unused on_entity_spawned handler is removed.
Version: 0.36.90
Date: 2026-10-29
Fixed:
- the server list lost every sidebar button after the first in a section, and the solar strip lost all but one, because several elements shared one name inside one table. Each button now sits in its own cell, and a failed element creation is logged.
Version: 0.36.89
Date: 2026-10-29
Changed:
- server window rebuilt on tables and fixed-size cells so every column aligns; planet strip is clickable.
- connector platforms are swept for asteroids every 10 ticks and on every platform state change.
Added:
- space server turns on peaceful mode, cease-fire and disables enemy expansion.
Version: 0.36.88
Date: 2026-10-29
Changed:
- The server window shows only players, UPS, speed and tick; icons are sized and centred; the current server is marked 'Current Location' with a highlighted button; the window fits its content.
Version: 0.36.87
Date: 2026-10-29
Added:
- servers report a heartbeat and the manager pushes players, UPS and version to every server.
Version: 0.36.86
Date: 2026-10-29
Changed:
- The server window is a server list on the left and a detail panel on the right, with Join and Cancel at the bottom right.
Version: 0.36.85
Date: 2026-10-29
Fixed:
- on_load wrote the boot marker to storage, which Factorio rejects as a save/load change
and refuses to load. The marker is now module-local and on_load touches no storage.
Version: 0.36.84
Date: 2026-10-29
Added:
- Every server sends connector_ready over UDP once after a save load, so the manager can
wait for all instances before the startup pre-sync.
- The startup pre-sync pauses the fleet, dumps every connector, and applies the planet hub's
state to the space counterpart.
Fixed:
- A connector platform that lost its hub is rebuilt instead of being left as a floating cargo
bay. connector_state reports hub=false for that platform instead of failing the read.
Version: 0.36.83
Date: 2026-10-29
Fixed:
- Dead mirror code removed from the platform module. Cargo-bay build and remove events now carry
a sequence number, and the connector state reports it, so the manager can detect a lost packet
and reconcile the pair.
Changed:
- A hub build now pushes the connector's full shape, cargo and requests, instead of only marking
the platform dirty. Bay offsets are relative to the hub, so the counterpart is re-anchored at
once rather than at the next restart.
Version: 0.36.82
Date: 2026-10-29
Changed:
- The server map is one Servers button that opens a list of planets, space and custom servers. It
no longer polls or moves, so it shows instantly in map view.
Version: 0.36.81
Date: 2026-10-29
Changed:
- Cargo bays sync as single build/remove events: a player build sends the bay offset and the
counterpart creates that one bay at the same offset; a mine removes that one. The full
platform shape is only sent on boot and on the startup reconcile, so an edit no longer
runs a whole layout comparison.
Version: 0.36.80
Date: 2026-10-29
Fixed:
- Building a cargo bay raced the mirror. The counterpart's ensure_bays raised a build event
that was treated as a player edit, and the resulting state could win and remove the origin
bay. Manager-created bay events are ignored, a player bay build or mine bumps the clock so
the origin wins, and a placed bay is protected immediately.
Version: 0.36.79
Date: 2026-10-29
Fixed:
- The space server no longer prunes the real platforms. The connector is added alongside
them; only a planet keeps just the connector. The converter keeps every platform surface
in the base and space saves and does not add a planet connector to the base.
- A cargo bay a player places is protected immediately, not on the next mirror apply.
Version: 0.36.78
Date: 2026-10-28
Added:
- Cargo accounting. Every insert and remove logs wanted versus moved when DEBUG is on; a
shortfall is recorded in the connector event log and returned to the manager, which logs
it as an error. A failed request-group or pad write is reported the same way. This does
not prevent the both-writable double-use window; it makes it visible.
Version: 0.36.77
Date: 2026-10-28
Fixed:
- Trash-unrequested was cleared on the request point only. A hub and a pad expose several
logistic points, so the pad still pushed its inventory into the platform and the hub
still ejected its foundation. Every point is cleared now.
Version: 0.36.76
Date: 2026-10-28
Fixed:
- A real connector platform was collecting asteroids; the game repaired the damaged tiles
from the hub's foundation, draining the starter-pack cargo. The connector now sweeps its
asteroid chunks once a second, the same cadence as the fleet's planet sweep.
Version: 0.36.75
Date: 2026-10-28
Fixed:
- An empty request list from the manager was skipped as "no change", so a request cleared
on one connector side stayed on the other. The state now says whether the lists are
carried, and empty lists are written.
Version: 0.36.74
Date: 2026-10-28
Fixed:
- The connector hub and the landing pad had trash-unrequested on. The hub ejected its
starter-pack foundation over time, and the pad pushed its whole inventory into the
platform as soon as a request was added. Both points now keep unrequested items.
Version: 0.36.73
Date: 2026-10-28
Added:
- One connector platform per planet, mirrored between the planet save ("Space Platforms") and
the space save ("[planet=<id>] <Planet> Hub"). Both sides are writable; the manager applies
each edit to the counterpart and compares the hub weight.
- Incoming (Space to Planet) and Outgoing (Planet to Space) request groups, with the source
forced: platforms for incoming, planet plus the planet's location for outgoing. "all" is
rewritten and a finite maximum is removed.
- The landing pad keeps only the Incoming group; anything else is removed.
- Only the hub and cargo bays may exist on a connector; other builds are mined and refunded.
- Deleting a connector deletes the counterpart and rebuilds both hub-only.
Notes:
- The whole-list mirror, the cargo sweep and the platform timers are retired. The manager
reconciles once at fleet start under a tick pause.
Version: 0.36.72
Date: 2026-10-28
Added:
- The save call: game.server_save(name) with a name the manager chooses. The fleet save uses
it for every server and records the file and tick in fleet.json's worlds, so an archive
says which file is which world instead of taking the current save's name.
Version: 0.36.71
Date: 2026-10-28
Added:
- The periodic platform meta now carries each hub's inventory weight. The space server is the
source of truth; every copy reports the same scalar every few seconds, so the manager can
see a discrepancy without reading a full hub.
Version: 0.36.70
Date: 2026-10-28
Added:
- platform_hub_dump reports the hub inventory's weight. The space server and every copy
report it, so the manager can compare the scalar the fleet already uses internally
(tick_hub) instead of only diffing item lists.
Notes:
- The dump's `limit` is capped at 100 stacks per page; a reader must follow `next` until
`done`. Comparing a single page reported differences that were only unread pages.
Version: 0.36.69
Date: 2026-10-27
Fixed:
- debug.json logged every argument-less call as "<unserialisable: bad argument ...>". Calls
with no args pass nil, which table_to_json rejects; it is now logged as nil. That noise was
roughly fifteen thousand lines per server and hid real failures.
Notes:
- The manager no longer calls apply_requests or apply_cargo_delta on a custom instance: a
custom world has no platform with the fleet's name, and every edit logged "no such
platform" against blueprint-world.
Version: 0.36.68
Date: 2026-10-27
Fixed:
- The hub edit handler called platform_api.requests_of, but the module exports that
function as `requests`. Every real-hub logistic edit threw ("attempt to call field
'requests_of' (a nil value)") before it pushed anything, so no platform_requests event
was ever sent and a station's requests were never copied to the planets.
Version: 0.36.67
Date: 2026-10-27
Added:
- A read-only surface_report call: entities, entity-ghosts and deconstruction orders per
surface. It answers whether a planet that looks ghosted is unbuilt ghosts, orders, or
simply empty.
Version: 0.36.66
Date: 2026-10-27
Fixed:
- apply_requests no longer requires the copy's cargo-bay count to equal the real one. A
logistic filter list does not depend on capacity, and a copy built from an older layout
(more bays than the real has now) made every request write fail as "copy does not have
the ship's bays".
- copy_is_whole now accepts a copy with at least the real platform's bays, not exactly that
number. A copy with more bays can hold the cargo; refusing it blocked the cargo mirror
until the bay trim caught up.
Version: 0.36.65
Date: 2026-10-27
Changed:
- A real hub's logistic edit now carries its full request list and bay count in the
platform_requests event, so the manager can apply it to every copy directly. The manager
used to answer that event with a full fleet resync, which took minutes and was throttled;
a station's requests could sit on the space hub while every planet copy stayed empty.
Version: 0.36.64
Date: 2026-10-27
Fixed:
- The platform mirror destroyed a player's new platform and then threw on a require inside
report_platform_create ("Require can't be used outside of control.lua parsing"), so the
create was never sent and the platform vanished. The transport now lives in control/bus.lua:
platforms and outbound both require it, and the cycle that forced the lazy require is gone.
- Adoption is one function (adopt_native_platform), and every adopted platform is recorded
and its create re-sent every ten seconds until a copy of the name exists here, a native
with that name is still standing, or five minutes pass. A dropped datagram no longer loses
a platform.
- starter_pack.quality is a LuaQualityPrototype; it is normalised through .name in the
request move, the debug dump and create_platform, so a moved platform keeps its quality.
Notes:
- The mirror still adopts a pending request as soon as it appears, so the space server
applies the starter pack itself and the silo request is removed rather than fulfilled by a
rocket. If the rocket should build it, the mirror has to skip pending requests; separate
decision.
Version: 0.36.63
Date: 2026-10-27
Fixed:
- The once-per-build silo dump was keyed to a hand-bumped number, so a save that had run
the previous build never dumped its silos again. It is keyed to the mod version now, so
every build seeds once, including this one.
Version: 0.36.62
Date: 2026-10-27
Fixed:
- The debug boot read game.active_mods, which does not exist on the script side, so boot
threw and skipped the rest of on_configuration_changed on every server. It now reads
script.active_mods.
- A debug dump can no longer stop its caller: boot is wrapped, and it now runs after the
crash-site, surface and speed steps rather than before them.
Version: 0.36.61
Date: 2026-10-27
Added:
- A DEBUG switch in control/debug.lua, on while the fleet is being finalised. It logs what
the build and save actually offer (optional events, the space-platform states, the
logistic member indexes, the silo statuses, the controllers, mod versions), the whole
platform list every five seconds, every silo once per build and whenever the starter-pack
request count changes, each platform that appears or disappears with all its fields, every
purge and resend decision, every mirror input and every removal, every create_platform
entry and result, every join-rule decision, every event the mod handles, every RCON call
with its arguments and result, and every UDP push.
- Twelve kilobytes per dump, with a truncation marker, so one value cannot swallow the log.
Notes:
- Set DEBUG = false in control/debug.lua when the fleet is finalised for v1. Nothing else
in the mod reads a flag.
- Logging is local and changes no game state, so it is safe with players connected.
Version: 0.36.60
Date: 2026-10-27
Added:
- A pending platform request named on the wrong planet's server is moved to the server that
owns that planet, with the same name and the same starter pack (item and quality). The
request is destroyed on the origin, announced over UDP as platform_request_moved, recreated
by the target through request_platform, and acknowledged through request_moved_ack. Until it
is acknowledged it is re-sent every ten seconds, and an unacknowledged move is logged.
- New calls: request_platform, request_moved_ack, request_purge_mode, request_probe. New
command: server-connector-requests, which prints the probe as JSON.
Changed:
- The purge is dry-run by default, on new and existing saves, and only logs what it would
move. Arm it per server with request_purge_mode {live=true}.
- A platform creation that fails to apply its starter pack is now destroyed instead of being
left behind as a hubless pending platform.
Notes:
- Anything else the delivered rocket pod carried is lost when the native platform is deleted
and recreated on the space server.
- This build of the game has no on_space_platform_created event, so the 60-tick purge pass is
what catches a request; the handler is kept for builds that have it.
- request_planet reads the platform's space_location. A pending platform that reports nil
there is kept, never moved; the probe shows it.
Version: 0.36.59
Date: 2026-10-27
Fixed:
- The watch's first-pass line was gated on a flag stored in the save, so a fleet that had
already run an older build never printed it. It now prints once per build, which is what
makes the reader's state visible after an upgrade.
Version: 0.36.58
Date: 2026-10-26
Fixed:
- The silo reader probed the logistic member indices and took the first that answered, which
is logistic_container, so a silo's starter-pack request always read as zero. It asks for
rocket_silo_requester by name first.
- A surface creation with no platform attached yet returned silently, which is how a new
platform surface could be missed entirely. Every creation is logged with its platform and
copy state before the native-platform check runs.
Changed:
- The platform watch runs every five seconds instead of every minute: a request can be set
and removed inside a minute.
Version: 0.36.57
Date: 2026-10-26
Fixed:
- The silo reader asked for one fixed logistic member index, which this build does not
answer, so the watch always reported unreadable. It now probes the indices and caches the
one that answers, the way the platform hub reader already does.
Added:
- The watch logs one line on its first pass: how many silos it sees, the request count, and
which member index answered. That is the line to read when a launch leaves no trace.
Version: 0.36.56
Date: 2026-10-26
Fixed:
- The platform watch called a helper declared below it, so it read a nil global, and it was
scheduled at 60 ticks, so it ran every second. Both fixed: the helper is declared first
and the pass runs once a minute.
Version: 0.36.55
Date: 2026-10-26
Fixed:
- A logistic edit on a platform copy is ignored. Forwarding it made the manager resync from
the copy and write the real list back over it, which removed a request a few seconds
after it was made.
Added:
- Once a minute, each planet logs its rocket silos' starter-pack request count and any
platform name that appeared or disappeared. The logistic-slot event does not cover every
edit the game makes, so this is the trace for a launch that goes nowhere.
Version: 0.36.54
Date: 2026-10-26
Fixed:
- platform_check and rebuild_platforms were named on the RCON surface but never implemented,
so the manager's platform check and force-rebuild answered "unknown call". platform_check
now reports each copy's bays, cargo and requests; rebuild_platforms drops the copies so
the next mirror push rebuilds them from the fleet's own data.
Added:
- A rocket silo's starter-pack request count is logged whenever a logistic slot changes, so
a launch request that disappears without a launch leaves a trace.
Version: 0.36.53
Date: 2026-10-26
Fixed:
- A join no longer leaves chunks on a planet this server does not own. The spawn point is
set to the owned surface at boot, before the foreign-surface cleanup, so a joining body
is created there instead of on nauvis.
- Chunks on a foreign surface are swept once a minute, and a chunk holding a body is never
deleted. Nauvis cannot be deleted (the game refuses the primary surface), so its chunks
are the only thing that can be removed.
- The space server is a viewer again: a join gets the remote controller, and the body the
game created is removed on the next window with nobody connected. Destroying it in the
join handler is the change 0.32.3 recorded as desyncing the join.
Changed:
- The surface check runs every second: a connected player standing on a surface this
instance does not own is put back, and the spawn point is re-asserted when it drifted.
Added:
- sweep_foreign, one chunk sweep on demand; report carries foreign_last and foreign_swept.
Version: 0.36.52
Date: 2026-10-25
Changed:
- map.refresh writes frame.visible and frame.location only when they actually change.
- platform_meta and platform_positions share position_of(), so their platform fields are
read once by the same helper.
- UDP send failures are logged at most once a minute from a local (non-storage) counter.
Measured:
- /server-connector-profile on the space server, 0.36.51: platform_meta full table
0.20-0.21 ms, change-driven 0.20-0.23 ms, positions 1.78-1.88 ms, logistic
8.6-11.1 ms, hub 70-748 ms, map 0.004 ms. The metadata saving is fewer datagrams when
nothing changes, not a faster table build.
Version: 0.36.51
Date: 2026-10-25
Changed:
- platform_meta is change-driven with a five-second full heartbeat instead of sending the
whole table ten times a second. The manager merges partial updates and prunes only on a
full list.
- distance moved out of platform_meta; the 2 Hz platform_positions stream now updates it.
- platform positions remain at 2 Hz. Manager-side extrapolation was not enabled because the
runtime does not expose a per-platform speed value to interpolate from.
Added:
- /server-connector-mod-profile measures the meta, positions, logistic, hub and map readers
with helpers.create_profiler().
Version: 0.36.50
Date: 2026-10-25
Fixed:
- Duplicate script.on_nth_tick(60) registrations overwrote each other, so the asteroid
sweep, map refresh and research push never ran. All intervals now go through one
collector and one dispatcher per interval.
Added:
- Startup log lists every nth-tick interval and handler; the first run of each handler is
logged once so a missing registration is visible.
Version: 0.36.49
Date: 2026-10-25
Changed:
- A native space platform on a planet is removed and recreated on the space server under
the same name; the normal mirror then copies it back to every planet.
Removed:
- The launch-request redirect, home-world handling, ghost reporting and rocket backstop.
Version: 0.36.48
Date: 2026-10-25
Added:
- Manager platform check and force-rebuild calls; queue_launch_request moves a player's
starter-pack request to the production planet's silo.
Version: 0.36.47
Date: 2026-10-25
Changed:
- A starter-pack launch request made on a non-production planet is removed locally and
sent to the manager, which schedules it on nauvis where the starter hub is produced.
Version: 0.36.46
Date: 2026-10-24
Fixed:
- A space-platform hub ghost is reported as a new platform, so the manager can create
the real platform on the space server instead of leaving a ghost on a planet server.
Version: 0.36.45
Date: 2026-10-24
Added:
- The new-space-platform starter-pack request is moved from a non-main surface's rocket
silo to a silo on the server's main planet.
Version: 0.36.44
Date: 2026-10-24
Fixed:
- Extra copy bays are made destructible before removal; protected bays ignored destroy().
Version: 0.36.43
Date: 2026-10-24
Fixed:
- A copy of a platform with no layout now trims extra cargo bays instead of keeping
every bay from the old layout forever.
Version: 0.36.42
Date: 2026-10-24
Changed:
- The server strip adapts its fixed position: top-left in the normal view, shifted right
in map view so the map search box stays clear. It is not draggable.
Version: 0.36.41
Date: 2026-10-24
Changed:
- The server strip is fixed near the top-left but offset to the right of the map search
instead of covering it. It is not draggable.
Version: 0.36.40
Date: 2026-10-24
Changed:
- The in-game server strip is a captioned, draggable window instead of a fixed overlay.
It no longer sits over the map search and can be moved like RateCalculator's window.
Version: 0.36.39
Date: 2026-10-24
Fixed:
- The in-game server strip is no longer gated on the server's reading of the client's
render_mode. It is visible while connected, so the map-view server buttons cannot be
hidden by a wrong chart/game reading.
Version: 0.36.38
Date: 2026-10-24
Fixed:
- Boot clears game.tick_paused, so a save taken while paused cannot open frozen.
Version: 0.36.37
Date: 2026-10-24
Fixed:
- Empty request lists are omitted from the meta and the manager clears its cached list on
the empty-request hash, so stale fake-platform requests no longer persist.
Version: 0.36.36
Date: 2026-10-24
Changed:
- No periodic layout/bay push. A real-platform build or mine still announces the full
layout immediately; a boot is the only forced full copy.
- Fleet start brings the space server up first and waits for its platform meta before
starting the planets, then force-pushes layout and resyncs cargo/requests once.
Version: 0.36.35
Date: 2026-10-24
Changed:
- Added a 1 Hz logistic-only platform_meta stream carrying requests and request_hash,
leaving the cheap 10 Hz identity/position stream and the 5 s full layout stream alone.
- The manager now ingests the request list from platform_meta.
Version: 0.36.34
Date: 2026-10-24
Changed:
- Cheap platform_meta now runs at 10 Hz; the position stream stays at 2 Hz.
- Handbook: the 30 s hub dump checks the hub inventory's weight first and skips the
per-stack dump when the weight is unchanged.
Version: 0.36.33
Date: 2026-10-24
Fixed:
- apply_requests selects a manual logistic section using LuaLogisticSection.is_manual.
LuaLogisticSection.group is a string, not an object, so the previous group.name check
never matched and writes were refused.
Version: 0.36.32
Date: 2026-10-24
Fixed:
- apply_requests writes a manual logistic section instead of sections[1], which was
refused with "trying to change logistic section that is not manual".
- The manager decodes the first JSON value from the mod's page output instead of
rejecting trailing data, so resync can read platform_meta_page and hub dumps.
Version: 0.36.31
Date: 2026-10-24
Added:
- platform_report, the same adoption datagram the rocket handler sends, callable over
RCON so the outbound/manager path can be tested without /c UDP.
Version: 0.36.30
Date: 2026-10-24
Added:
- on_entity_logistic_slot_changed triggers platform_requests, so a hub's request change
is synced to the copies immediately instead of waiting for the cargo audit.
Version: 0.36.29
Date: 2026-10-24
Fixed:
- A platform deleted on the space server now removes its copy on every planet. The mod
records the copies it creates, so a stale copy is removed while an unknown native
platform is still kept and adopted.
- Platform requests are written to the copy while players are connected. The previous
empty-server guard meant a hub's new requests never reached the clone, so its
logistics never queued rockets.
Version: 0.36.28
Date: 2026-10-24
Fixed:
- events.lua used an undefined instance() in the new platform-created and rocket-launch
handlers. The rocket launch fired and failed with "attempt to call global 'instance'".
Version: 0.36.27
Date: 2026-10-24
Added:
- on_space_platform_created reports a new starter-pack platform to the manager directly,
and on_rocket_launched rescans for any platform the fleet list does not contain.
This replaces waiting for the planet mirror to discover it.
Version: 0.36.26
Date: 2026-10-24
Fixed:
- Any platform the fleet list does not contain is kept and reported for adoption. The
hub test was also wrong: a native starter-pack platform can exist before a hub object
is visible, so the mirror destroyed it as a stale copy.
Version: 0.36.25
Date: 2026-10-24
Fixed:
- An unknown hub platform on a planet is kept and reported even when its protection
flags look like a copy's. copy_is_protected() matched native starter-pack platforms,
so the mirror destroyed them instead of asking the space server to adopt them.
Version: 0.36.24
Date: 2026-10-24
Changed:
- Removed the connected-player guards from the platform mirror and the space-side
platform creation. The join desync was the per-client GUI rebuild counter, not these
world changes. A starter-pack platform is now adopted even when its owner is standing
on the planet or the space server.
Version: 0.36.23
Date: 2026-10-24
Fixed:
- Removed the require cycle introduced in 0.36.22 (platforms -> outbound -> platforms)
by requiring outbound lazily when reporting a native platform. 0.36.22 failed to load:
"too many C levels" in platforms.lua.
Version: 0.36.22
Date: 2026-10-24
Fixed:
- A starter pack launched on a planet no longer deletes the platform the game creates
there. A native platform the fleet list does not know is kept and reported; the
manager has the space server create the real platform, and the next mirror pass turns
the planet's platform into its protected copy. Previously the planet mirror treated
it as a stale copy and destroyed it.
Version: 0.36.21
Date: 2026-10-24
Fixed:
- The server-list GUI rebuild signature is stored in `storage` by player name instead
of a module table. A client's Lua state is recreated on every join, so its module
table was empty and it rebuilt the GUI on each join while the server's persisted.
That is the +18 custom-GUI element indices in the desync report.
Fleet:
- The manager and node now require the exact connector version. A node rejects an
archive whose info.json does not match the requested version, refetches the pinned
release, and restarts a running server when the mod set changes.
Version: 0.36.20
Date: 2026-10-24
Reverted:
- Removed the os.clock/game.tick timing instrumentation and the slow-call logs.
- Removed the joining check, the 10-second mirror block after join/leave, and the join
move log. The mirror and join rule are back to their pre-guard behavior.
- The platform streams, the os fix and the platform cadence remain.
Version: 0.36.19
Date: 2026-10-24
Added:
- The join rule logs when it moves a character and which surface it came from. The
teleport was silent on success, so the rejoin desync could not be attributed.
Version: 0.36.18
Date: 2026-10-24
Fixed:
- Removed every os.clock() use. Factorio's Lua sandbox does not expose os, so the
platform metadata streams were erroring on every tick. Timing is now game.tick based.
- The copy mirror refuses while a client is joining (connected but not yet in
connected_players), and for 10 seconds after any join or leave. The mirror was running
during the map-load window and changing copy entity state after the client had
downloaded the map, which desynced vulcanus.
Version: 0.36.17
Date: 2026-10-24
Fixed:
- Pod tests use the owning entity's create_cargo_pod{cargo_hatch=...}, which reserves the
source hatch; the hatch's own method rejected the call and the entity method without a
hatch left the pod awaiting_launch.
Version: 0.36.16
Date: 2026-10-24
Fixed:
- Pod tests create the pod through the source cargo hatch's create_cargo_pod(), not the
owning entity's. The hatch method reserves the launch hatch and starts the pod; the
entity method left it awaiting_launch.
Version: 0.36.15
Date: 2026-10-24
Fixed:
- Cleanup includes the space hub-to-hub test pod.
Version: 0.36.14
Date: 2026-10-24
Fixed:
- space_platform_to_platform uses the first real item in the source hub instead of
requiring space-platform-foundation, which the source may not hold.
Version: 0.36.13
Date: 2026-10-24
Fixed:
- Cleanup includes the force-drop and platform-to-planet test pods.
Version: 0.36.12
Date: 2026-10-24
Added:
- podtest force_drop: a real copy-hub pod to the planet surface (the force-drop/remove path).
- podtest space_platform_to_platform: a real hub-to-hub pod on the space server, the native
platform-to-platform path the bridge intentionally ignores.
- platform_to_planet sets the landing pad and copy hub operable/destructible/minable before
the pod, to test the station with no protection-side effect.
Version: 0.36.11
Date: 2026-10-24
Fixed:
- Cleanup includes the last platform-to-planet test pod.
Version: 0.36.10
Date: 2026-10-24
Added:
- podtest cleanup destroys the parked test cargo pods by unit number.
Version: 0.36.9
Date: 2026-10-24
Changed:
- The rocket test selects a silo whose status is rocket_ready, rather than the first silo,
which may be empty.
Version: 0.36.8
Date: 2026-10-24
Added:
- rocket_to_platform pod test: load the silo rocket and launch it at the copy hub with
rocket_silo.launch_rocket, which is the real planet-to-platform path.
Version: 0.36.7
Date: 2026-10-24
Changed:
- Pod test clears all three protection flags on the copy hub before creating the pod, to
tell a non-station from a protected-station rejection.
Version: 0.36.6
Date: 2026-10-24
Changed:
- The planet-to-platform test falls back to a landing-pad cargo pod when the silo has no
free hatch. The destination hub is the same, so the station/bridge path is unchanged.
Version: 0.36.5
Date: 2026-10-24
Changed:
- Pod test makes the copy hub operable before creating a planet-to-platform pod, to
confirm whether non-operable is what makes the game clear the station.
Version: 0.36.4
Date: 2026-10-24
Fixed:
- The pod test picks an input-compatible, unreserved, non-busy cargo hatch. The first
hub hatch was reserved and the game refused it; the copy hub exposes 33.
Version: 0.36.3
Date: 2026-10-24
Fixed:
- planet_to_platform test uses a rocket silo, not a cargo landing pad. A landing-pad pod
to a space platform hub is not accepted by the game; the station is cleared and the pod
waits.
Version: 0.36.2
Date: 2026-10-24
Added:
- The pod test reports the created pod's state and the hub/landing-pad cargo hatch counts, so a
pod that does not launch can be diagnosed.
Version: 0.36.1
Date: 2026-10-24
Fixed:
- Cargo pod destinations use defines.cargo_destination.station, not the string "station";
the string made the game refuse the destination.
- platform_to_planet test now removes the cargo from the copy hub first, so the copy and
the real hub both decrease; report mode shows both sides.
Version: 0.36.0
Date: 2026-10-24
Added:
- Planet <-> platform cargo bridge. A pod leaving a copy hub removes the same cargo from
the real hub; a pod arriving at a copy hub adds it. Pods between real space hubs are the
game's native logistics and are left alone.
- The bridge queues each move in storage and re-sends for 60 seconds; the manager
de-duplicates by event id for an hour. There is no RCON acknowledgement because an ack
would write script storage from outside the game while a player is connected.
- The manager applies the delta to the real hub on the space server with the copy's name
and ordinal.
- server-connector-mod-podtest can create a real cargo pod from a planet landing pad to a
copy hub, or from a copy hub to a landing pad, and can enqueue a synthetic add/remove.
Version: 0.35.21
Date: 2026-10-23
Changed:
- The full platform meta runs every five seconds, not every second. A build/mine event
still carries the layout immediately.
Added:
- /server-connector-mod-streams on|off is a per-server diagnostic. Off stops the platform
UDP streams so the game's own cost can be measured; everything else keeps working.
Version: 0.35.20
Date: 2026-10-23
Changed:
- The continuous platform position/meta stream is 2 Hz instead of 10 Hz; the board does
not redraw fast enough to use the difference.
- The hub dump no longer reads the first page twice.
Version: 0.35.19
Date: 2026-10-23
Changed:
- The 10 Hz platform meta is now the cheap shape only: identity, position, state. The
bay count, layout, asteroid/other counts and request hash moved to a 1 Hz full meta.
Those walks were the mod's largest constant cost on the space server.
- The hub cargo dump runs every 30 s instead of 10 s; the aggregate audit every five
minutes instead of one.
- The real space platforms no longer count "other" entities in the full meta; that
walk is only meaningful for copies.
- The layout is taken from the build/mine event, so a new bay reaches the copies without
waiting for the next full meta.
Added:
- Log lines when the cheap meta, full meta, hub dump or audit exceed their budget, so a
mod cost is measured instead of suspected.
Version: 0.35.18
Date: 2026-10-23
Fixed:
- copy_is_protected was defined before bay_list, so the mirror errored with "attempt to
call global 'bay_list' (a nil value)" on a planet and the copy was left untouched.
Version: 0.35.17
Date: 2026-10-23
Fixed:
- The full bay layout in the RCON platform list made the space server's reply too large
to decode ("invalid character '{' after top-level value"), which stopped every copy
push. The layout now rides the 10 Hz UDP platform meta; the RCON list stays small.
Version: 0.35.16
Date: 2026-10-23
Fixed:
- Copy entities were only destructible=false, which does not stop mining, deconstruction
or opening the hub. The hub and bays now also set minable_flag=false and operable=false,
and a deconstruction order on a copy is cancelled.
- Cargo and request writes to a copy now refuse if its bay count no longer matches the
real ship, and an inventory insert/remove counts only what actually moved. A player
who removed bays could previously make an insert silently stop at the reduced cap.
- Kept copies were not re-protected after a repair; they are protected on every push.
Added:
- A build or mine on the real platform pushes its layout to the manager immediately,
instead of waiting for the next poll.
- The mirror log reports how many copies are unprotected.
Version: 0.35.15
Date: 2026-10-23
Added:
- The mirror log now reports, after every empty-server push, how many copies differ from
the ship layout, hold any entity other than the hub/bays, or hold an asteroid. A clean
line is the check that the copies are the ship.
Version: 0.35.14
Date: 2026-10-23
Fixed:
- Copies are protected (destructible=false), and a protected platform survived
destroy(0) even though the call reported success. Removing a copy now clears
destructible on its hub and bays, cancels any earlier schedule and destroys on the
next tick, which is the pattern that worked in 0.35.6.
Version: 0.35.13
Date: 2026-10-23
Fixed:
- A copy that differs only in bay layout or extra entities is repaired in place instead
of being destroyed and recreated. The recreate path used destroy() without a deletion
argument, left the old copy on the server and made the copy count grow on every push.
- Removing a copy uses destroy(0), and a failed removal is logged with the error.
Version: 0.35.12
Date: 2026-10-23
Changed:
- A planet copy now reproduces the real platform's hub-and-bay layout, not a ring of the
same number of bays. The manager sends the bay offsets from the real hub.
- Each empty-server mirror push compares the copy with the ship. A missing hub, a
different bay count/layout or any other entity rebuilds the copy; asteroids are
destroyed on every push.
Added:
- server-connector-mod-platforms reports each platform's bay count, layout hash,
asteroid count and other-entity count as JSON.
Version: 0.35.11
Date: 2026-10-24
Fixed:
- The platform metadata read a cargo_bays key the platform class does not have, so
every bay count was nil. It is counted from the cargo-bay entities on the platform
surface, and the platform page now shows it.
Version: 0.35.10
Date: 2026-10-24
Fixed:
- Cargo and request sync addressed a copy by name. A name can belong to several
platforms, so the first match won and a duplicate could receive another platform's
cargo. The manager now sends the ordinal within the name, and the mod selects the
platform by that order.
- The manager's platform store keyed entries by name and collapsed duplicates; it now
keys by name and index, so the platform page shows every platform.
Version: 0.35.9
Date: 2026-10-24
Fixed:
- Copies were matched by platform name, but the fleet has several platforms with the
same name, so a planet held 12 copies of 16 platforms. Copies are now grouped by
name and paired by the real platform's index, so every platform gets its own copy.
Version: 0.35.8
Date: 2026-10-24
Fixed:
- A platform that is docked or in transit has no location or connection, and the
manager sends that as an empty string. The copy builder treated it as a name and
failed with "Unknown space-location name", so those platforms never got a copy.
- The mirror log now states how many copies the server actually holds, so a missing
copy is visible in the log rather than inferred.
Version: 0.35.7
Date: 2026-10-24
Fixed:
- Planet servers hold the fleet's platform copies again, as the hub plus the same
number of cargo bays as the real platform, with no asteroids and no way to damage
them.
- Copies are made, kept and pruned only from the manager's RCON list. The boot,
configuration-change and leave handlers no longer touch platforms, so a client
never applies a platform change of its own and has nothing to diverge on.
- The platform list now reports each platform's cargo-bay count.
Version: 0.35.6
Date: 2026-10-24
Fixed:
- Old planet platform copies now cancel a previously scheduled deletion and destroy one
tick later, so the copy and its asteroid chunks are actually removed.
Version: 0.35.5
Date: 2026-10-24
Fixed:
- The asteroid sweep runs only on planet instances; space and custom instances such as
blueprint-world are left alone.
- Old fake platform copies are destroyed immediately (destroy(0)) instead of being
scheduled for deletion, so their asteroid chunks go with them.
Version: 0.35.4
Date: 2026-10-24
Fixed:
- Planet servers remove old fake platform copies on init, configuration change and
the last player leaving. The 0.35.3 cleanup only ran when the manager pushed a
changed platform list, so copies already on a planet survived the update.
Version: 0.35.3
Date: 2026-10-24
Changed:
- Planet servers hold no platform copies. The copies were fake platforms at a space
location: they spawned asteroid chunks, the sweep removed them, and their state
diverged from the server while a player hopped planets -- desyncing on rejoin.
The real platforms live on the space server; use the space map.
Version: 0.35.2
Date: 2026-10-23
Fixed:
- The fake-platform protection reads cargo bays from the platform surface. The
LuaSpacePlatform class has no cargo_bays key, so 0.35.1 refused the platforms call
and the hub protection threw.
Version: 0.35.1
Date: 2026-10-23
Fixed:
- Fake platform copies are no longer deleted by asteroid chunks. The copy's hub and
cargo bays are made indestructible, and the existing one-second sweep keeps
destroying the chunks. The engine has no per-platform asteroid spawn switch:
hidden only removes it from the remote-view list, and paused only stops thrust and
schedule.
Version: 0.35.0
Date: 2026-10-23
Added:
- platform_meta(): the cheap platform call (identity, position, state, bays, request hash),
pushed at 10 Hz from every server, copies included.
- platform_hub_dump({index, cursor, limit}): the heavy call, paged so a platform of any
size never goes in one datagram; cargo and requests, with a hash and a done flag.
- platform_audit(): raw item totals summed across platforms, for the manager's drift report.
- apply_cargo_delta({platform, ops}) and apply_requests({platform, requests}): the only
mutations; the manager computes the difference, Lua applies it.
- Every UDP push now carries origin, origin_epoch and seq, so a save restart is visible to
the manager.
Changed:
- Cargo dumps are sent only when the hub hash changed (checked every 10 s); metadata is
the 10 Hz stream. The manager reassembles pages and does all diffing and fan-out.
Version: 0.34.0
Date: 2026-10-22
Changed:
- No data path uses stdout/log any more. The mod is pure RCON (calls into the game) plus
localhost UDP (events, platform positions, research). The once-a-second report and
platform JSON on stdout is gone.
Version: 0.33.9
Date: 2026-10-22
Fixed:
- UDP sends use helpers.send_udp, the API that actually exists, instead of game.send_udp.
Version: 0.33.8
Date: 2026-10-22
Added:
- The space server pushes every platform's serialized position (location, connection,
distance, docked, paused) over localhost UDP every 6 ticks.
- Research progress is pushed over UDP once a second only when it moved, with the delta
and the queue; every research queue/selection event is pushed as well.
- The manager keeps the last platform-position and research payloads and exposes them at
/api/fleet/platform-positions and /api/fleet/research-udp.
Version: 0.33.7
Date: 2026-10-22
Added:
- A platform changing state (docking, leaving, arriving) is pushed as a server-side
localhost UDP event to the one-container app, which exposes the last events at
GET /api/fleet/events.
Version: 0.33.6
Date: 2026-10-22
Changed:
- The mod's outbound facts (telemetry, platforms, queued events) are written to stdout
once a second as SCMOD|kind|json, so the node no longer needs an RCON round trip to
read them. Inbound calls remain RCON; nothing is written to stdin.
Version: 0.33.5
Date: 2026-10-22
Fixed:
- Foreign-surface cleanup runs once per save, not on every topology push. Deleting the
nauvis chunks after a client had loaded the map was the desync on the join tick.
Version: 0.33.4
Date: 2026-10-22
Changed:
- A join no longer touches the controller, the character, the editor, the remote or the
inventory. It only teleports the player's existing body onto the surface this server
holds. Every controller change was a world change the client did not make.
- The non-nauvis servers remove the nauvis surface (its chunks included) as part of the
foreign-surface check.
Version: 0.33.3
Date: 2026-10-22
Fixed:
- The flat surface replacement happens once, not on every topology push. Without the
marker the unchanged branch deleted and recreated the flat Main repeatedly, wiping it.
Version: 0.33.2
Date: 2026-10-22
Fixed:
- The unchanged-topology branch now applies the declared surface forms too. It only ran
the foreign-surface cleanup, so a declared flat surface that already existed was never
replaced when the manager kept sending the same topology. This is why blueprint-world
stayed mixed.
Version: 0.33.1
Date: 2026-10-22
Fixed:
- An instance declared as an editor is an editor again. The editor branch is the
instance's declared mode, not a fallback; blueprint-world uses it. Every other server
still gives the player its own character.
Version: 0.33.0
Date: 2026-10-22
Changed:
- Every server gives the player its own character on its own surface. The editor, god
and remote fallbacks are gone from the join rule: a foreign copy is detached and a new
character is created; if that cannot happen the player is disconnected rather than left
in the bodyless physical controller. Each server is a separate life.
Version: 0.32.9
Date: 2026-10-22
Fixed:
- A declared flat custom surface that already exists in the save is now replaced with
the flat form once. The create branch only handled a missing surface, so a old mixed
world was carried forward every conversion and the flat form was never applied.
- The foreign-surface cleanup no longer deletes platform surfaces on a planet. Those
are the copies the planet needs to see the fleet's platforms, and deleting them was
the world change behind the join-tick desync.
Version: 0.32.8
Date: 2026-10-22
Changed:
- The reported surface list omits nauvis on every server except the nauvis server. The
homeworld cannot be deleted, so a stripped, empty copy is in every converted save; it
is not a surface that server serves.
Version: 0.32.7
Date: 2026-10-22
Changed:
- The cross-server body tracker no longer decides a join. Each server gives the player
its own body on the surface they joined on: attach a character already there, else
detach a foreign copy and create one. The space server has no living body and gives
the remote controller.
- The server strip has no caption and is pinned to the top; it is no longer a draggable
window.
Version: 0.32.6
Date: 2026-10-22
Fixed:
- A planet or custom save no longer keeps the space server's platform surfaces; they are
foreign there. The space save now keeps its platforms and removes every non-platform
surface, instead of skipping the cleanup entirely. Both run only with nobody connected,
so no join is made a world change.
Version: 0.32.5
Date: 2026-10-22
Changed:
- A map click connects immediately again. Telling the manager first is kept, but the
held connect read as a dead button and the target's short remote view is preferable.
Version: 0.32.4
Date: 2026-10-22
Fixed:
- A body whose home is the server it is stored on was indistinguishable from never having
been told, so that server read it as nauvis and made its owner a remote viewer. The mod
remembers that the manager has spoken.
- A join never destroys a character and only creates one on the body's home when the save
holds none; a copy on a foreign surface puts the player in the remote controller.
Changed:
- A topology that arrives while somebody is connected applies its destinations and
refreshes the map immediately; surface creation waits for the last player to leave.
- A map click tells the manager the destination and holds the connect for six seconds, so
the target has the body's new home before the player arrives.
Version: 0.32.3
Date: 2026-10-22
Fixed:
- A remote viewer's character copy is left alone on join. Destroying it there was the
world change the client did not see, and the join still desynced with the copy's
inventory. The player is put in the remote controller; the copy stays on its surface.
- The server map frame is shown in the remote controller, not only on the chart. A viewer
could not reach the buttons that move them to another server.
Version: 0.32.2
Date: 2026-10-22
Fixed:
- A join no longer moves a character to another surface. That teleport is a server-side
world change the client does not see, and it desynced the joining player. A character
found on a surface this instance does not own is removed as a copy instead.
- A player with no recorded body is parked on nauvis. If the join lands on nauvis and this
world holds no character for them, one is created there, so a player with no body
anywhere gets a nauvis body rather than the observer controller.
Changed:
- set_body_location only stores the body. It arrives over RCON, and applying a controller
or character change to a connected player is a world change the client never sees; the
stored body is applied by the join rule the next time they join.
Version: 0.32.1
Date: 2026-10-20
Added:
- research_all() unlocks every technology on this force. It is what a custom instance
whose research mode is "all" is given; it never reports anything back.
- A surface's form carries its seed, whether it generates cliffs, and its water size.
create_custom_surfaces applies them on top of the chosen planet template.
Changed:
- ensure_surfaces removes surfaces this instance does not own, so the planet copies the
old layout made disappear from existing saves. The space server is left alone: its
platforms are what it owns, and they are not declared.
Fixed:
- A custom instance never contributes research to the fleet, whatever its mode says.
Version: 0.32.0
Date: 2026-10-20
Changed:
- No fake surfaces. A server creates only the surfaces it owns: its planet, the custom
surfaces declared for it, or nothing at all on the space server, whose platforms are
built. Another server's planet is no longer copied here, and the join fallback that
cleared those copies is gone.
- The way to another server is the server map: a list of buttons shown while the map is
open, one per other instance, labelled with its name. A click connects. The vanilla
space map is disabled, because it would offer a planet with no surface behind it.
- The topology is instance-centric: name, address, kind, editor, primary and the list of
surfaces an instance owns. No public copies and no owner id.
- report().bodies counts a character on any surface this instance owns, not only one
named after the instance.
- A custom instance can give its players the editor controller on join.
- create_surfaces takes the manager's surface forms: flat tile, planet-template
generation, peaceful, no enemies, day length, solar, wind and cold.
Added:
- delete_surface(name) removes one custom surface. It refuses while anybody is
connected, and refuses the primary.
Fixed:
- route_for, route_if_elsewhere and destination_for are gone with the surface-change
trigger they existed for.
Version: 0.30.2
Date: 2026-10-19
Changed:
- Every event handler and both commands contain their own failure. An error from a
handler is non-recoverable in Factorio: the server quits, and the fleet's watchdog then
stops the other five without saving. A fault is now a log line and the handler returns.
- The writes in the join rule (destroying a character, both set_controller calls) and the
position lookup in enforce_surface are wrapped individually, so one refusal is a log
line and the rest of the rule still runs.
- A failed connect_to_server is logged and retried on the next surface change, instead of
raising from the routing handler and leaving the player marked as handed over.
Version: 0.30.1
Date: 2026-10-19
Fixed:
- A player joining with their character on a different surface no longer takes the
server down. set_controller refuses an entity from another surface and that error is
not recoverable, so the body is put where it belongs first and the controller is only
attached once the two surfaces agree.
- report() only counts the bodies this server owns. A character on another planet's
surface in this save is not this server's body; claiming it made the manager state a
home the character was not standing on.
Version: 0.30.0
Date: 2026-10-19
Changed:
- A world change driven over RCON is refused while anybody is connected: set_instance,
set_topology and create_surfaces answer skipped and write nothing. The node already
retries an identity push until it takes, and the manager now retries a skipped topology
push instead of reading it as applied.
- set_instance and set_topology answer unchanged when they are told what they already
hold. Re-pushing the same identity no longer clears the recorded body locations, and
an identical topology with nobody connected still repairs missing surfaces.
- set_topology drops entries with no address and compares two topologies as sets.
- A platform surface counts as owned on every server, so a planet server's copies are no
longer cleared by the join fallback.
- platform_api only reads. The probes that moved a platform, unpaused it or created one
are gone.
- A hand-set startup setting is a working fallback again; the default, unconfigured,
still leaves the mod inert.
Fixed:
- destination_for returns nil when the topology holds no entry with an address for the
surface, and route_if_elsewhere checks the address before handing over. Looking at a
platform on a fleet with no space server is no longer an error.
- report() no longer depends on storage.viewing existing, so a missing table cannot cost
the manager its whole telemetry.
- clear_foreign_chunks collects a surface's chunks before deleting any of them; deleting
while walking the iterator could skip entries or raise.
- The asteroid sweep carries on past a platform it could not clear, instead of stopping
for every other platform too.
- game.planets and is_space_location_unlocked are read under pcall, so a build without
Space Age cannot take ensure_surfaces down.
- mirror_platforms collects the copies to remove before destroying them, and reports only
the removals that took.
- apply_research clamps the progress it is given to 0..1.
- set_body_location reports destroyed_character when it destroyed a connected player's
character here, and only changes a controller for a player who is connected.
- The -call command refuses a player. Identity, research, pause and the probes are no
longer reachable from chat.
- The empty on_player_left_game handler is gone.
Version: 0.29.0
Date: 2026-10-19
Added:
- report() now includes bodies: the characters each world holds, whether their player is
connected or not.
Version: 0.28.0
Date: 2026-10-18
Changed:
- Not recorded.
Version: 0.27.0
Date: 2026-10-18
Changed:
- Not recorded.
Version: 0.26.0
Date: 2026-10-18
Changed:
- Joining a server now puts a player on that server's own surface straight away, instead of
waiting for their first surface change. Landing somewhere else and having to click their
way across was the join being treated as a look rather than an arrival.
Version: 0.25.0
Date: 2026-10-18
Changed:
- Conversion is gone from this mod. Cutting a world down to the one surface a server keeps
-- the tick-bounded strip, delete-and-recreate, and the per-surface primitives -- moved to
the private converter mod the manager installs for the length of a conversion and removes
afterwards. This mod routes, reports, researches and settles; it does not cut worlds down.
Added:
- A join fallback: a player joining can generate chunks on a surface this server does not
own, and those are taken off at once. It is one join's worth, and it is the only clearing
left here.
Version: 0.24.1
Date: 2026-10-17
Fixed:
- A surface's chunks are found by asking the world for them (get_chunks, tolerant of the
shape it hands back) instead of walking a window around the origin. A 170MB world has
chunks far from anywhere and every one of them is a chunk of a surface nobody wants.
- surfaces() says which of them are platforms, because a space server keeps its platforms
and they cannot be named in advance -- they are built.
Version: 0.24.0
Date: 2026-10-17
Added:
- delete_surface_chunks(name): delete one surface's chunks and everything on it. This is
the primitive a conversion is driven with -- one surface per call, the node deciding
which and in what order, because a sequence of steps belongs to the node and the mod is
only the way into the game's components.
- surfaces(): what surfaces this world has, so the node can walk them one by one.
Version: 0.23.3
Date: 2026-10-17
Fixed:
- The world work no longer runs on a load or on a tick. Both run on every client as well
as the server, and a client that is joining reports no connected players while the
server sees one -- so the client cleared surfaces the server had kept, and the game
desynced the moment it noticed. Surfaces, the spawn point and clearing happen only on
an order (settle), and only with nobody connected: a world change made here is not
replicated, so it must never happen while anybody can be comparing.
Version: 0.23.2
Date: 2026-10-17
Fixed:
- World changes happen only with nobody connected. They are driven by orders that arrive
over RCON, and RCON-driven world changes are NOT replicated to clients: the server cut
a surface down and the client, never told, kept it -- "Multiplayer desynchronisation:
crc test failed" on join, every time. Clearing, the spawn move, the strip and the
platform mirror all run empty now, and the boot-time work is re-armed when the last
player leaves so a busy fleet still gets it done.
Version: 0.23.1
Date: 2026-10-17
Fixed:
- The strip step says what it does and what fails. It was called under pcall with nothing
logged, so a strip that made no progress for eight minutes left every counter at zero
and no word about why. The handler logs its error, a surface the job cannot find names
itself, an empty surface says so, and a job with nothing to strip says that too.
Version: 0.23.0
Date: 2026-10-17
Added:
- Stripping a world is a job now, not one call. A 170MB world cannot be stripped inside
an RCON round trip: the work outlives the timeout, the reply comes back empty, and an
empty reply looks exactly like a refusal -- so the manager retried, the retry started
the work again, and the world came out untouched while the conversion reported success.
strip_begin starts it, a permanent on_tick handler does a batch every tick,
strip_status says where it has got to, strip_finish returns the summary, and
strip_cancel stops it. Every step is wrapped and says what it did.
Version: 0.22.4
Date: 2026-10-17
Fixed:
- The space server no longer mirrors itself. It is where the platforms really are, so a
list derived from them must not be applied back to them: a list one poll old dragged
the real platform back to where it had been, and a pause read from it re-paused it.
That loop is why the copies and the real platform kept reverting.
Version: 0.22.3
Date: 2026-10-17
Added (probes):
- Unpausing the real platform, so the copies can be watched following it both ways.
- Which logistic member index a hub's requests live on, asked of the game rather than
read out of the defines page.
Version: 0.22.2
Date: 2026-10-17
Fixed:
- 0.22.1 did not parse: the helper that reports refused position writes was put inside the
interface table, where a local function cannot go. Every server running it refuses the
mod. It is a top-level local again, and the parse is checked before anything is
released -- the check caught it and the release ran on regardless, which is its own
fault to fix.
Version: 0.22.1
Date: 2026-10-17
Fixed:
- The position writes on a copy say why they were refused. They were wrapped and silent,
and a silent refusal is indistinguishable from a copy that follows: the write happens,
nothing changes, nobody is told. Three faults today were hidden by that pattern.
Version: 0.22.0
Date: 2026-10-17
Added:
- A copy follows the real platform: the position fields the manager pushes (space
location, connection, distance, paused) are applied to a copy that already exists, each
write made only when it differs and wrapped, because these are the game's setters on
something that is, on a planet server, only a copy.
Version: 0.21.4
Date: 2026-10-16
Fixed:
- A planet server's copies have no asteroids, ever. One sweep when a copy was made was
not enough: a copy sits at a space location and spawns them regardless, so the sweep
runs every second from a handler registered once at load. There is no switch for it --
spawning comes from the location and a platform has to be at one to exist -- and the
space server's platforms keep theirs, because asteroids are part of what a real
platform is.
Version: 0.21.3
Date: 2026-10-16
Fixed:
- Creating a platform passes both required fields. planet is a space location and
starter_pack is space-platform-starter-pack, which the game's own prototypes name --
asked for with plate rather than guessed.
Version: 0.21.2
Date: 2026-10-16
Changed:
- platform_api asks the game for the starter pack's item name, because creation requires
one and a guessed name is the third guess today the game has had to correct.
Version: 0.21.1
Date: 2026-10-16
Fixed:
- mirror_platforms walked the list it was sent with ipairs, and nothing was made: the
JSON is decoded by the game's own helper and the shape that comes back is the helper's
business. It walks either shape now, and reports how many entries it saw and how many
were usable, so a list that arrives unusable says so instead of looking like a fleet
with no platforms.
Version: 0.21.0
Date: 2026-10-16
Added:
- mirror_platforms(entries): make, keep or remove this server's copies of the fleet's
platforms, as ordered by the manager. A copy is a hub and its cargo -- the starter pack
and nothing else -- with no asteroid spawning and nothing that can damage it: nothing
here runs a platform. A platform that has left the list is removed, because a copy of
something that no longer exists is a lie players can stand on.
Version: 0.20.0
Date: 2026-10-16
Added:
- platforms(): what this server's platforms are -- name, index, state, location,
connection, distance, paused, whether it has a hub, hidden, and how long until it is
deleted. Read-only, and every field is one the runtime docs list for LuaSpacePlatform.
A planet server reports none, which is a real answer rather than an error.
- platform_api(): the creation call the docs name (LuaForce::create_space_platform) tried
with a couple of shapes under pcall, so its arguments come from the game rather than
from a guess. Two of this fleet's outages were guessed calls.
Version: 0.19.0
Date: 2026-10-16
Changed:
- The mod does nothing at all until a node tells it what it is. It is a driver: it
reaches into the game's components and the node decides what is done with them, the
order coming in over stdin and the event going out over stdout. A server that never
hears from a node -- somebody's own save, a server with nothing to do with this fleet
-- never gets an identity, and now every action in the file does nothing: no surfaces
created, no players moved, no chunks cleared, no scenario touched. Loading it changes
nothing.
Version: 0.18.4
Date: 2026-10-16
Fixed:
- The sweep had two copies of itself and the older one was the live one -- in Lua the
last definition wins -- so it still called get_chunk, the method this build does not
have, and cleared nothing on any server while reporting an error per surface. One
copy, and it asks the surface API rather than assuming it.
Version: 0.18.2
Date: 2026-10-16
Fixed:
- The sweep no longer asks for a chunk with a method this build of the game does not
have (get_chunk), which threw from a boot-time handler and took clearing down with it
-- including the report of what had already been taken off. The entities go first and
now always report; chunks are deleted only if delete_chunk is there at all.
Added:
- surface_api, which reports which of these calls the game actually has, so the next
question about it is answered by the game rather than guessed at.
Version: 0.18.1
Date: 2026-10-16
Fixed:
- 0.18.0 did not start. The spawn-position check called get_spawn_position with no
argument where the API wants one, and the error came out of a boot-time tick handler,
which is non-recoverable: every server running it quit as it loaded. The spawn
position is set on the surface this server is for instead of being compared with
anything, and every step of the boot work is wrapped, so a fault in one of them is a
log line rather than a fleet that will not start.
Version: 0.18.0
Date: 2026-10-16
Added:
- A player standing somewhere they do not belong is put back on the surface this server
owns. It happens only when they are not on that surface, and only after
route_if_elsewhere has had its turn: looking at another server's planet is a journey
and connect_to_server takes them there, and a redirect already in flight counts as
handled, so nothing fights the connection being made.
- A surface this server does not own is cleared on boot: every creature on it is
destroyed and the chunks around the origin are deleted. A fleet server's save is a
nauvis world whatever planet the server is for, so nauvis is generated -- spawn area
and biters -- before anybody arrives, and on five of the six servers nobody ever goes
there. Those biters are a UPS cost paid every tick by a server playing elsewhere.
- The spawn point moves to the surface this server is for, so a player arriving without
a body does not generate a fresh spawn area -- biters and all -- on a surface that was
just cleared.
- clear_surfaces, so the manager can ask for the same thing after loading a save.
Changed:
- The report says which surface the spawn point is on and what the last clear took.