Factorio and Software Engineering
I've been a software engineer a while now and I can say this with confidence - it is fun. It's great and I wouldn't trade it for anything else. It's so much fun that some folks try to capture the most enjoyable elements and put them into games.
I've played two such games. The first is Shenzhen.io. This one looks similar to what an engineer working on embedded devices would see. You solve puzzles by writing assembly code on low power devices. What makes this game great is that they remove the annoying parts of writing and shipping code.
- The requirements are clear, rarely true on the job.
- The edit-debug-compile loop is lightning quick. That combined with a great test suite means you can try several potential solutions in a minute.
- The platform your code depends on (the game itself) doesn't have bugs. You don't need to fix your dependencies before you start on your own code.
Should a software engineer play Shenzhen.io? The gameplay isn't for everyone. For some people it feels too much "like work". At the end of the day you want to relax, not work at tasks that feel similar to what you did for 8 hours. Despite that, I think it's worthwhile just to see how much more fun a task becomes when the requirements are clear and developer tools are fast. Everyone knows that investing in our direction and our tools will help, but having fun playing this game reinforces that feeling.
The second game is Factorio which released last Friday, though it has been available as an early access preview for about 4 years now. Those who've played it are probably scratching their heads right now - this is a game about building a factory, not coding. You work with conveyor belts, metals, oil products to craft products necessary to make a spacecraft.
And yet, this game reminds me of software engineering more than any other. Let me explain why.
- Technical debt. Do we hack it for now or do we implement it right? The answer as always - it depends. Hacking it gets us closer to our goals right now but we have to pay off the debt eventually. Novice players (like me!) start out connecting various parts of our base by conveyor belts till our base resembles spaghetti, similar to poorly maintained codebases. Eventually we learn techniques to tame this complexity so our base/codebase becomes easier to reason about.
- Don't Repeat Yourself (DRY). One of those techniques is reducing duplication. If you have a component that's needed in multiple places, do you make it once and use it everywhere or do you copy paste in each place it's needed? The answer is "it depends". As an engineer, sometimes you use a library while other times you copy paste. It depends on the complexity of the component - a couple of functions can be copy pasted while something complex probably shouldn't. So it is in Factorio, a certain component (electronic circuits) was being produced in 4-5 places. I eventually replaced them all with one centralised production array to simplify the factory.
- Scaling. A repeated theme in this game is building a production array and later finding we need 3-5x the throughput. The first few times this happens, it requires redoing from scratch. After we wise up, we start design our arrays with space for scaling up. So it is with software - our systems need to scale to many more users, sometimes without much warning. We design our systems keeping that in mind.
- Rebuilding. When we're rebuilding a component in a single player game or a personal software project we don't usually care if the component or the whole system stops working briefly. I was playing multiplayer with friends though, so I tried to make sure components I was working on didn't break anything else. I created a new oil refinery system, shifted existing customers to the new one before decommissioning the old one. Zero downtime.
- Debugging to find root causes. Our factory is far from perfect, so something is always breaking as we add stuff to it. Finding the root causes of these issues is tricky, especially when fixing those leads to other problems, like playing whack-a-mole. An example from yesterday - We don't have enough electricity, so we add more boilers, but now the water pipes need fixing. Then the water is fine, but we don't have enough coal. That mirrors real life
- Teamwork. Most things are possible solo given enough time. But it's quicker and more fun working with a team you like. We were able to move fast by splitting responsibilities among the team. We have one oil guy (me), one trains guy, one secretary of defense, among other roles. The others don't care about the internals of the refinery system, just the interface - they use the outputs and let me know if it's broken. It's the same on large software projects - everyone can't learn the intricacies of the whole system. Instead everyone learns the APIs of all components while a few are responsible for the implementation.
- Researching. We spend most of our time exploiting our existing knowledge to keep us in our local maxima of output. However, a smart player dedicates some time to learning new techniques. In our game, coal power wasn't working out for us and I had dismissed nuclear power as an option because we didn't have enough uranium ore. I looked into it again when we were desperately short of power and producing too much pollution. Turns out even a little ore is enough to power the base for a 100 hours if we do it right. It's the same with software - our existing stack probably works well, but it's smart to see what's out there and possibly learn from others. New team mates can help here too - everything is new to them so they're spending more time than you on learning. They can come across stuff that we didn't know about and use that knowledge to find a higher maxima. A fresh pair of eyes is always good.
- Automation. You can do most things manually, it just takes time. But if you're doing something repeatedly, it should be automated. The game gently eases you towards this idea by requiring a few items be automated. It gets better later in the game you unlock construction robots. You can tell them the layout of the production array you've designed, give them the materials and they will construct it for you. This reminded me of AWS CloudFormation and similar tools - although it's possible to set up servers by hand, it's quicker and less error prone to specify the end state and let a tool do it for us. But if you've developed software, you know that automation isn't just a means to an end - it's an end in and of itself. We do it because it makes us happy, even if we do too much of it and forget what we were doing in the first place.
- Putting out fires. Sometimes it's hard to implement new features because we're being pulled away to deal with alerts - all too common on software engineering teams. The typical solution is to have one team member deal with alerts while the rest focus on adding features. We rotate the responsibility regularly. That's what we did in our game too.
But more than any one thing, the game is about managing complexity. Designing a specification and implementing systems that fulfill that specification. Maintaining and growing that system over time.
IMO, playing Factorio will not make you a better software engineer. But if you're a software engineer, you'll likely find the game fun. And conversely, if you're good at the game you should give software engineering a shot.
You can get Factorio at on the official website or Steam. There's also a free demo, in case you'd like to try before you buy. (Just one thing - don't wait for a sale. This game has never gone on sale and possibly never will.)
Thanks to Minesh Patel for reading drafts of this and suggesting improvements.