Learning AI Optimization w/ Factorio 2: Modelling

July 9, 2025
Example screenshot of a factorio blueprint

What is this project?

If you have not yet read the introduction, you can find it here. The abridged version is is: My goal is to create a system for determining the “best” possible Factorio factories based on footprint and cost to build.

Modelling?

So, one of the key things for making a maze solver, is making a maze that the solver can navigate. Instead of walking through a maze, we are laying out a factory. The mechanics of a normal maze are so simple they rarely even get discussed on their own, 4 (or 8) valid move directions, don’t go through walls, and that’s it. However, Factorio has a LOT of different mechanics I will need to implement to fully model the behavior of a factory. In order to start getting into the AI portion of this project in the time I have available I’ll need to trim the list of mechanics I’ve implemented down to something manageable. A description of each of the components I’ve implemented at that level of detail is below:

  • Assembler: takes inputs and produces outputs according to a particular recipe

Image of an Assembling Machine

  • Inserter: moves from tile A to tile B (always in a straight line)

GIF of an inserter moving items from a belt to a chest

  • belt: moves items placed onto it along a contiguous path

Example animation of belt layout

Notably absent for right now is the different tiers of each of these which operate at various rates. All I want with this initial model is something that hypothetically can place the output material on the output belt. This means no rate evaluation, no bottleneck consideration, not even considering powering everything. This excludes a LARGE list of possible components, but that is fine for now.

Blueprints

Factorio natively supports the idea of a blueprint; this is definitely the baseline concept we are going to use. A blueprint is just a layout of components. Blueprints as we define them will have 1 notable expectation, they must ONLY have “valid” placements of components. Valid is something that is going to be an ever evolving term, but to use the maze analogy, valid would mean not running through a wall, and not going backwards. In the base game a blueprint’s requirement is just that it components don’t overlap, so we are being a bit pickier in our model.

Expanding

So, I lied, this isn’t just about replicating how the game works in python, it also is about making a system for placing down the factory one component at a time. Not just the maze, but a model of how to take a step in the maze. This is a key parts of A*, finding all your next steps from a point. So it is important that a blueprint be able to determine ALL the possible “children” for it. We are going to do this by first determining all the border tiles of the map. Then trying to place a valid inserter, belt, or assembler on that tile. Assemblers are actually 3×3, so that adds a little complication.

Our starting point is actually going to be the “finish line” of the belt that we are putting the final product on, and from there we are going to work backwards. From a belt you can put up to 3 different orientations of belt (belts that would run in opposite directions of each other are invalid, and parallel is invalid). And you can place an inserter that deposits onto that belt. Meaning you have 12 belts, 4 inserters, and 0 assembler “directional options” from the starting position (assemblers are a special case to be explained later).

Image showing each of the possible inserters in the first step   Image showing examples of invalid belt placements from the initial point

Our “finished” definition for right now is going to be tracked by a list. I use a library which generates the list of assemblers we need (along w/ similar buildings, but we only care about assemblers for now), including specifying the recipe to be assembled. For now, we consider the factory ready once we’ve placed all the components from that list.

Special Rules: Why

So this is where I had my “big opinion with little expertise” moment. Because this “maze” will have a minimum of 16 possible “directions” it can go from a given point in the maze, being able to define what is a useful direction is important. Actually, 16 is AFTER I’ve put in the guardrails to avoid potentially useless options. If you wanted to be TRULY inefficient, just in the 4 cardinal border tiles from the start, you have:

  • 16 inserters
  • 16 belts
  • 12 assemblers (per recipe)

and then, after evaluating one of those 44 blueprints the next “directions” are:

  • 24 inserters
  • 24 belts
  • 14 assemblers (per recipe)

So to avoid having the list of blueprints to evaluate be an even more ridiculous mathematical explosion, I decided to put in some guardrails. No making a blueprint that “hopes” to meet the requirements for functioning at the end. Instead, you have to be actively working in the realm of functioning.

Special Rules: What

This meant some rules that are different from the base blueprint in game. We already covered the fact that inserters need to have a valid destination, but in order to place an assembler it must feed an inserter. The only valid things to put into the tile that feeds an inserter are an assembler, or a belt. Belts must be placed in a valid contiguous line of belts, or feed an inserter. I also decided to include a basic “needs and has” record so you can only put an assembler that makes a recipe that fulfills a need. This all combines to support the list of “remaining parts” being a measure of how complete a blueprint is.

To summarize, starting from the end you can actually guarantee drawing a web outward from there with each branch being in a particular order. So you can require that the next piece being placed satisfy that sequence to help minimize the number of “directions” you can go in from a particular point in the maze.

Unfortunately, there is a hypothetical world where you could keep placing belts or inserters forever, but if we do A star evaluation correctly this should be avoided.

Evolving the model

So, what things do I most want to add to this model? This is a surprisingly difficult thing to answer, but in no particular order:

  • Rates of production and transportation
  • Full belt detail
  • Other production buildings
  • underground components
  • input belts
  • more refined “progress” rules