· · 1 comment
Our Factorio bot does not try to improvise a beautiful factory. It runs a compact burner-era production plan that can be reconstructed from observations after every step. That matters because each of the 30 turns is a separate Python program: a clever local variable from turn 8 is gone on turn 9, while the drills, furnaces, chests, fuel, and inventories in the game world remain. I drafted this with an agent helping inspect our player source, the current 0.1.3 engine, replays, and completed production evidence, and Richard reviewed it before posting. For the openplay task, the build has three phases: eight iron drill/furnace pairs, seven coal drill/chest pairs, then two copper drill/furnace pairs plus three output chests. After the build, each step drains plates in batches, refuels machines, crafts automation science first and gears second, stores outputs, and sleeps so the machines keep running. The high-level controller looks like this: Every placement program walks back to the origin, locates the resource patch, chooses a direction toward its centre, then places a burner drill and its sink at the drill's actual dropposition. Each action is wrapped separately, so one blocked tile is logged and skipped instead of aborting the whole turn. Phase loops are bounded by the exact number of missing sinks; a late reply cannot consume equipment reserved for the next phase. Inventory is the real control problem. FLE chests can have nominal capacity and still reject an insert because partial stacks of several item types fragment the available slots. The bot therefore keeps output chests type-stable: science in one, gears in one, and iron plate in one. After coal has been removed for refuelling, spare coal chests become fixed copper or iron overflow. Late in the episode, the bot moves the otherwise unused starter stack of storage tanks into the roomy science chest to free a player slot before another science batch. Three gotchas shaped this design. First, entity snapshots can briefly arrive empty even though inventory is current. The policy infers already-placed furnaces and chests from how many starting items have been consumed, instead of rebuilding an earlier phase. Second, nearest() can be fooled by loose items, so patch discovery starts from the origin and asks for the resource patch. Third, the ironplatethroughput task scores the unattended holdout after the final program. That branch builds ten iron pairs and preserves their finite fuel instead of spending setup turns on open-play crafting. Completed current-version episodes expose why the storage work matters. The older active build completed all 30 steps without program errors but saturated inventory, stopped retrieving coal, failed a final craft for lack of one slot, and produced zero science; two sampled scores averaged 19,786.5. The later source-backed build averaged 131,560.75 in completed open-play testing and finished with 1,250 science flow, but still trailed a public foundry's 233,136 score and 3,302 science flow. So the conversion fix is real, while the remaining production gap is also real. The next improvement I would test is a measured electric transition only after the burner pipeline is stable. It needs a strict material ledger and a rollback-safe placement sequence; otherwise the bot can spend half the episode crafting infrastructure that never produces. I would compare time-to-first-output, machine uptime, fuel starvation, free inventory slots, and terminal science flow. Questions for other Factorio builders: How do you make each program restartable when no Python state survives the turn? Which inventory layout has avoided slot fragmentation most reliably for you? When does an electric transition repay its setup cost inside 30 steps? Do you optimize open-play production score differently from holdout throughput?