Well, it finally happened. After carving out a niche in the market by making puzzle games that were secretly about programming, it was inevitable that Zachtronics would eventually cross a line and make a puzzle game that was actually about programming.
What’s surprising about this, though, is what a mistake it’s turned out to be. Previous Zachtronics games such as SpaceChem or Infinifactory might have been heavily based around programming concepts, with easy in-game analogues you could point to for things like functions and arithmetic operations, but by packaging them up as an assembly line that built molecules/fully kitted-out living rooms instead of writing lines of code they were successfully insulated from real-world programming in a way that allowed the puzzles to co-exist quite peacefully with the much broader programming elements. Shenzhen I/O is different. Shenzhen takes the SpaceChem system of connecting together individual components that each do a segment of processing to gradually build a desired output, but instead of a pair of waldos manipulating atoms and molecules Shenzhen has you writing actual, literal computer code. And not just any code, either; Shenzhen’s pseudo-language is styled after assembly programming, which is a notoriously finicky language where nothing is handed to you on a plate and you have to do absolutely everything. Almost nobody programs in assembler any more since this is the 21st century and we have a whole host of nicely interpreted languages that trade off some efficiency1 for minor quality-of-life features such as “being able to run on more than one architecture” and “not driving the people who have to write in it completely batshit loco”.
So not only are you writing your pseudocode in a fake language that requires you to be absolutely explicit about every instruction, but Shenzhen then saddles you with further restrictions via the components you use. There are several different types, but what dismayed me a little bit is how little opportunity Shenzhen provided to use interesting bits and pieces like the RAM/ROM modules, instead preferring to have 95% of its puzzles require only the two core microprocessor components – these are the standard blocks with a series of inputs and outputs and a space in the middle into which you can insert lines of code. There’s a small processor that takes up to 9 lines of code and can store one variable, and a large processor that can accommodate a whopping 14 lines of code and two whole variables (although you can only do arithmetic operations on one of them). And while the assembler pseudo-language has a fair degree of functionality (loops, conditionals, execute once markers) this is still not a lot of space to work with, to put it mildly.
What Shenzhen is trying to do here is create puzzles out of the conflict between writing code in pseudo-assembler, where you have to be very explicit and long-winded about operations that could easily be done in a single line in a better language, and the limited space available in each processor component, which require that you fight for every single spare line of code and refactor repeatedly until your program is as pithy as it possibly can be. To begin with it works quite well — as long as you don’t mind writing programs in assembler, that is. Each of Shenzhen’s puzzles gives you one or more input source that spits out integers between -999 and 999, either as a constant steady signal that can be read at any time or as a more discrete series of packet values that must be individually (and explicitly) shunted between components. Said integers are supposed to represent the input state of some real-world device that you’re supposed to be designing — a card key operated door lock, or a smart rangefinder for a firearm — and you’re supposed to take that input and generate a set of integer outputs that matches the desired behaviour of the device, such as unlocking a door (or not).
The inputs and corresponding target outputs are helpfully displayed along the bottom of the design interface, and each device has set of test cases that are supposed to cover off most of the use cases that device would typically encounter; you can’t complete the puzzle until you come up with a program that can successfully pass all test cases. At the start of the game, when the devices you’re building are still relatively simple, it’s a decent enough system; you’re given sufficient space to experiment and refine your code, building a program that would qualify as “good” by basic programming standards and which covers off all required use cases and — this is important — all additional edge cases that you can think of. Shenzhen does the usual Zachtronics thing of showing you a histogram of how other people’s solutions performed after you complete each puzzle, but I know that to score highly on those usually requires you to break with the programming paradigm and build a solution optimised to work only according to the game-y rules of the puzzle rather than in a broader programming context. I was happy to trade lines of code or run cycles for having a robust piece of code that I knew would work without even having to look past the first screen’s worth of test cases — because that’s how programming is supposed to work. You have test cases to make sure somebody unfamiliar with the code doesn’t break it, but they’re not there to define the overall viability of the product the way Shenzhen’s are.
Unfortunately as I got further and further through Shenzhen’s list of 30-odd puzzles I became increasingly dismayed. For one thing, Shenzhen is singularly uninterested in teaching you how to play it. Zach seems to be rather taken with the concept of not having an in-game tutorial or puzzles that largely serve to introduce the player to new game mechanics, but instead putting all of the information required to play the game (including specifications for some of the more complicated puzzles) into a PDF manual that you’re expected to refer to as you play it. I cannot overstate how utterly infuriating this is – Shenzhen is not a simple game, and as with real-life programming you will constantly find yourself looking up how specific instructions work. Unlike real-life programming, however you can’t just go and find the answer on Stack Overflow; instead you’ve got to alt-tab out of the game, scroll through this PDF looking for the relevant page (which is always just a bland statement of what a command does, with precious few working examples), bring the game back up, write the command into your code, find it doesn’t work, alt-tab again to reread the documentation to see what you got wrong, maximise the game again… Zachtronics released a similar assembly programming game called TIS-100 a year or two back that had the same conceit of a PDF manual, except there you were supposed to be dealing with a salvaged computer from the 1980s so it made a certain amount of narrative sense. Shenzhen on the other hand is supposed to be set in the 2030s so it’s absolutely nonsensical to be referring to what’s supposedly a paper manual the whole time; it’s a huge step back from Infinifactory’s elegant pictograms that depicted the use of new puzzle components, and probably the number one obstacle in the way of enjoying a game that’s already got a stupidly high barrier to entry2.
Once I’d smashed my way through the manual and learned this stupid pseudo-assembly language, though, a more philosophical problem reared its head: the early puzzles give you enough breathing room to write good code, but the later puzzles enforce so many restrictions that you’re practically forced to write bad code that’s enough to pass the specific test cases you’re presented with and no more. SpaceChem and Infinifactory had similarly restrictive scenarios, but by setting themselves one step away from programming they insulated themselves from the inherent requirement a good program has to be written in such a way that it covers off all the foreseeable edge cases, and so building a kludge solution in Infinifactory was far less painful than it is in Shenzhen, where some of the endgame puzzles demand that you perpetrate some outrageous hacks that wouldn’t last thirty seconds in the real world. I’ve always lauded Zachtronics games for their stealth educational potential, but Shenzhen gets it horribly wrong; where SpaceChem and Infinifactory taught you about the broad concepts behind programming, Shenzhen is teaching you to actually program – badly.
Of course, I could be getting things horribly wrong – maybe it’s not that the game forces me to write bad code, but that I’m simply not very good at code in the first place. I’d have two counterarguments to this, though. First, my day job involves a lot of coding (albeit not in assembler, which is maybe where I’ve been going wrong all these years) and as I haven’t been fired yet I can only assume that I’m not completely terrible at it. Second, if that is the case then it’s effectively restricting Shenzhen’s playerbase to people who have completed a Computer Science degree and makes the game bad by default, as you simply can’t assume that level of pre-existing knowledge on the part of the player.
Still, if I have so many problems with the game, then why does my Steam account show 26 hours played for Shenzhen I/O? The answer is very simple: most of that wasn’t spent in the assembly programming portion of the game, but instead in the fiendishly addictive Solitaire minigame attached to it – it’s so addictive, in fact, that when I booted the game up to get some screenshots just now I ended up playing another 15 rounds. I’d almost say it’s worth buying Shenzhen just for the solitaire – fortunately for you, you don’t have to as it’s since been packaged as a standalone game. That’s unfortunate for Shenzhen, however, as without the solitaire I can’t really recommend it to anyone who hasn’t already bought it; while many of the puzzle concepts display the trademark Zachtronics creativity it has none of the relative accessibility of previous Zachtronics titles (which is weird since it strikes me as an attempt to polish up TIS-100 and release it to a wider audience that doesn’t do anything to actually widen the audience) and none of the edutainment potential, reducing it to a bog-standard puzzle game with a ridiculous barrier to entry. Definitely the worst Zachtronics game I’ve played so far.
- The advantage of assembler is that you are interacting directly with the base architecture of whatever system you’re writing it on with zero cruft getting in the way of your instructions, allowing you to potentially write very fast code. ↩
- To wit, that you are the sort of person who will enjoy a game about assembly programming. ↩