back
193 comments
I wonder how difficult it would be to implement a language for specifying Factorio factories without worrying about physical layouts. This post provides a lot of good insights into how that could be done. Once a factory is specified, a compiler could turn the high-level specification into a blueprint or a valid save file to be loaded up in the game.

Of course, the compiler would have no way to lay out the factory with respect to available resource deposits. Maybe that would have to be part of the specification as well? Or maybe the programmer (player?) could pass an empty map file as a compiler argument.

Also, this doesn't give any consideration to the tech tree or enemies within the game. I guess those could be compiler flags, as long as we're dreaming.

Look, all I'm saying is that it would be really cool to be able to check factories into version control.

I actually made this, a factory "compiler" that takes in a target output (eg. 1000 science / minute), and lays out a blueprint working from raw inputs to the desired output. It's hacky and buggy (and by this point probably out of date) but you can see it here:

https://github.com/ekimekim/factoriocalc/tree/generator

The factory it generates is a main bus design, with discrete "steps" on the bus that take certain inputs, process them in a standardized area, then put the output onto the bus. It also stops every so often for "compaction" where it reduces several low-throughput belts into fewer high-throughput belts. The whole area is covered by roboports to enable automated construction (no logistic robots are used, production is entirely done by belt) along with power lines etc.

The full layout looks like this:

    ||bus||
    |||||||  ...beacons...
    vvvvvv\-> input to process
    ||||||
    ||||||/-- output from process
    |||||||  ...beacons...
in a repeating pattern, each process step sandwiched between two lines of beacons.

It is very much not optimised, the idea was to make something as simple as possible that would work.

There's also a blueprint-to-ascii-art renderer which I added to help debug layout issues.

I haven't played factorio in a while but I do plan to keep working on this. Due to some poor choices early on implementing the last few fiddly (and less interesting) bits ended up being the bottleneck. In its current state it can go from raw inputs to a full suite of science packs, though some of the recipes are probably out of date, and I think there's some bugs in a few of the layouts that manifest in the finished blueprint as belts the wrong way around, etc.

Personally I think most of the game is actually about managing changing requirements and layouting, but there's certainly a subset of gamers that are after the perfect endgame base (the X science per second crowd). If that's the target group of the compiler then you can assume that enemies don't exist (they waste CPU power), resources are decoupled from the factory using trains (they run out too fast for tight integration) and that the entire tech tree is explored (everything before that is just a unimportant bootstrap base). Making those assumptions certainly makes the compiler more tractable, but it also gives you another interesting metric to optimize (CPU load of running the produced layout)
Such a language could be an extension of VHDL or verilog (or more likely, just a library in such a language). The map could plausibly be the equivalent of an FPGA architecture, and build upon existing tooling. Caveat: I'm a bit of an FPGA noob and have zero clue how one specifies a detailed FPGA fabric to such tooling.
You absolutely can check factories into version control. They are exported as 'blueprints' and many blueprint management sites exist. One such example: https://factorioprints.com/
Hardware description languages such as VHDL/Verilog feel very similar to Factorio in that "everything is happening at the same time in parallel". Definately takes a while to wrap your head around it coming from procedural languages.

The "compilers" for these languages have very sophisticated "routing" algorithms which synthesize efficient physical layouts of circuits.

Programs like Quartus even let you edit your description visually as an abstract block diagram by dragging around wires/placing blocks.

I have been day dreaming about a program taking a factorio blueprint and running it through a genetic algorithm to produce a compressed but still functional version. I can imagine it could produce some interesting spaghetti layout! One way to ensure that the end result still works the same would be to only let the algorithm work with a selection of predefined refactoring steps that guarantee that the factory does not break. Another maybe more interesting approach would be to include some actual simulation that could test the factory. With the simulation the algorithm could work more freely with possibly destructive changes and apply them until the factory works as expected. This I figure would produce even more interesting spaghetti..
There's a haskell project called Clash[1] that produces VHDL/Verilog that gets pretty close to this for FPGA development. [1]https://clash-lang.org/
This will take a specification: https://kirkmcdonald.github.io/calc.html#tab=graph&data=1-1-...

But 98% of the problem remains: generating a layout.

I don't think it's actually that hard, as long as you don't try too hard to optimize the layout itself. Write a few heuristics into the system and you can get really close to the thing you're describing. Most of the throughput modeling is pretty straightforward from an algorithmic perspective.

