A few hours in
An interesting thing happened while playing EXAPUNKS: I beat it. Cleared all the puzzles up to and including the last one, saw the story move to its (wild) conclusion, watched the credits, the whole nine yards. This is ‘interesting’ in the sense that this doesn’t generally happen for me with Zachtronics games: I either run into a puzzle wall my brain can’t clear, or (more commonly) get so stuck on optimizing the early puzzles to beat all my friends that I burn through my enthusiasm before getting to the end. Neither of those things happened with EXAPUNKS. But is this a good thing or a bad thing? Perhaps unsurprisingly, the answer is ‘no’.
I said I didn’t want this review to just be more references to old Zachtronics games, and it won’t be. But if you are familiar with the corpus, I’ll quickly say this: EXAPUNKS feels more than anything else like a follow-up to Shenzen I/O [which I reviewed here], Zachtronics’ game about Assembly coding and circuit board placement. Both games focus on a combination of pseudo-code programming and physical object placement/location, and both games use that setup to play in real-world space: Shenzen I/O had its big red binder manual, EXAPUNKS
has its ‘zines.
I’m hesitant to call EXAPUNKS a ‘sequel’ or ‘follow-up’ to Shenzen I/O, or anything like that, because that’s not really how Zachtronics games work. Their games never build on each other directly, just conceptually and (to some degree) mechanically. Shenzen I/O is still a unique and interestingly distinct game from EXAPUNKS — researching it and re-reading my own work for this article has made me want to reinstall it and give it another crack. Rather, I’ll say that EXAPUNKS gets most of its Zachtronics DNA from Shenzen I/O — but then takes it into new and interesting places, where a static circuit board design theme couldn’t go. EXAPUNKS‘s unique game identity is themed on three concepts: Spatiality, uncertainty, and finiteness.
The element of spatiality is core to EXAPUNKS‘s unique spin on hacking, taking it beyond ‘just’ executing code on a computer. EXAPUNKS visualizes connected computers in a network as a flat physical space, almost akin to a tabletop RPG dungeon: Rectangular ‘rooms’ made of squares (representing different ‘host’ computers) connected by ‘doorway’ links (representing the connections between those hosts). Files and hardware registers take up squares of space on the computers they’re on, and hosts and links are traversed by EXAs, the aforeshown code-executing robot friends.
The spatial nature of hacking is the closest analog EXAPUNKS has to Shenzen I/O‘s gameplay (I swear I’ll stop making this comparison). Your code does not exist in the abstract, but has a particular location in your solution. And that location determines how it can interact with other blocks of code, or with static objects/values. Variable values live inside certain registers, and manipulating those involves arduously keeping track of where everything is related to everything else at any time. If you’re getting XBus flashbacks at this point, good. So am I.
But in EXAPUNKS, code locations themselves are variable. Your EXAs carry their code with them, and they’ll move through the network as a function of executing that code. This means that while writing code, you’ll have to be able to visualize where a given EXA is going to be when any given line is executed — or just make good use of test runs and debugging.
Network layouts aren’t just a fun visualization, they have actual puzzle implications. Any host can only so many EXAs and files as it has empty squares: Each square can hold one EXA, one file, or one EXA holding a file. And any link between hosts can only be used by any one EXA at any time. Try to overload things, and your EXAs will randomly determine amongst themselves who gets to go first. And then the other ones will just… wait.
EXAs can also communicate, in a limited sense, and that communication can be influenced by respective location as well. One EXA can copy a value into their M register, which basically turns them into a broadcaster: It’ll be stuck holding that value until another EXA tries to read from their M register, at which point a transfer takes place and both EXAs can go on with their lives. But while EXAs in ‘Global’ mode can communicate with any other EXA that it can track a network link to, EXAs in ‘Local’ mode can only communicate with other EXAs in the same host. That are also in ‘Local’ mode, because the two modes are incompatible. And if that sounds needlessly complicated to you, consider this: If two EXAs are trying to transmit different M values to the same recipient, the order in which those values are received is (again) determined randomly. Or maybe one EXA is waiting to receive a particular confirmation value, but then two hosts over, two other EXAs are trying to quickly exchange register information. How can you be sure that the right EXA reads the right value? Maybe if we put this one in Local mode, and that one…
To complicate things even further, EXAs can at any time choose to replicate themselves — provided there’s enough space in the host to hold another EXA. The REPL command creates an EXA that’s functionally identical to the original one, down to the value in its X register, except its operant pointer is pointed at a label of your choosing. And then it just goes off and does its own thing. Maybe ‘its own thing’ is replicating itself, again. You’re allowed to start any puzzle with a bunch of EXAs, if you want, but it’s often more convenient and easier on the timing to have solitary EXAs replicate themselves in locations that they need to be. Just as long as, again, you’re able to mentally keep track of how many EXAs are supposed to go where. And what exactly it is they’re doing. And which ones are transmitting to which ones.
If this was everything there was to EXAPUNKS, we’d already have a tidy set of possible challenges. But the second element of the three, and the one that I think the most gives EXAPUNKS its unique flavor, is the element of uncertainty.
It’s always been a hallmark of Zachtronics games that you don’t just run your solution once, you run it several times in a row, to see if you actually solved ‘the puzzle’ instead of hyper-optimizing for the first set of starting circumstances. In Spacechem and Opus Magnum, this was mostly done to make sure you could deal with spatial repetition. In Shenzen I/O (and I assume in TIS-100 as well), the different puzzle loops would include different variables and input/output conditions, to make sure you didn’t just hard-code in the correct solution. In all cases, you’d generally look at somewhere between five and ten puzzle loops.
EXAPUNKS runs through its puzzles no less than one hundred times.
One hundred repetitions doesn’t mean Zachtronics got incredibly paranoid in-between games. It’s partially there to prevent hard-coding, but also helps EXAPUNKS fully explore its own puzzle space. Maybe a puzzle wants you to find and replace certain keywords in a long list of strings: With one hundred repetitions, you can be sure that players can’t cheat their way around things. Maybe a puzzle wants you to discover a three-digit password. Maybe a puzzle wants you to access up to seven individual links, except some of those links may or may not exist. In all cases, kicking the repetition up as far as this ensures that all interesting exceptions and edge cases are taken care of — and that even the most hardy players can forget about working around things.
Consequently, we get uncertainty. In the find-and-replace puzzle, you don’t know where the keyword are — but maybe you don’t even know on beforehand how many times it’s going to appear, or how long the message is. In the password keyword, there’s no way of coding recognition of the right key. In the seven-links puzzle, you can never be sure which links do or do not exist, or how many of them exist in the first place. And this is relevant because of one small but actually secretly huge thing: Remember how I said that if an EXA tries to execute a valid command that the host has no space for, it’ll wait for its turn? Well, if an EXA tries to execute an invalid command — traverse a link that doesn’t exist, grab a file that isn’t there, read a file past the end of its length, divide by zero, or even just reaching the end of its command file — it reacts in a much less wholesome and much more explosive manner.
Say you’re doing the last example puzzle: You’re hacking a bank, and you need to access and mess with up to seven ATMs. Except that in any given puzzle iteration, you have no idea which ATMs will or will not be active. Like this:
A simple brute-force solution won’t work. If you code an EXA to go into each of the seven ATMs and do its thing, it’ll crash and end the moment it tries an invalid link. So what else can you do? You could make seven separate EXAs and hard-code each of them to go into a single path. That would work, though it’d probably result in a high Activity score. And replicating all that code seven times won’t do your Size score any good either, and it might mean you run out of lines. Or maybe, since all the ATMs are the same on the inside, you’ll want to make one ‘main’ EXA, and replicate into different sub-programs right on the outside host. Or maybe you could…
At any rate, you get the idea. Later puzzles get real inventive with this uncertainty aspect, which forces you to think about attacking the puzzle, the underlying challenge, not just the one example illustrated in front of you. You’re also free to move between any of the one hundred test runs, if some in particular are giving you trouble — that’s only slightly more likely than you think.
Finally, there’s the element of finiteness, which I nearly called finity. This one is simple: In all but a small number of select puzzles, one of your objectives is always to leave no trace. That means you can’t make any changes to the network that aren’t within mission parameters, you can’t leave any files you created anywhere outside your own host, and all of your EXAs need to stop running and terminate.
The first barrier is easy: I can count the number of times I had issue with unauthorized changes on one hand. It’s super funny to activate all the copy shop printers, honestly, especially since EXAPUNKS often includes picture-in-picture views to visualize the real-world space you’re playing it. But just don’t do it, okay.
The other two barriers are harder. Cleaning up your file mess can be as easy as including a WIPE command at the right time, though I’ve lost count of the number of ‘correct’ solutions I had to tweak for this. It’s the ‘no EXA left alive’ requirement that really shapes how you make solutions. It’s not always an issue, since EXAs by design self-terminate when they reach the end of their code. But so many missions are made easier by having one or more EXAs do something infinitely. Spawning replicated EXAs, writing files from an M register, looping through high values, that sort of stuff. But any viable solution will inevitably have to deal with this. Maybe by including a self-timing element, or an evaluation of incoming values to act as a kill-switch? Maybe by having other EXAs swoop in to KILL-command the offending infinite ones as part of their own life-cycle? I have on at least three occasions created EXAs specifically to function as time-delayed kill switches: They’d initialize by writing a value to X, looping through that value while counting down, and when they hit the end, they’d kill the other EXA in the host and then immediately halt. Which I assume is not a great motivator for the aforementioned other EXA, but hey.
In a very mechanical nutshell, this is EXAPUNKS: A series of slowly but also rapidly escalating puzzles themed around writing good code, interpreting different network layouts, and dealing with uncertainty. And comparing yourself to your friends, of course: As with every Zachtronics game, EXAPUNKS has Steam friend leaderboards to tear down and/or glorify your best solutions. In the specific case of EXAPUNKS, solutions are graded on: The size of your code in active lines, the number of cycles they take to complete, and the amount of ‘activity’ they induce, measured as the sum of each EXA that executes at least one line of code in each host — with the values for the latter two being determined by the worst of your 100 test runs, each separately. I actually like that in EXAPUNKS, these metrics feel meaningfully three-way different. In other games, I often felt that the metrics were two-against-one: For instance, making cheap solutions and making small solutions in Opus Magnum often amounted to the same thing, and cheaper Shenzen I/O solutions often had less code just as a function of the number of allowed lines. But EXAPUNKS has a broad possibility space: Fast solutions often use more space, since repeating instructions is more cycle-efficient than making loops, and incur more activity, since running all across the network is faster than setting up remote connections. Developing low-activity solutions is also generally space-inefficient, since making sure the right EXAs talk to each other tends to require a lot of hand-shaking. Which means that if you’re interested in a small-code solutions… you get the idea. EXAPUNKS kindly summarizes all your different solutions on the friend-facing leaderboard, just showing your best scores for each — which does mean that novices might get intimated by the idea that you’ve made one solution that’s better than theirs in literally every aspect.
Initially, my gut feeling was that inter-player comparison was less of a driving force in EXAPUNKS than it was in other Zachtronics games. Opus Magnum still feels like the gold standard here: Puzzles were small and direct enough that any improvement in your metrics, even a single cycle or dollar, felt cool and meaningful. And obviously the GIF maker was a golden move — I understand why EXAPUNKS doesn’t have an equivalent, but I still miss it. This gut feeling was probably inspired somewhat by the fact that nobody on my Steam list was playing EXAPUNKS when I got into it, so there literally was no-one to compare myself to. Hell, that probably contributed to me actually finishing this game: I occasionally felt the need to upstage myself, but otherwise was free to move forward. And upward. But in an ever-forward motion, of course.
Then Ninja Blues co-writer Ranneko also got EXAPUNKS, and the results were as expected.
The overriding need to tweak my old solution in that screenshot is so powerful that I have to consciously decide to not launch EXAPUNKS every other word I type. So if you are the competitive type, don’t worry: EXAPUNKS has you covered as well as any other Zachtronics game.
Have I mentioned how much I love the writing in this game in general, and the ‘zines in particular? I thought Shenzen I/O‘s manual was an interesting thing, but the ‘zines take that idea to a whole different level. It’s not just that they’re smaller, and time-differentiated, making them an accessible way to provide players with new inputs over time. I also love that they explain potential puzzle environments in general terms. Like, you can read an article about ‘geographic information systems’, which explains in general terms how those kinds of systems work — and then two later puzzles play into that type of network. But in meaningfully different ways. Hell, that division won’t even work the way you’re expecting it to! And finally, ‘zines are just so… fitting, for the whole aesthetic. They’ve got articles and ads and reader letters. There’s even one part where the game and the ‘zine intersect in a way that… but I’ve already said too much. It’s cool, they’re cool, if you play this game you should totally print them.
Which segues into the meat and potatoes question: Should you play EXAPUNKS? Obviously I enjoyed it, and if you liked what you read here, the twenty dollar price tag feels more than fair to me.
Maybe the more challenging question is, should you play EXAPUNKS instead of any other Zachtronics game? I honestly don’t think I have a good answer to that question. Obviously EXAPUNKS is new, so it’s more likely to have an active interested player base; if you’re interested in being cutting-edge, or getting into the asynchronous multiplayer ‘hacker battles’ — I didn’t even mention those very much, but yeah, this Zachtronics game totally has competitive multiplayer — get in on this one early. Otherwise… it’s really a matter of taste, honestly. Do you think ‘programming little spider robots to trawl 1990’s computer networks’ sounds more or less fun than ‘circuit board design in contemporary China’ or ‘programming claw arms to do alchemical operations and make cool GIFs in the process’? They’re all good games, and they’ll all fry your brain by degrees… Get the one that you think looks most fun, that’s the best advice I can give you.
Jarenth really wanted to rant about his last-puzzle solutions, but that would be spoiling things to an advanced degree. Notify him on a href=”https://twitter.com/StevenBeargal”>Twitter or hang out with him on Steam. And if you dig Indie Wonderland and Ninja Blues in general, why not consider supporting our Patreon campaign?