Functorio
bartoszmilewski.com
bartoszmilewski.com
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.
Just connect blocks A and B in some hardware description language. Further describe B as an assembly of blocks A and C.
Ask a compiler such as yosys to flatten your hierarchy down to a set of primitive blocks (say, A and C). Once you have the diagram, use a custom placer and router to position it.
There might be additional constraints while placing blocks. In silicon, this relates to impedance, design rules, and making sure the clocks are properly synchronized (adding buffers, etc). In factorio, this could be making sure conveyors are the same length, placing extractors on resources, etc. But the general topology doesn't change, since you are the one specifying it.
Note: I've done some, but very little logic synthesis, this is really a bird view.
Does Verilog allow the description of throughput or a capacity constraint? I'm imagining a situation where a specific component (or belt) can only allow so many messages per second or needs less than a specified amount of current. Or is this concept somehow handled in a different way when specifying circuits?
Verilog and VHDL allow specifying delays, which is basically troughoutput. Basically:
when input changes:
computed_output = f(input)
after 10ps:
actual_output = computed_output
That's not actual syntax, mind you, I am a bit rusty for this. But the idea is that you either make sure every delay fits in your clock period, you use different clocks, or wait a few clock cycles to sync everything (which is the same as having different clocks).Of course, you can oversize a capacitor to drive a high-capacitance line faster, and that would require more current. I don't think logic synthesis tools can handle that sort of compromise yet.
This is also why non-sequential (no clock) logic is hard: you would likely need synchronization signals so that the rest of the circuit knows when it can change the inputs (maintaining those during setup and hold times is necessary to guarantee valid output... try changing the input numbers while you perform a multiplication by hand).
And that class of issues is likely not a problem at all in factorio: I have only played mindustry and infinifactory, but I guess that factories do not run until they have the right input materials? Control signals are already there, in the form of {material present, material absent} on the belt, and factories are already fully-fledged state machines.
---
It would be cool to have a CPU/GPU/Circuit design game that literally made a game out of designing logic gates and instructions as a game - but based on real-world circuit design....
As for your idea, Zachtronics had one for a while, but it was flash, so I don’t know if it still exists.
Thats the one
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.
Electronics is just inherently 'parallelised', and software generally isn't, I get that. But some how we built up from parallel hardware to procedural synchronous (I know it isn't all but let's be honest it ~~all is) software, then built up further to sometimes wanting parallel again, and it's just sort of hard (er than it seems it should need to be) to use?
I challenge anyone who's used exclusively procedural languages to try an HDL (like Verilog or VHDL) or at least a high level declarative language (like Prolog or HCL/Terraform, as long as you view it as a language rather than config files) and not feel refreshed.
> Programs like Quartus
Egh, if I have nightmares tonight I'll know why!
Building complex logic ins declarative languages is one of the most rewarding things I've ever done. I tend to prefer a strong focus on type transformation when approaching a problem in any paradigm (I'd tend to read "Get the user's name" as "Create a transformation from a User ID to the User's Name and then cast the value") but just putting all the blocks for declarative programming together and then saying "Now, go!" is quite satisfying.
Clock signals do seem like a very useful abstraction (when I have my software-hat on) - not sure how you'd do it for a general purpose CPU however.
Most tools operate on the compressed, binary header including, base64 encoded blueprint strings, not the raw blueprint JSON payload.
It would be comically trivial to setup a .gitattributes filter[1] to do the conversion for you on checkout (to the base64 form) and commit all JSON, allowing for beautiful diffs.
It's a bash one-liner[2] to turn JSON into their base-64 form and into your clipboard anyways.
[0] https://wiki.factorio.com/Blueprint_string_format [1] https://git-scm.com/docs/gitattributes#_filter [2] left as an exercise for the reader
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.
Comparing Factorio to Satifactory (basically a simpler Factorio but in 3d space) - component layout gets a lot easier to optimize since you can essentially float rando chunks of logic in random parts of the sky - Factorio does have an interesting mod[1] to allow what's essentially a black-box subroutine but the majority of the headache is trying to build a relatively compact (and thus defensible) layout while also allowing yourself the room to re-tool the setup as needs change.
Building absolutely can be automated - there are a lot of self-replicating structures out there, most of which automate the forward deployment of defenses since that's a real issue you're going to need to deal with.
Yup that's exactly what I was thinking about. If you don't have to optimize, then you can mix and match heuristics to get the job done. If you have to optimize... now the search space gets real big real fast.
Optimizing layout is a very interesting problem and one interest component in Factorio in particular is that you have some real values to measure as output like:
1. Total space used
2. Total energy required (more inserters means more power - more belts usually means more space)
3. Throughput
4. Pollution produced
5. Tile-ability of the design.
6. Proportion of unused space within a bounding box
Probably a few other fun ones - it actually sounds like a pretty approachable problem to get objectively good results out of.
You'd need some empirical data on train acceleration and top speed, but once you have that plus some generous assumptions about latency tolerances, you can probably automatically lay out tracks and train routes and resource outposts.
At some point, the inserter-to-belt interface becomes a serious bottleneck. CPU load does too. As for enemies, you can basically treat them as a solved or solvable problem after artillery even if you don’t turn them off.
But 98% of the problem remains: generating a layout.
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?
This would be a great application for ML or genetic programming.
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.
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.
These kinds of projects are one of the only things I get FOMO over studying physics - I really like the idea of getting a few months to (say) write a compiler as a group rather than piles of utterly inane lab work teaching me how to use equipment I already know how to use
I'm having some trouble coming up with plausible inferences from that fact. Do you mean to imply that "when you have a hammer everything looks like a nail"?
The category theory for programmers crowd argue that categorical diagrams (annotated graphs) are the right way to reason about software to gain insights — and the rest is describing the equivalence between functions in a type theory and maps in a category.
Your mental model of directed graphs is a functional model.
In the more general sense that may be true, but I was talking about Factorio specifically, where I'm using the graph representation to do the analysis.
Or rather, just because a functional interpretation exists doesn't mean I actually reach for the toolkit filed in my memory in the box labeled "functional stuff". In practice I mostly reach for the boxes I've filed away under "linear algebra", "graph theory", and "circuit design", which aren't things I typically reach for when I'm actually doing functional programming.
it's literally arrows
It's not the only possible way to model the world, but it absolutely is a unified approach that you can apply to a whole system, and it tends to work better when you do - trying to apply "FP as a tool" within a fundamentally mutation-oriented system (for example) gets you a very limited subset of the benefits, IME.
Right. Which is very much opposed to your initial "FP is a tool, not a unified theory on how to model the world".
We are in Erlang though, so I wouldn't call it 'mutation' necessarily. The stateful bits are individual actors, creating a new internal state in response to messages.
To me, a functional language without tail recursion seems pointless. Is it possible to abstract away whether you are recursive or iterative, like an iterative recursion scheme?
One thing that I think would be great is if there was a Python approach to effects systems like Polysemy (free monads); what might an in between be for this?
Tail recursion is a low-level detail IMO. Scala does fine without it.
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.
> I tried Minecraft [...] but I didn't much enjoy the [...] lack of "systems"
> I also just enjoy sitting back and watching systems work
> I prefer top-down planning
Yeah, you should love Factorio!
There's a demo version which gives you a pretty good idea of how Factorio feels. I forget whether the demo runs on Linux, but the full game is straightforward to run on Linux, by which I mean I forget whether you need an emulation layer.
> Would you mind sharing what it is that keeps bringing you back to play?
To be fair, I did reach the "I'm done with Factorio" point. I have one last hurrah of getting one last accomplishment in progress, and then I'm realistically done with the game.
But to answer your question: it's because Factorio's systems are extremely deep, where the nature of the puzzles and the way you think about them keep evolving. And as you solve those problems you get the satisfaction of seeing those systems working. It's the same high I get from seeing my code work, but in video game form.
> 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).
Factorio isn't the type of game you can play for a few minutes at a time. For me, Factorio relies on the same kind of flow state I use for other focused work. So I play it when I opportunistically have long blocks of time. Most of my hours put into Factorio were from earlier years of my life when I had fewer responsibilities and obligations.
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.
In Excel you can't modify existing state in a cell, but only transform and output the results in a new cell.
On the other side, within any programming environment, you can entangle your data, output layout and businesses code and thus create an unmaintainable mess.
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.
Sure you can
and many times
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?
[1]: https://gist.github.com/chrisdone/672efcd784528b7d0b7e17ad9c...
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.
Imperative programming would be like instead of having your factorio factory, having 1-32 employees running around at ludicrously fast speeds doing all the work trying not to crash into each other.
Each entity has a state, time is advanced, and the threads run through their queue of entities and update their state, along with the state of connected entities. Since some entities interact directly with other entities (such as two fluid pipe segments), these queues are ordered (so the fluid movement and pressure calculations make sense).
For example, a belt would advance the items on it 1/60th of its speed. Inserters would look to see if there's room in the destination, if there are items within their reach on the belt, and start moving to pick them up. Assemblers would check to see if they're currently building something, if they're full (the quantity that determines "full" is based on whether there's an outgoing inserter attached), if they have the necessary ingredients in their incoming buffer, and start incrementing the creation timer. The outgoing inserter would check for items in the assembler's output, grab them, and so forth.
Basically the whole game is driven on rate and ratios, not just ratios.
Both of those constraints do exist on programming but they don't come up often enough that generally we'll discuss or review code entirely ignoring those effects and instead favoring correctness.
Most of the items you listed aren't really important when discussing the nature of a function in the same way the fact that I happened to write my 1+1=2 algorithm on a RISC architecture isn't fundamental for teaching - sure it will potentially behave differently on a different processor - sometimes an intel bug might even cause subtle float errors - but those are implementation details and this article is focused on theory.
Factorio, as normally played, is much closer to analog electrical circuits than it is to digital computers. In flows of resources and outflows of products that change dynamically and in real time.
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.
There are so many things that we describe as a graph of boxes with inputs & outputs that we can indeed draw many parallels see many similarities between them. I think it's quite interesting to think about this diversity of tools and try to analyse what's common and what isn't between them (some are stateless others aren't, some have the notion of "time" and some have not, some are closer to state machines while other closer to mathematical functions, etc.) and it gives a lot of inspiration about new/alternative programming models & architectures
Factorio is incredibly resilient to mistakes which is a bit odd in that style of game - normally bad input in an assembly line game like that will result in a system freeze but Factorio just shrugs and keeps on keeping on.
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.
> 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.
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.
Visually explaining abstract concepts works a lot better in building an intuition than explaining them in abstract terms in my experience.
(I've played a lot of Factorio, but haven't really delved very far into the more exotic things that can be done with blueprints and circuit networks.)
This talk is 3 years after release, and includes all the hindsight they gained from that. Also, the parts talking about the netcode are quite amazing, and the precision of their predictors that they attribute to using ECS.
https://www.youtube.com/watch?v=W3aieHjyNvw&feature=youtu.be
ECS systems overlap functional programming (FP) only in that both are data first.
Purely functional would mean never mutating an existing value, functions only receiving one value and returning another, monadically binding side effects and so on.
To put it bluntly, a non-trivial computer game in pure FP would hog every resource in your system to barely hit single digit frame rates.
(Disclaimer: I love FP, and use it at my day job. It is not fit for games though)
I love programming in a variety of paradigms and settings and I'd suggest you take a bit of a closer look at what you can get out of statelessness and higher order functions in particular. Assuming you're working in a pure JS variant and not a strongly typed FE language (like Elm or TypeScript) my absolute favorite quality (strict typing) isn't available, but there are a lot of tools that can be quite helpful.
Especially if it is considered as a competitor to object oriented programming. Unfortunately it is considered that way, and it is really a serious problem today.
People try to do stuff with FP that should be done with OOP and run into serious problems. OOP and FP paradigms work good together, but FP is often overused.
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.
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.
Hmmm, no.
But, nearly all of them have functions, at least as a concept. Then in some languages they are called methods, sub-routines, procedures and more, but the concept are mostly the same. A collection of lines of code that does something, probably with a name.
Only if you write your code that way, and then it's a self-fulfilling prophecy.
There's a good amount of mutable state that's just incidental for particular algorithms, and not intrinsic to the problem you're solving.
(FWIW, I'm in the latter camp)
I was of this opinion until I realized I was basically doing digital logic in minecraft. You're right in that engineering without crud is very fun.
It was pretty fun for the first half hour. Then for the next fifteen minutes something didn't feel right. To quote Robert Zemeckis, it felt like kissing your brother.
The other thing that was hot around that time was UML, and it feels like half of UML is just trying to get lines not to cross each other. Ding! I was doing some of my least favorite work 'for fun'. Closed that window, pushed away from my desk dramatically, and went for a cup of coffee and a bit of perspective.
Make a factorio-themed reskin of labview.
If it took me 100 hours to complete a coding project of the magnitude of a factorio playthrough I would say I'm pretty bad at coding.
I'm of the former of your two listed camps, but I don't try to look at how the game is like coding and look at it how it is like modded minecraft. Learning rules and discovering tricks and being creative is a fun way to spend free time. Maybe coding can have a similar track, but it often feels heavy on the grind.
If you want to make real software, you have to do your software engineering in the middle of a sandwich with tooling and dependencies on one side and your platform on the other.
Dealing with either of these can sometimes be satisfying, but they both tend to require a lot more effort than is desired.
Further, how was launching your first rocket anything other than rewarding?
With all of that said though, getting to a result is always a great feeling and basically why I still play it after all of these years.
Launching the rocket was inevitable after a certain point, it was just a matter of tuning everything well enough to get there as quickly as possible, which seemed always to be hampered by some tedious task or another. Having robotics much much earlier in the game might have helped a lot there.
You were watching a speed runner who knew exactly what they were doing. I was a first time player who didn't. I spent north of 30 hours tediously laying out factory bits and wondering "why the hell can't I automate this?"
P.S.: and hey wait, whole speed runs of Factorio seem to be in the range of 2-3 hours, and you're suggesting under 2 hours isn't late game?
But robotics itself only requires blue research. In my own speed run of ~6h40m (admittedly, on an older version of the game, but the game pre-blue science hasn't changed much), I got blue science in about 2h, and bee-lining for robotics after that would only take a couple of researches beyond that (advanced oil, electric engine, robotics, and then construction robotics to do anything useful IIRC).
I wouldn't call anything that takes only blue science to get to be late game; for me, that requires at least purple or yellow science. Robotics is on the other side of the oil barrier, which is definitely going to push it far later in the game for new people, but it's also accessible before you hit the point of needing to repetitively scale up your factory (which tends to come with purple/yellow science), so it is accessible before you really need it. However, the game doesn't particularly guide you towards knowing that it exists, so I can see how it might be frustrating for new players.
IIRC, Factorio does have a sandbox mode where you can just create arbitrary designs without having to gather/assemble the stuff first.
I will note that someone who does enjoy the game would never describe themselves as having "finished" it, there is always more to expand, more to optimize, etc. Not to mention all the mods to explore!
It definitely scratches that Factorio itch but in a different way.
Roadmap includes a ton of interesting things which should make it more challenging in the long run.