The first thing you hear when you start TIS-100 is the cold boot of an old CRT. Whether or not this induces a pang of nostalgia is a good litmus test for how you’ll feel about the assembly-language compiler disguised as a game. Make no mistake: TIS-100 is for the keenest of programmers only. If you’re not already familiar with conditional statements and iteration and the like, you’ll have a precipitous learning curve in front of you. Even if(have_exp == true), TIS-100 is hardly a cakewalk.
Assembly language, for those unfamiliar, is a form of programming language that was common in the ’50s and ’60s, before being supplanted by higher-level languages like C in the ’70s and beyond. Assembly-language instructions are typically based on the machine code a computer uses to talk to itself, and as such they’re significantly harder to read and write compared to the likes of Java and C#. Still, despite its archaic sensibilities, TIS-100 grapples with a number of concepts that remain relevant to this day.
What is it?
Communication is an essential component of modern programming. From online leaderboards to multiplayer FPSs to MMOs, games rely more and more these days on talking to each other to facilitate their fun. The problem is, it’s practically impossible for one program to know what another is doing at any given moment, so managing communication becomes tricky. Think of it like two people having a conversation while at the same time fiddling with their phones. If one person’s attention is focused on their phone, they might not hear what the other person is saying. To remedy this, programs communicate using ports and sockets, which are basically Post Office boxes managed by the operating system. A program can send off its data then go about its business, while the onus for checking for new messages falls on the recipient.
How is it taught?
Programs in TIS-100 are split up into nodes, each of which can only execute a limited number of instructions. To achieve the goals laid out for you requires a whole lot of data sharing between nodes. Worse, each node can only talk to those adjacent to it, complicating matters even further. Creating a working solution demands you think of each node as a separate program, privy only to its own operations. Getting them all to cooperate means establishing a communications protocol, just as a network programmer must do. You discover very quickly that convincing different programs to play nice together is harder than it might seem.
Concept: The Stack
What is it?
Like arrays, the stack is a container for grouping together related data. The stack, though, is better suited to shared-data environments where different programs, or different parts of a program, need to access the same data without directly communicating with each other. As the name implies, the stack stores data in a vertical list, adhering to the Last In, First Out (LIFO) protocol: when a new item is added, it goes to the top of the list, and when an item is removed, it’s taken from the top of the list. Think of it like a stack of plates at a buffet restaurant, where patrons take from the top, while clean dishes are also placed on top. Or an internet browser’s Back button and its record of your recent page history.
How is it taught?
As the programs you’re writing increase in complexity, moving data between nodes that can only store two things at a time becomes a game of Chinese whispers, with the likelihood of error only getting higher. The introduction of stack nodes with their limitless data buckets gives you the means to handle much larger sets of data, though the extra capacity doesn’t come free. You have to consider issues like deadlock, where one node is waiting for an empty stack to be refilled, but the node that would refill it is in turn waiting on something from the original node – stalemate! Then there’s the problem of storing multiple datasets on a single stack without getting them all mixed up. Weighing up the trade-offs of using stack nodes versus managing data manually is the sort of consideration programmers make on a regular basis.
Though TIS-100 looks like a relic of the past, it’s in no way outdated. From overlaying menus to multi-core programming, concepts like stack memory and network ports are as relevant today as ever. For the programmer-in-training, TIS-100 is the final hurdle; if you can survive its stiff challenge, you’re ready to code.
So, can you learn to program by playing games? I’d say yes, with a couple of caveats. First, the challenges of programming are rarely as clearly defined as the puzzles in the aforementioned games; project requirements often change multiple times during development, and sometimes you won’t even know whether what you’re trying to do is possible until you do it – or give up. So maybe don’t put Human Resource Machine on your CV. Second, games alone won’t turn you into John Carmack; they can teach you the basics and help hone a programming mindset, but you’ll still need to hit the virtual books before you’re ready to make the next DOOM.
Nevertheless, if you go in with appropriate expectations and a healthy supply of determination, games like those I’ve looked at here can be a solid stepping stone to a future in programming. Just don’t forget the most important rule of working in the tech industry: never tell anybody what you do for a living, or you’ll be on the hook for fixing family members’ bloatware-laden computers for the rest of your life.