This probably gets the most interesting in the super-late game where players have unlocked all of the tech and are building megabases. Now that the making of everything has been automated, perhaps the building of everything should be automated as well.

It could take inspiration from some speedruns formats where the "seed" is pre-selected. That way you could have multiple people compete to write the most efficient factory in terms of resources and space to generate as many rockets as possible, and everyone with the same resource limitations and map layout!
I’ve been noodling away on this related question:

Given that sub factories in Factorio can be graded numerically on units/s output, and given that Factorio has a built in blueprint system, could one use ML to automatically create the most efficient blueprint possible for a given output?

I really want to see a factorio app with a pipeline that takes an HTTP request as input and eventually converts it into a useful JSON at the end.
Not too far off from circuit design languages (VHDL, Verilog) to me.
It sounds like it would be really easy to make a game like that, without the hassle of a 2D grid.
"Fractorio"
I can definitely see the point the author is trying to make, and I agree that it naturally lends itself to a functional model of how the game works.

On the other hand, and this is speaking as someone who has played the game for an embarrassing number of hours all the way into endgame "megabase" territory: my mental abstraction of the game isn't really functional. It's directed graphs. Sure, the two views can be equivalent representations, but I find thinking about the game as a directed graph (and reasoning about throughputs in a graph representing a network) to be the perspective that gives actionable insights most readily.

It also seems to me that the author is conveniently ignoring the mechanics that aren’t mapping well to FP. To me, belts and buffer chests are much easier to describe as a mutable data structure (FIFO queues). That’s also analogous to how real world applications typically look like: functional core / imperative shell (see also Gary Bernhard’s brilliant ’Boundaries’ talk). It’s a nice article to introduce FP but I get immediately suspicious about statements like ‘Engineering is FP’. FP is a tool, not a unified theory on how to model the world.
Factorio is a genre-defining game, and I think the number of clones is a testament to that.

Factorio is often compared to programming, but it's closer to Excel where the logic and the output live in the same space. The game does a great job letting the user build with programming-like constructs without them ever having to understand any theory.

Factorio killed just about all ability for me to actually do normal work for two weeks. It took over my brain: all thoughts were about logistics, supply chains, the structures that would deliver them...

It was highly addictive, and fun and fun at first, but then got stressful. I've never been so relieved to finish a game, or had such an anti-climax watching the simple rocket animation.

I can't say I hate I hate the game, but saying I like it doesn't quite feel right either.

> Merging an empty belt with any other belt, makes no difference.

I know the intended meaning was that it makes no difference to the result belt's type, but in-game it does have the important difference of putting all material from the input belt onto just 1 side of the output belt, halving throughput.

If in this image https://bartoszmilewski.files.wordpress.com/2020/11/unit.png the incoming belt had both sides filled, both would go onto only one side of the outgoing belt, possibly causing some stalling.

Do type systems exist that include a notion of "throughput" or "capacity" like this?

An interesting writeup, but <troll>like most oversimplified functional programming writeups</troll> they are ignoring a lot of external state around Factorio "functions" and "composed functions" - things that absolutely need to be considered when creating a factory.

For example: energy requirements, inserter speed (and the impact of that and inserter stack size on throughput), input/output bottlenecks, pollution, efficiency modules (which really mucks with the "an assembler is a function" analogy), beacons, and probably more.

>In Factorio, the nesting of functors is drastically limited. It’s possible to produce belts, and you can put them on belts, so you can have a beltful of belts, Belt Belt. Similarly you can store chests inside chests. But you can’t have belts of loaded belts.

You can, however, have vehicles on belts, and they have storage: https://youtu.be/JgqT6DEnBGM?t=2082

AFAIK that's where the nesting ends though.

