top | item 26157969

Functorio

697 points| ibobev | 5 years ago |bartoszmilewski.com | reply

193 comments

order
[+] bmgxyz|5 years ago|reply
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.

[+] ekimekim|5 years ago|reply
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.

[+] wongarsu|5 years ago|reply
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)
[+] klyrs|5 years ago|reply
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.
[+] NickBusey|5 years ago|reply
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/
[+] arduinomancer|5 years ago|reply
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.

[+] apabepa|5 years ago|reply
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..
[+] bobnamob|5 years ago|reply
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/
[+] munchbunny|5 years ago|reply
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.

[+] momothereal|5 years ago|reply
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!
[+] ashtonkem|5 years ago|reply
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?

[+] ljm|5 years ago|reply
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.
[+] jcurbo|5 years ago|reply
Not too far off from circuit design languages (VHDL, Verilog) to me.
[+] muzani|5 years ago|reply
It sounds like it would be really easy to make a game like that, without the hassle of a 2D grid.
[+] munchbunny|5 years ago|reply
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.

[+] m_mueller|5 years ago|reply
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.
[+] herodoturtle|5 years ago|reply
> speaking as someone who has played the game for an embarrassing number of hours

I enjoyed reading that line - made me chuckle :) Would you mind sharing what it is that keeps bringing you back to play?

I'm a grey beard programmer, husband, father, and vanilla Linux kinda guy - and I've seen Factorio being mentioned on this forum quite a bit over the years. The chatter here today has once again piqued my interest to say the least.

I was once an avid gamer in my youth, but these days I have little free time - so if I were to pick up a game, it would have to be the sort of experience that I can play for a few minutes here and there (and / or immerse myself in for several hours at a time when the opportunity arises). It would also need to run smoothly on Linux, and be relatively easy on computing resources.

I tried Minecraft for a bit - and it ticked most of the above boxes - but I didn't much enjoy the interface and lack of "systems" if that makes sense. I love building things, but I also just enjoy sitting back and watching systems work. I prefer top-down planning / building games like the Sim City of old but that got boring pretty quickly.

Anyhow I think I oughta just install Factorio and check it out - but I'm deeply curious what it is that keeps bringing you back for more.

[+] willis936|5 years ago|reply
Because factorio is much closer to a gui-based HDL layout tool than a programming language. It might be fun to program a simulated annealer to play factorio.
[+] zygomega|5 years ago|reply
I often think about functional programming as a directed graph consuming information.
[+] dexwiz|5 years ago|reply
The author is one of the main sources of Category Theory for Programmers material. Take that as you will.
[+] dnautics|5 years ago|reply
if you don't mind going impure, you could translate those functions into actors and (easily) test their resiliency against alien attack using a virtual machine like the BEAM.
[+] dexwiz|5 years ago|reply
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.

[+] psychoslave|5 years ago|reply
Excel might spur users more to not separate code from data, but you can do so. Nothing prevent users from having one sheet for raw data input, one for output layouts, and the businesses implemented in dedicated formula sheets or VBA modules.

On the other side, within any programming environment, you can entangle your data, output layout and businesses code and thus create an unmaintainable mess.

[+] devenvdev|5 years ago|reply
I tend to disagree, there are some obvious aspects of programming in the game: refactoring spaghetti, converting monolith into microservices, multiprocessing, etc.
[+] ineedasername|5 years ago|reply
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.

[+] an_ko|5 years ago|reply
> 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?

[+] rrobukef|5 years ago|reply
The inserter type is wrong when considering fluids, maybe it should be `inserter: Item a => a -> a'? Oh well, leaky abstractions are endemic.
[+] falcolas|5 years ago|reply
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.

[+] Groxx|5 years ago|reply
>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.

[+] roguas|5 years ago|reply
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.

[+] munk-a|5 years ago|reply
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.

[+] romaniv|5 years ago|reply
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.

[+] bee_rider|5 years ago|reply
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...
[+] oconnor663|5 years ago|reply
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
[+] tomaszs|5 years ago|reply
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.
[+] sudhirkhanger|5 years ago|reply
Where does one begin playing Factorio? Is there a place which doesn't make it feel like work?
[+] jon-wood|5 years ago|reply
Factorio by its nature does tend to feel a bit like work, whether that's a good thing or not is going to depend on your personality.

Whether I enjoy it depends very much what I'm doing in my actual job, if I'm in a period where I'm hands on writing code every day then finishing work and playing a game which is about incrementally building a system that inevitably needs refactoring or completely rebuilding to meet new requirements isn't much fun. If I'm in a period where the day job is planning projects, or supervising things with a long term payoff, Factorio is great for the satisfaction of picking it up and being able to achieve something concrete in a few hours.

Just remember, on at least your first 10 or so runs, what you think is a massive base that just needs some incremental improvements really isn't. Its the base you build in order to build the components for your actual base.

[+] devenvdev|5 years ago|reply
You just start it. Beware - this game is notorious for showing you in your face that whatever doesn't work in your base is YOUR problem, you made a mistake, probably plural, probably too basic to fix. So prepare to start over multiple times. It's my at least tenth attempt in 5 years right now. And it's lots of fun!
[+] wruza|5 years ago|reply
That was fun, now how do I build a warehouse dispatch and accounting 3-tier with functorio?
[+] jzer0cool|5 years ago|reply
This is a fun read. Learn Haskell, functional programming, and game design all in one.
[+] frozenlettuce|5 years ago|reply
Bartosz and Factorio? That was an unexpected, but welcome crossover!