To me, Factorio looks more like dataflow programming (https://en.wikipedia.org/wiki/Dataflow_programming) much more than functional programming, but I guess people see much more similitude with what they are used to.
I love how quick haskell folks are to bring types and say "hey look, look how neatly we can express this". What is skipped is that assemblies take unordered input. Why this is important, because the neatness would start to collapse. You would have to type `(a, b, c) -> d`, `(a, c, b) -> d` or you would require monads (case item of a) or there is some other fancy type machinery in haskell for that(without checking I am sure there is).

And we should talk about this even before we start talking about linear types. Hidden bonus is: we get a huge benefit of haskell's autocurrying matching the way "production" works in factorio. However why I am writting this. I am very disillusioned in haskell - getting something that seems about right(few rough edges) without hardcore typing bonanza is order of magnitude easier than getting precise types that you can depend on (since types that depend on them will be even more complex).

Its funny to me that some of this "precision" is lost(unheard of in haskell community). Especially by someone like Bartosz, who I can only speculate did it on purpose to fit to his story and not show the Hommer Simpson's pulled back :).

ps: I returned from vacations during which I was reading haskell/on haskell, as I often do on vacation. I am not trying to bash, haskell is pretty amazing even without any utility.

I think this is a neat attempt to make functional programming more acceptable but I really dislike the first section on assembler production

> If Factorio were a strongly typed language all the way, there would be separate recipes for producing different assemblers (that is assemblers with different recipes). For instance, we could have:

Technically yes - in a strongly typed language assemblers would be specifically specialized at compile time. For the Haskell side of things they go on to specify a higher order function to produce an assembler that can then be given a purpose by a second call. However they dropped the ball a bit on the C++ side and, while generics cause grief, they are quite good to learn about and this is a perfect place to use a templated function that could infer the correct type at compile time.

In 1986 people wanted to make real programming more like a computer game:

https://www.youtube.com/watch?v=I9LZ6TnSP40

Today, when we have much more computational resources, I'm reading this article about representing Factorio as static text with compiler checks. Something somewhere is off.

I wrote a similar article explaining Kafka with Factorio analogies a while back: https://medium.com/@ruurtjan/understanding-kafka-with-factor...

Visually explaining abstract concepts works a lot better in building an intuition than explaining them in abstract terms in my experience.

I don't really know much about functional languages, but did the section on higher order functions throw any flags for those of you who know both functional programming and the game? The "assembler" components, when used as an ingredient in a recipe, aren't really acting as assemblers anymore, just as a component...
John Carmack spent some time in one of his famous keynotes talking about functional programming. On the one hand, obviously video games tend to be very stateful, and implementing them in imperative terms is natural. On the other hand, tons of specific things you do inside a game (or in any program) can be described as pure functions, and doing that is often a great idea. I think it was this part of this keynote: https://youtu.be/Uooh0Y9fC_M?t=4660
I love the way the author explained it. And surely there are places where functional programming helps eg. linear processing of data, analysis, processing. However in my field, frontend, there is more focus on interactions between very short factory lines. So functional programming does not shine, and often just leads to increased complexity and risk of mistakes.
Where does one begin playing Factorio? Is there a place which doesn't make it feel like work?
That was fun, now how do I build a warehouse dispatch and accounting 3-tier with functorio?
This is a fun read. Learn Haskell, functional programming, and game design all in one.
Bartosz and Factorio? That was an unexpected, but welcome crossover!
> It’s a simulation game called Factorio, in which you are given resources that you have to explore, build factories that process them, create more and more complex systems, until you are finally able to launch a spaceship that may take you away from an inhospitable planet. If this is not engineering at its purest then I don’t know what is.

I think that good engineers should focus first on how to prosper on the current planet which was favorable enough to sustain their live until now, rather than carelessly exploit its resources with a delusive goal of finding a more hospitable place somewhere else.

I started to dream in assemblers. And belts. Endless belts.
Would sure love something browser or phone based that's quick and something I can hop in and out when not busy. I'm currently on a factorio binge...
This is kind of unrelated, but it would be so cool if assemblers like that existed in real life. It's a "hard problem" unfortunately.
More evidence that, not only do we live in a simulation, but that our simulation is running in Factorio. Great writeup Bartosz.
The inserter function automagically picks a direction for the ingredient/product flow.
> The building blocks of every programming language are functions.

Hmmm, no.

Most programs are not factories. Programming is mostly about handling state.
Bartosz is the best
I look forward to the inevitable two camps of comments on anything related to Factorio: "This is just software engineering, why would I do that in my free time?" and "This is just software engineering, but without all the distractions, frustrations, meetings, and dependencies - how can I do this all the time?"

(FWIW, I'm in the latter camp)

I know this kind of misses the point, but Factorio is one of the most addictive and rewarding gaming experience I've had. Beware: within months it ate up collectively hundreds of hours from myself and members of my friend group.