Spacewar 1 and the Beginnings of Video Game Aesthetics
Tales of the early days of the first digital video game.
Sometimes it’s only a short sentence, a few words dropped as an aside, which changes our understanding. A short glimpse, which provides deeper inside and understanding in what is a complex process. As it is here the case regarding how Spacewar!, the first digital video game became this remarkable program that gave birth to an entire industry. As usually, what was intended to be just a brief dump of an idea — at least, this is what a blog post is all about, isn’t it? — became lengthier than expected. Not for the least, as it’s still necessary to establish the subject, even as Spacewar! is rapidly progressing towards its 60th anniversary. So bear with me…
Last week, I finally got hold of something, I’ve been looking for for a few years. Namely, it’s an audio recording of the Smithsonian presentation on the occasion of the Spacewar! team recieving the AIAS Pioneer Award on November 29, 2018. All those involved in the making of the game (that is, with the exception of Alan Kotok, who passed away in 2006), were reunited on the podium to give their account.
As there were:
- Dan Edwards
- Martin Graetz
- Steven Piner
- Steve Russell
- Peter Samson
- Robert Saunders
- Wayne Wiitanen
- Moderator: Christopher Weaver (founder of Bethesda Softworks)
- also in attendance: Professor Jack Dennis (in supervision of TX-0 and PDP-1 related activities at MIT)
Now, the story of Spacewar!, the first known digital video game, has been told again and again, and if you’re familar with the subject, you’re at least no foreigner to what I call the “sine-cosine incident”.
— What’s this “sine-cosine incident”?
Glad you asked! Here it is, as told in The Origin of Spacewar by J.M. (Martin) Graetz (in Creative Computing, volume 7, number 8, August 1981. pp 56-67):
Russell, never one to “do something” when there was an alternative, begged off for one reason or another. One of the excuses for not doing it, Slug remembers, was “Oh, we don’t have a sine-cosine routine and gee, I don't know how to write a sine-cosine routine…” Then Alan Kotok came back from a trip all the way to Maynard (DEC headquarters) with paper tapes saying “All right, Russell, here’s a sine-cosine routine; now what’s your excuse?” “Well,” says Slug, “I looked around and I didn’t find an excuse, so I had to settle down and do some figuring.”
And here it is in the more detailed version of the Smithsonian event, Nov. 29, 2018:
- Did the program happen instantly?
- Why not?
- I was lazy! [inaudible; laughter]
- What is your nickname?
- Slug. [laughter]
- I was just checking…
And, we now were talking just a minute ago about Alan Kotok. Now, did that have anything to do with assisting you out of your laziness?
Aw, I would not call it exactly ‘assisting’… I think, it was more embarrassing.
I had various excuses: I talked of this idea that somebody better write a demonstration program, and, it will be neat, if somebody wrote a spaceship trainer, because people didn’t understand how spaceships coast and that sort of stuff, and so it would be ultimately possible on a PDP-1 with a display to actually give people a spaceship, they could control and learn something about it. And the reaction, I got, was, sort of, “You know, that’s really a good idea. Somebody ought to that.” [laughter] “Somebody who really understands the idea of how to do that, [inaudible; laughter] will do that.” [laughter]
Well … I had various stories, like I hadn’t taken numerical analysis course and I didn’t really understand how to write the sine-cosine routines that were obviously needed, so I just didn’t have the right tools. And so Alan Kotok snuck out to all the way out to Maynard, Massachusetts, where Digital lived, and got copies of a sine-cosine routine for the PDP-1. And he came back, and, probably in the morrow of…, somewhere where there were lots of people around, several, … presented them to me and said, “Here are your sine and cosine routines; now what’s your excuse?” [laughter]
So, I was embarressed and I went off and started thinking about how to really do it, and in several weeks I figured it out and got something working and, by December of 1961, I had a program that worked and displayed two spaceships on the screen and allowed two people to control.
And, this was fine. A number of people thought that it could be made better and so I gave out copies of the sources and fortunately it turned out that only one person worked on it at a time, which saved the project.
- So you had built-in version control…
And so I had that demo running, and Dan Edwards looked at my display program and figured out a way to speed it up. He apparently is the first perpetrator of a just-in-time compiler, becaus he wrote a compiler that compiled exactly the right code to display the spacship outlines and keep the display hardware running at full speed. Which was a real challenge, which I hadn’t mastered. So that gave us enough time to calculate the effect of gravity on the two spaceships, which made it a much, much better game. And there was enough time to calculate the gravity between the Sun and the two spaceships, but there still wasn’t enough time to calculate the effect of gravity on space torpedoes that were flying around on the screen. And so we decided that they were photon torpedoes, [which; inaudible] weren’t affected by gravity.[laughter]
While this is an excellent, lighthearted and compact recount of how the first digital video game came to be around, we’ll have to add a minor correction regarding the timeline of events, for the sake of history: While Steve Russell suggests here, as in his oral history, that his first playable demo was ready by the end of 1961, we know from the court proceedings of the so-called “Magnavox vs. Bally” case, October 28, 1975, that the Type 30 CRT display wasn’t available before the very end of this year, as it was installed on Friday, December 29, 1961 (page 87):
- When was the Type 30 display delivered?
- The display was installed December 29, 1961.
And on page 88, quoting the PDP-1’s log:
- “1300 DEC installed display. Okay to use. Repeated display of a single point will bum CRT.” I had that underlined. "Light pen okay. Working on sequence break.” And initialed “JAM.” [JAM: John Alexander McKenzie; N.L.]
Accordingly, work on a demo program with an actual display of the spaceships couldn’t have begun before January of 1962, which gives us about a month or so into 1962 for a working program. Which matches neatly the progression of events as described by Martin Graetz in “The Origin of Spacewar” (op. cit.):
By February, the first game was operating. It was a barebones model: just the two ships, a supply of fuel, and a store of “torpedoes”
So make this “by February 1962”…
Ornaments & Space Aesthetics
As to be expected for a story told so often, there are few surprises. However, there is one notable eception. At about 40 minutes into this 74 minutes long recording, Dan Edwards explains how he got to think about the all-decisive introduction of gravity:
- As I looked at the game, essentially it had this star in the middle, while it had no effect on the gameplay itself. I thought it would be better to use that to provide the gravity and put something out of the immediate, direct control of the game player (…)
Now this is really unexpected. Previously, we were meant to think that the central star (or “heavy star”) had been added along with gravity and the outline compiler by Dan Edwards. At least, an article in the MIT Technology Review from June 2005 by Corie Lock says so clearly:
Dan Edwards programmed a sun in the middle of the screen that exerted gravitational pull on the ships. (Lock, Corie, “The Start of Computer Games”, MIT Technology Review, 1 June 2005)
This seems to be in turn based on a passage in Steven Levy's “Hackers – Heros of the Computer Revolution” (1984/2010, p.53):
Another programmer named Dan Edwards was dissatisfied with the unanchored movement of the two dueling ships. It made the game merely a test of motor skills. He figured that adding a gravity factor would give the game a strategic component. So he programmed a central star a sun in the middle of the screen; you could use the sun's gravitational pull to give you speed as you circled it, but if you weren't careful and got too close, you'd be drawn into the sun. Which was certain death.
“The Origin of Spacewar” (op. cit.) isn’t that clear about this, but doesn’t suggest any to the contrary, either:
Russell: “Dan Edwards was offended by the plain spaceships, and felt that gravity should be introduced. I pleaded innocence of numerical analysis and other things" — in other words, here's the whitewash brush and there's a section of fence— "so Dan put in the gravity calculations.”
The star blazed forth from the center of the screen, its flashing rays a clear warning that it was not to be trifled with. Its gravity well encompassed all space; no matter where you were, if you did not move you would be drawn into the sun and destroyed. (As a gesture of good will towards less skillful or beginning players, a switch option turned annihilation into a sort of hyperstatial translation to the “anti-point,” i.e., the four corners of the screen.)
However, Dan Edwards is quite clear about this: “As I looked at the game, essentially it had this star in the middle, while it had no effect on the gameplay itself.” — There had been a central star before gravity had been even a thought!
According to Peter Samson, the central star had been created by Don Eastlake, at least, he has been told so. Steve Russell, on the other hand, recalls that he and “and many other people tinkered with the star and the explosions to make them better”, and would “hesitate to ascribe authorship to an one person, but happy to accept all as contributors.” (Peter Samson and Steve Russell on the PDP-1 Team mailing list in reaction to this article, which has been updated accordingly.)
So, while the authorship of the central star remains a bit of a mystery, it is much more interesting for why it had been there in the first place. As a do-nothing graphical effect, it had been put there for aesthetic reasons only, as a pure ornament!
As I put it a few years earlier, the central star is a crucial element of the aesthetics of Spacewar!, its pièce de résistance:
While just a single short spinning line, the gravitational star (or the heavy star, or just the Star, sometimes also called the Sun), was maybe the most important visual element of Spacewar!. In order to understand this, we have to recall the actual setup, in which the game would have been experienced: While the PDP-1’s scope, the DEC Type 30 CRT display (…) would paint any content on a perfectly square display area, it exposed a circular tube, which was contained in a distinctive hexagonal housing. A concentric layout that would be further emphasized by the circumference of the bright metal border of the central extrusion of its bezel. Further, the Type 30 CRT featured a P7 compound phosphor that sported dual characteristics, a bright blue activation and a long sustain in a dimm yellowish green, which would provide for the iconic trails that were drawn by any moving objects. (…)
This essentially concentric setup was echoed by the game itself: Emphasized by the fading trails, the ships would be drawn by gravity to the very center, just to explode in a pictoresque cloud of pixel-dust, or would swirl around the center thanks to the wonders of Netwon’s law. And in the very midst of it, there would be the Star, not just a bare line, but a mysterious bunch of fading, pulsating, spinning flashes, quite like a magic eye, the very embodiment of the natural magic of gravity, Spacewar!’s governing feature of game play, — by this providing both a visual focus and the very glue between the game's appearance and its internal mechanics.(“Inside Spacewar! — Part 2: To Draw a Star”, N.L., 2014)
This really emphasizes, how complete Spacewar! already was as a game, how much consideration was put in it from the very beginning. Not only was it centered around a twofold challenge, the educational experience of mastering a spaceship’s motion mechanics, Spacewar!’s simulation aspect, and the playfull challenge of overcoming the opponent in doing so, it combined these elements in a well orchestrated and cheerful rendition that drew as much from the constraints of the techical implementation as from a pop-culture background, which enriched by its mere evocation of ephemeral themes and references the joy and thrills of the game.
This started with the very outlines of the cartoonish spaceships
[The rockets] were rather crude cartoons. But one of them was curvy like a Buck Rogers 1930s spaceship. And the other one was very straight and long and thin like a Redstone rocket. (Steve Russell quoted in Kent, Steven L. The Ultimate History of Video Games. Roseville, CA: Prima Publishing, 2001)
and didn’t end with the exciting animation of the first “Minskytron hyperspace” that would send less experienced players to safe heavens by a “local distortion of space-time resulting in a warp-induced photonic stress emission” (J.M. Graetz, op. cit.).
By May 1962 the game was eventually frozen and presented at MIT's annual Science Open House. By the time, the game had incorporated a few more bells and whistles. As there are:
- Two cartoonish spaceships, one a 1930s Buck Rogers-style spaceship, the other one a contemporary, Space Race inspired Redstone rocket, navigating in toroidal space;
- Two spaceship mechanics to chose from (inertial navigation and Bergenholm gyros);
- An ample supply of torpedoes (32 for each spaceship);
- A pulsating central star excerting a gravitational pull on the two ships;
- Fading trails added by the Type 30 display’s P7-phosphor to any animate graphics;
- The “warp-induced photonic stress emission” effect of J. M. Graetz’s first hyperspace; (While a late addition, hyperspace had been planned for from the very beginning as the means of leveling the playfield and allowing players of varying degrees of experience and accomplishment to compete with one another.)
- A somewhat crude particle effect for exploding spaceships (the so-called “crock explosions”, which would become more refined in Spacewar! 3.1);
- Peter Samson’s “Expensive Planetarium”, an animated rendition of the night sky (down to just above fifth magnitude between 22½ degrees N and 22½ degrees S, thus including most of the familiar constellations), which served as a realistic backdrop to the game;
- An automatic restart facility detecting end of game state;
- A scoring and match play facility, devised to manage a stream of eager players lining up for their chance to experience the game;
- Specially devised game controllers (AKA control boxes).
At this state, the game had also gained a few options, which were accessible by the PDP-1’s array of sense switches, like a more easily to handle Bergenholm navigation by gyros (as opposed to the more realistic inertial navigation by the angular momentum effected by a ship’s by rocket thrusters), speed settings for the “Expensive Planetarium” (slow , normal, and static), and the effect of a collision with the central star (instant death or warping to the antipodes at the very corners of the playfield.)
The first of these options, the one regarding the mode of maneuvering, proves the unprecedented talent of the Spacewar! designers: even, if this was meant to be a simulation, they knew exactly where and when to cut back on the realism in order to preserve the experience, to even enable it in the first place.
Initially, there had been just inertial navigation by rocket thrusters, by adding or subtracting angular moment, what Steve Russell described above as “coasting” in space. The challenge was really in mastering a carefully orchestrated combination of steering, counter-steering and thrusting, while meeting the openent and keeping aim provided the motivational objective for all this maneuvering. When the much more satisfying challenge of gravity was added, this really became a bit too much and the futuristic “Bergenholm Inertialess Drive” (J.M. Graetz, op. cit.) by gyros was introduced: just let go of the turn controls and the spaceship stops at its current heading (just like with about every arcade game, since). Had the game been initially about the educational simulation of inertial navigation and “how spacships coast in space”, it was now about maneuvering in orbit. If the addidtion of unrealistic means of maneuvering was what it took to refocus the game on the tactical challenge and to preserve the motivational side of things, it was welcome. At least, this was science fiction stuff all along. (Much like the photon torpedoes and jumping to hyperspace.)
It was crucially this ability to back away from the original claim that made it an even more interesting simulation — and a much better game, with all its tactical and strategic aspects. As Steve Russell put it in
It’s a relatively fast-paced, and that makes it an interesting game. It seems to be a reasonable compromise between action — pushing buttons — and thought. Thought does help you, and there are some tactical considerations, but just plain reflexes also help.
We may observe that this “reasonable compromise between action — pushing buttons — and thought” is also a major provision for any modeless graphical user interface (GUI): fast paced motor controls for mastering pointing and operating widgets in combination with tactical considerations regarding the workflow and intended objectives. Spacewar! also establishes that a program can evoke a magical world sui generis on the screen, as long as its internal physics are concise, and that such a virtual world may be navigated quite naturally by reaching “through the screen” in real-time by use of a minimal set of controls. — Again, a major provision for any GUI. I guess, this common ground is probably, why Stewart Brand put Spacewar! and the developments at Xerox PARC, which brought us the GUI, side by side in his seminal Rolling Stone article “Spacewar — Fanatic Life and Symbolic Death Among the Computer Bums” (September issue, No 7, 1972), of which “II Cybernetic Frontiers” is an extended version.
In September 1962, Steve Russell revisited the game for a refined version 3.1, which added, besides a bit of refactoring, a revised hyperspace, which did away with the Minskytron effect in favor for a more random chance of a fatal defect that was better prone to limit its use in gameplay, a table of configurable parameters to tweak the game and its mechanics, a (default) option for firing torpedos in salvoes, and a less flickerprone version of the “Expensive Planetarium”. Moreover, it fixed the visible square confinement of the “crock explosions” for pretty clouds of pixel dust.
At the end of the year, MIT’s PDP-1 recieved an automatic multiply/divide option as an upgrade, which facilitated an even better gravity algorithm that converted fixed-point coordinates to floating point and back again to provide higher precision (devised by Demitrios D. “Monty” Peronas). As seen in version 4.1, the somewhat canonical version of the game. The last known version of classic MIT Spacewar! is version 4.8, which features an on-screen score display, devised by Peter Samson and based on an earlier version of such a visual scoring mechanism. (Visually and gameplay-wise, this last version is identical to the one presented at the Computer History Museum in Mountain View, CA.)
In addition to this, there were some quite arcane versions: There is a version 4.3 by Joe Morris, based on a version by Diamantis Drakos “Monty” Preonas, which features a display option with one of the spaceships, the Needle, fixed to the center of the screen and everything else displayed relative to it in some kind of polar view. (Confusingly, there’s also another version 4.3, as we’re dealing here with two parallel strains of MIT Spacewar!.) Version 4.4, May 1963, also by Joe Morris and Monty Preonas, took this another step further by displaying two distinctive views relative to each of the spacships on a dedicated display. (Compare the emulation and the related discussion of the code.) While this is not a true first person perspective, it still provides a dedicated, subjective view for each of the players, relative to their respective position in space (and epicycles for the oponents ship as it swerves around the central star)! Sort of like the view on a radar screen inside a spacship — mind that the scopes utilized tubes that were produced for actual radar displays, this was the “real stuff”. While the program isn’t perfect and requires one or two fixes (which are easy enough to provide), the intention is clear. Notably, this predated Maze (or Maze War) by 9 years! (While the viewport doesn’t rotate around a fixed orientation of the ship, as the limited computing power wouldn’t have allowed for this, this still conveys all the instabilities and puzzels inherent to a true first-person perspective.)
Note: The feasability of a true first-persion version (and the lack thereof) was briefly discussed in the Smithsonian event, but without any notion of this version 4.4.
However, apart from these arcane attempts at a subjective multidisplay rendition and the visual score display, there haven’t been any crucial changes to the game at all. — Which is a testament to the amount of care and the kind of inspiration that went into a game, which was without any precedent. As Steve Russell proudly states,
The program, we’ve done, is now 50 years old, it’s a 1962 release — it’s more than 50 years old —, and there are no outstanding user complaints and support is still available. (AIAS Pioneer Award presentation, November 29, 2018)
BTW, the game fits into 4K of 18-bit words, which is the standard amount of core memory the PDP-1 came with. And, if you think that this is tiny, there was a (much more basic) version for the LINC computer by A.J. Hance, April 1965, which fits into less than 512 12-bit words, half a KB. (But this may be another story.)
Memory map of Spacewar! 3.1 for the DEC PDP-1, Sep. 1962 (addresses in octal) 0000 - 0002 reserved for sequence break system (interrupts) 0003 jump vector to sequence break flush (0061) 0004 default start address (jump to configure to use control boxes) 0005 alternative start address (jump to configure for test-word sw.) 0006 - 0031 table of essential game constants (for hacking) 0032 - 0037 free, space for patches (dedicated to alternative control input) 0040 instruction vector for alternative control input 0041 - 0060 free, space for patches 0061 - 0065 routine to flush sequence breaks 0066 - 0155 sine-cosine subroutine 0156 - 0245 BBN multiply subroutine 0246 - 0305 integer square root subroutine 0306 - 0403 BBN divide subroutine 0404 - 0647 outline compiler 0650 - 1127 display routine for gravitional star 1130 - 1443 Expensive Planetarium (display routine) 1444 - 2734 Spacewar! main code 2735 - 2744 outline data spaceship 1 2745 - 2751 free 2752 - 2761 outline data spaceship 2 2762 - 2765 free 2767 - 3111 constants 3112 - 3222 unused (space left by assembler on symbol assignment) 3223 - 3275 variables 3276 - 3475 free, space for patches 3476 - 3772 space reserved for the objects table 3773 - 5245 code produced by the outline compiler goes here 5246 - 6077 free (unused) 6077 - 7750 Expensive Planetarium (star-map data) 7751 - 7777 free (binary loader resides here)
Spacewar 1 — Reconstruction
Now, we may muse what Spacewar! would have looked and felt like right from the beginning, before gravity was added, which changed the game and intrinsic mechanics in such a crucial way. Let’s call this “Spacewar 1”, since the earliest preserved version, we know of, is “Spacewar 2B”. And, where there’s a version 2 (or even, “2B”), there must have been a version 1, at least, retroactively.
While there is no known listing or binary tape (or “octal program” in the terms of the day), we can reconstruct this with some degree of confidence and by a bit of conjecture. I actually did so 5 years ago, in April 2016, and it's time to revisit this reconstruction in the light of what was said at the Smithsonian presentation, namely, regarding the central star.
What we do know, is Spacewar 2B, like it was shown at the MIT Science Open House in May 1962. This survived in two forms: A printout of the source code, dated 25 March, 1962 (which showed up in 2014, together with a retyped version of the original Hyperspace patch) and a binary (sorry, octal) version of the program, dated 2 April, 1962. Both programs are identical but for a minor difference: the polarity of most of the sense switch option is flipped. Meaning, in the later version, you get an all-bells-and-whistle game with all sense switches off, while you would have to have most of them flipped to on for the same configuration in the earlier game.
Why would you do this?
My conjecture is that this was owed to the process that lead to the game as we know it. Which might also shed some light on the social process that brought the game into being. We know for instance that there were some options, which were suggested to the game, but proved unpopular and were later removed again. A prominent example is an option for realistically inaccurate aiming, introduced by Steve Russell at some point:
“One of the other things I experimented with was putting a little more realism in. The torpedoes in Spacewar go plodding along very reliably. I said, ‘Gee, that’s not real. Most real-world devices have some noise in them.’ So I put a little random error in the torpedoes. They wouldn’t always go quite in the direction you aimed them, and they didn’t always go quite the as far as expected. I thought it was kind of a neat idea, but everybody just hated it. And if you think about it, you’ll see that people take a great deal of effort to make sure that their guns and knives and other offensive weapons are the best they can get. That variation died very quickly.”
Steve Russell in II Cybernetic Frontiers, op. cit., p. 56)
While we can't be sure, of what phase of the development of the game Steve Russell was talking here in particular, this still poses the question, how would you go about such a thing? Like a new variation to the game, or a patch introducing a new feature? (E.g., the Hypespace patch, dated 2 May 1962, bears the phantastical version number “VIci”, which can be read either as 6.3.9 or even as 6.101. Apparently, no effort was spared to get the effect right. Another testament to the importance that was put to the visual presentation.) Surely, there had been various features and enhancements proposed, some were commonly approved and made it into the final game, while others would have been dismissed and eventually discarded and forgotten. I guess, the proper way to do it would have been to make it an optional feature. — “See this new feature on sense switch 3! Isn’t it great?”
Eventually, as March turned into April, when the game had found its final form, becoming, as we would say today, feature-complete, you wanted all the proven and now usual options and bells and whistle in the default configuration. If you really wanted, you still could have navigation by angular momentum, but in the default congiguration it was now inertialess gyros.
So, in the later version, which is probably what was shown at the Open House in May, the default configuration was the game with all its approved and beloved features. Conversely, if we flip all the sense switches to on, we get the game in its most basic configuration: the original navigation by rocket thrusters, low gravity (half of the standard one), no background stars (Expensive Planetarium), and no central star.
Meaning for our reconstruction, we’ll strip the program of all but these basic features (and of gravity entirely), and put just these in that we know of for certain that they were in it. Particularly, this is a random starfield and, as we’ve just learned, the central star.
The Outline Interpreter
Let’s start with the elphant in the room, which is the original outline interpreter. To begin with, we have to stress that it’s really the dedication to visual detail, which made its later replacement by the JIT compiler a requirement. If Steve Russell had been happy with some simple abstract shapes to represent the spaceships, say a triangle and an oblongate rectangle (as the common nicknames “Wedge” and “Needle” do suggest anyway), the code for drawing the respective outlines could have been implemented straight away, without any need for an interpreter — and thus without any need to replace this by a more performant JIT code.
While the designers of Spacewar! were happy enough to let go of the original realism and the original educational experience by refocusing the game from initerial navigation to orbiting (which required simpler, but less realistic mechanics for navigation), there was another kind of realism that was more important, which was not up to debate. This other, indispensable realism, which may be called “aesthetic realism”, was more related to the media side of things. The starships had to look right, they had to evoke the right kind of cultural background: ephimeral cultural memories, like sci-fi novels, trash films, and 1930s Buck Rogers cartoons on the one hand, and the contemporary excitements of the Space Race on the other hand.
There is no way to get this kind of evocation right from the beginning, just by typing some code and maybe a quick correction, where it doesn’t fit perfectly, right away. This affords fiddling. And what you wanted for proper fiddling is a tiny graphical language for drawing the outlines of the spaceships.
Something like this:
0: (fall through to 1) 1: down 2: outwards 3: outwards & downwards 4: inwards 5: inwards & downwards 6: store/restore position 7: end of code, first pass: flip and start over second pass: exit & return / outlines of spaceships ot1, 111131 111111 111111 111163 311111 146111 111114 700000 ot2, 013113 113111 116313 131111 161151 111633 365114 700000
There are 7 commands in total, just the right number to fit into a 3-bit octal number. A nice example for how common abstractions do inform programming. Just like programmers are apt to think in hexadecimal numbers (0…F or decimal 0…15) and octets (00…FF or decimal 0…255) since multiples of 8 bits have become the prevalent word size with the advent of the microprocessor, in the days of descrete logic, when memory used to come in triplets, octal numbers were the common abstraction and “natural” unit size. — Just as we see it here.
5 of these commands are dedicated to moving the plotting position along and relative to the vertical axis of a spaceship, one marks a position in order to return to this on the next encounter of this code (as needed for drawing the fins), and a last one marks the end of the outline commands. On first encounter of this last code we flip parameters and start over in order to draw a symetrical second half of the outline, on second encounter we’re done and the routine returns to the main program.
In order to parse and display the outline codes, we need to do the following:
- Keep track of which word of the outline code we’re currently inspecting,
- Keep track of and extract the appropriate 3 bits (octal graphics code),
- Interpret this code by selecting (i.e. jumping to) the respective calculations,
- Display a dot (where appropriate),
- Loop around until we hit code 7 a second time.
And we’ll have to do this each frame of the game. Here, a brief excursus on the PDP-1 as a gaming platform may be approriate.
Excursus: Platform Considerations
A brief overview of the most crucial characteristics of the PDP-1, which not only inform how spaceships are displayed, but Spacewar! as a whole, as well.
The PDP-1’s Type 30 CRT display is the most basic of x/y or random scan displays: We just provide x and y coordinates (and a brightness) and instruct the display to display a dot at this location (of which there are 1024 × 1024, providing a quite remarkable resolution). This is essentially a fire-and-forget operation. There is no display memory and we’ll have to display the dot again, if we want it displayed permanently.
Since consecutive display commands may address arbitrary locations anywhere on the screen, the cathode ray has to swerve from point to point quite rapidly, which involves some rather high voltages in the deflection coils. Therefore, in order to provide a crisp and stable image, the display comes with cooling circuits for these coils in order to let the coils stabilize and prevent any under- and overshoot. Most of the runtime of 50 μs (microseconds) of a display operation is dedicated to this cooling, which makes displaying a dot the most expensive operation on the PDP-1 and the crucial bottleneck of any visual program.
(The PDP-1 is capable of displaying a maximum of 20,000 dots per second — assuming our program doesn’t anything other than issuing display command. Which gives us, with a reasonable frame rate for a flicker free display of, say, 18 fps, about 1,100 display instructions per frame, which is just good enough for a single line accross the display. From this follows that we really want to keep the number of displayed dots as low as possible, epecially, if we want to include some logic, as well. Thankfully, space is for the most just a black void, which lends this theme especially well to the PDP-1.)
Some characteristic run-time expenses for PDP-1 intructions are:
- display instruction: 50 μs
- simple instruction internal to the processor: 5 μs
- instruction involving memory: 10 μs
- indirect addressing: add 5 μs for each lookup
- multiplication and division are vastly expensive: these are subroutines involving iterations over each of the 18 bits of a word. (With the hardware multiply/divide upgrade, which became available in 1962, this shrinks to a mere 14-25 μs for a multiplication and 30-40 μs for a division.)
As we may observe, a display operation takes about 10 times of the most simple of operations, which provides some run-time to accomplish other things between display operations. In its basic form, a display instruction is an asynchronous operation. However, we may instruct the display to send a “completion pulse”, when it has finished with displaying a dot and is ready for the next one, and there is a form of the display instruction, which will halt the processor to wait for such completion pulse, if it hasn’t yet recieved one. Providing the following variations of the display instruction:
- display a dot asynchronously (“fire and forget”)
- display a dot and request a completion pulse
- display a dot awaiting a previous completion pulse
- display a dot awaiting a previous completion pulse and request a new one
The latter variant is of special note, since it allows us to interleave display operations with code preparing for the next one at optimal effeciency.
The PDP-1 has two CPU registers that are accessible to a program, the accumulator and an auxiliary I/O register. Both of these 18-bit registers are used by the display instruction to provide the display coordinates. The CRT, however, uses just the highest 10 bits (signed, origin at the center), which provides a “natural” fixed-point representation of 10 signed binary integer digits and 8 fractional bits. Which is also, what’s internally used by Spacewar!, providing for subtle “subpixel” increments.
Further, the PDP-1 has a barrel shifter (meaning, we may shift/rotate the contents of any of these CPU registers by up to 9 bit positions in any direction at once, which also provides the means of swapping these registers by combining them into a large 36-bit registers). More precisely, it’s a mirco-sequenced shifter, stepping over the bits of a 9-bit operand in a single instruction and performing a shift for any bit found set to hi in this operand. This makes scaling values a breeze, an operation, which we encounter quite frequently in Spacewar!.
The basic principle of a just-in-time (JIT) compiler is simple enough: Since the image has to be refreshed every frame, an interpreter has to execute the entire procedure each frame, as well. The compiler, on the other hand, runs only once and rather than executing the calculations for the coordinates and the display commands in place, we push those to memory to be executed as a subroutine. The result of this separation of concerns, parsing the outline codes on the one hand and displaying dots at the other hand, is an extreme example of the space-versus-time paradigm: the essence of an unrolled loop without any of the ballast of the housekeeping instructions to maintain this loop. The benefits are quite obvious: At the cost of some memory we get the fastest code possible.
But there is another benefit, which isn’t that obvious: Since there are just two CPU registers and both of them are involved in a display instruction, using an interpreter, any code involved in the interpretation will compete for these registers with the display code. As we're traversing along the outline in relative increments, we’ll have to swap the coordinates in from memory and back again, as they are destroyed by the logic maintaining the parsing loop. As we’ve seen above, memory instructions are the second most expensive instructions, there are. Hence, we'll save a considerable amount of runtime by not having to do this swapping for every dot displayed, since no such roundtrip to memory is required for the compiled version.
Still, we have to stress, none of this would have been an issue with simple, platonic shapes, had it not been for this “aesthetic realism”, if some platonic shapes had been good enough, which could have been accomplished by a simple line-drawing algorithm. In other words, it’s the aesthetic ambitions, which brought Spacewar! into this mess, to begin with.
Anyway, regarding our reconstruction, we’ll have to reverse this process. As already illustrated by the example of Steve Russell, human ingenuity tends to go hand in hand with lazyness. There’s no reason to assume any different regarding Dan Edwards and his outline compiler. Surely, he wouldn’t have reinvented the wheel without need, rather, he would have stuck to Russell’s precious outline routine, where possible.
It may be of note that Dan Edwards had previously worked with Steve Russell on the implementation of the very first S-expression interpreter of Lisp and was probably quite familiar with Russell’s style. On a more humorous note, it had been this very effort towards a general interpretation of S-expressions that had rendered McCarty’s original plans for M-expressions obsolete. But here, in Spacewar!’s outline compiler, the most important macro “
comtab” takes two arguments, each consisting of a literal for a PDP-1 instruction, expressed as PDP-1 assembler literals, which in turns consist of the mnemonic of an instruction code and an assembler variable representing the address. In a way, McCarthy finally got his M-expressions with S-expressions data…
How would we approach such a JIT compiler? Well, we might introduce a macro for pushing things to subsequent memory locations, and, rather than executing the coordinate and display business in-place, we might feed them into this macro to take care of the business. Which is exactly what we do find in Spacewar!. Reversing this is simple enough: wherever there’s a call to the macro, we replace it by a direct call to the instructions passed to it. Since we’re lazy ourselves, we may even repurpose the existing macro to execute the instructions in question and take care of the redundant memory management, as well, which is common to all the advance-and-display codes. Thus, we also gain confidence in the fidelity of our implementation.
Note: Having a closer look at the structure of the outline codes, we may also imagine a totally different implementation, like parsing this like microcode, where the least significant bit indicates a vertical progression of the cathod ray (along to the main axis of the spacship) and the two remaining bits a lateral deviation to either side, while the presence of both of those bits at once encodes a non-displaying operation. However, this would have meant that Dan Edwards would have reinvented the wheel all together, which isn’t very likely. Moreover, managing the interpretation by a single jump in a dispatch table, just like the outline compiler does it, is faster than checking individual bits, anyway.
There’s a last point of interest in the outline display, namely, the very kind of display instructions used. As we’ve seen above, there are four variations of the display instruction, respective to the degree of synchronization, we attempt. While this is not an issue with the interpreter, where the runtime of the code maintaining the loop exceeds by far the minimum time required between any two consecutive display instructions, this is a potential issue in JIT code. Therefore, it’s small wonder that we find the highly synchronized variant used, where each instruction awaits the completion pulse from the display and in turn requests a new one. However, this implies a first completion pulse to be sent by the display, otherwise our code would stall, forever awaiting a signal, which is not to come. Since there is no way to receive such a completion pulse other than by issuing an appropriate display instruction, each run of the outline code starts with a display instruction that produces a dot at the center origin of the display as an artifact.
In the “production versions” of Spacewar! this artifact is hidden by the central star (but it is still there, to be observed, if we disable the central star by sense switch 6). Conversely, it’s perfectly possible that this artifact may have inspired the idea of the central star, right away. Since this dot at the center is refreshed every frame, while any stars in the background are comparably dim, as they are refreshed only every second frame, it’s by far the brightest star on the screen. Moreover, it its at the very center, fixed, immovable, always present, even, if there are no background stars at all. It's easy to think of this bright spot as a sun. — And, for the sake of aesthetic realism, why not do it properly?
While it is not clear, which variant of the display instruction had been used in the original outline interpreter, this conjecture suggests that it may have been quite the same as we find it used by the outline compiler.
The Central Star
Speaking of the Sun, this is one of the things, we’ve learned to not strip from the game. This is easy enough. It’s a self-contained, highly encapsuled subroutine (even more so than the Expensive Planetarium, which has become famous as the program in the program) called at the very end of the main loop, just after the call of the background subroutine (indicating the later addition), both of them put next to another in the first part of the source code, which contains all those subroutines that are somewhat external to the game.
As there was a central star, could you also collide with it? No way. The collision detection in later versions is part of the gravity calculation (and located far away in the spaceship routine) and relies on some factors of these calculations, which are very expensive to compute. So no instant death on collision and no warping to the antipodes. It is what it is, a pure ornament.
The Random Starfield
We know that there was a random starfield, before the Expensive Planetarium was added, and also that it was this very random starfield, which annoyed Peter Samson to a degree, which lead him to invest substantial effort to replace it by a simulation of proper realism. We also know that this random starfield wasn’t just for pure aesthetics, but served a particular purpose:
It was apparent almost immediately that the featureless background was a liability. It was hard to gauge relative motion; you couldn't tell if the ships were drifting apart or together when they were moving slowly. What we needed, obviously, were some stars. Russell wrote in a random display of dots, and the quality of play improved.
(J.M. Graetz, The Origin of Spacewar, op. cit.)
Having a background was important to give some idea of range and so on.
(Steve Russell quoted in II Cybernetic Frontiers, op. cit., p. 56)
So much, we do know. The rest is left to imagination. That is, the game comes with a random number generator (which was derived from some TX-0 code) and this would have been used for the starfield, as well. How many stars? At least enough to serve the purpose of providing a reference for estimating motion, which suggests a certain minimal density. On the other hand, we won’t go too luxuriously about this, since runtime is a consideration. Certainly, we would make this a nice, round octal number. I went for 060, which is about the average number of stars displayed at once at any time by the Expensive Planetarium. It’s also about the right amount of stars to inspire the idea of constellations, to even provoke the question, “Why are these not real constellations?”
How would we store it? Now, when I first started to investigate Spacewar code, there was a common myth regarding Spacewar running that low on memory that multiple parameters had to be stored in a shared memory location. In actuality, there is not a single instance of this found anywhere in the code. That is, in the Hyperspace patch, we find such a technique used to store three pairs of screen coordinates used for drawing the Minskytron effect. So I thought, it may be nice to use this technique as well in order to honor the myth. (Who knows, maybe there’s some truth to this, all along?) At least, regarding runtime, an extra memory access is just as expensive as a splitting the pair of coordinates into the two registers used by the display command. So there’s no harm to it, it’s economic on memory, and a single random number does for a pair of coordinates during setup. Even better, it also provides a safeguard against the greatest assumed accident of such a random starfield: two random stars accidentally touching one another, by this becoming an unsightly and irritating blob. As it happens, the display uses 10 bit coordinates, while splitting an 18-bit value gives us two 9-bit coordinates with the least significant bit always zero. This way, we get a minimum distance of 2 display locations between stars for free.
Should this be a static background, or should the stars move, quite like in the Expensive Planetarium? We may recall John A. McKenzie’s testimony:
- “1300 DEC installed display. Okay to use. Repeated display of a single point will bum CRT.” I had that underlined.
This was something to be respected. It was in the log, it was even underlined to convey the urgency of this recommendation. I guess, you won’t go against this in the first month or so, and you wouldn’t have wanted to be caught doing so by McKenzie or by Jack Dennis. At some instance, I really don’t recall the context, some sort of Q&A session following a presentation (so no source for this), Steve Russell also mentioned explicitly that the game had always had some built-in burn-in prevention. So it’s a fair guess that a static starfield was probably a no-go. How fast should it move? Well, not too fast, mostly indiscernibly in order to provide points of reference, but still fast enough to prevent burn-in. From this also follows that this may have been a lateral motion only, quite like the Expensive Planetarium, and as we are at it, we may copy the count-up value (and by this the particular pace) for its slower mode from this (supposing, the idea for this must have come from somewhere).
Since all versions of Spacewar! come with an option to disable the backround, we’ll make this one optional, as well. And while we’re at it, we’ll add the background motion as an option, too, just, because the original Expensive Planetarium comes with a static mode, as well.
So, while there’s no positive hint on the particular implementation, we may say, these are all fair guesses, employing techniques and parameters that are grounded in actual Spacewar! code.
A final thing to consider is pace. While expressly designed for real-time computing, the PDP-1 doesn’t have a real-time clock. So how does Spacewar! control its pace? Well, there is total instruction budget, which is set anew at the beginning of each frame. Any of the routines for managing an on-screen object, like spaceships or photon torpedoes, will subtract an estimate of their instruction count from this budget. If there’s anything left at the end of the main loop, the remainder is burned in a count loop to make up for it.
As it happens, the run-time estimate assigned to each of these objects is also used for determining the size of an explosion. Call it the other side to Spacewar!’s aesthetic realism: large objects are those which are heavy in computation, like spaceships, small objects are those light-weight in computational resources, like photon torpedoes. Thus the visual size of an explosion is a function of the run-time estimate of the respective object.
Surely, we won’t fuzz with the explosions. Since the estimate assigned to a spaceship in Spacewar 2B is already half the total budget, it won’t matter anyway and the game will run at max speed, as long as there two spaceships displayed at once. Any additional torpedo, however, will cause a small slowdown.
Note: The avid reader may have observed already that the run-time budget doesn’t do much at all in Spacewar 2B. In the basic game, there will be always two spaceships on the screen, hence there never will be anything left to be burned for extra time. So, why is it in the program at all? Well, the only occasion, I can think of, where there may be less than two spaceships displayed, is one of the ships (or both) going to hyperspace. Without such a provision, the game would speed up considerably on the occasion. So it may be a fair guess to assume this was already preparing for the hyperspace routine that was to be added by Martin Graetz. While this eventually arrived in form of a patch tape, there are already variables reserved in the main program for the use of a future hyperspace routine and there is even a source comment indicating where this routine was expected to go. Proof for the hyperspace feature being a crucial element of the game, right from the beginning, as it had been conceived.
So had this run-time budget been already in the first demo? I don’t know, but it may well have been there, as hyperspace had been a much anticipated feature already.
The resulting source code, along with other versions, may be found here:
- www.masswerk.at/spacewar/sources/ (see sect. “Mods”).
Spacewar 1 — The Experience
Well, what it does this reconstruction look and feel like? In order to separate this from any authentic versions of Spacewar!, I made this available in an alternative UI, which features more accessible sense switch options (which may be of interest in this context) at the cost of a less realistic presentation of the CRT:
So, what is it like? Well, a bit like a Western-style shootout with supertankers. As expected, it’s all about mastering navigation (“coasting”) while running up to your oponent. While the addition of gravity and the speedup resulting from the outline compiler made this indeed a “much, much better game”, it’s worth mentioning that similar attractions were deemed sufficiently exciting to serve as the stereotypical climax of an entire film genre.
Another thing to be observed is pace. With gravity, it’s this added agency of the machine that sets the pace of the game in later versions, while it’s here left to the engagement of the players themselves. What Spacewar 1 is lacking, still awaiting, is this crucial autonomous agency, which found its focus and representation in the central star, in this twinkling object right at the center, at this stage merely an ornament, but destined to become the very incarnation of the game mechanics. (And, as we have seen, it’s not that improbable that this grew in turn from a mere artifact of the spacship drawing routine.)
What’s also remarkable, is the percieved size of the ships: they are huge! In comparison, the ships of Spacewar 2B feel much smaller and agile. And thanks to some fine-tuning of parameters, those of version 3.1 feel like actual roadsters.
An interesting detail are the exhaust trails and their length, as found in Spacewar 2B (which probably also applied to the original demo) and how they appear in Spacewar 3.1: In version 3.1 and ever thereafter, they had been extended to double the length of what they had been originally. Had this been done to reflect the change in perceived size of the ships?
And, speaking of the flickering exhaust trails, a final fun fact: While Spacewar 2B had a fuel spupply assigned to each of the ships, this was never actually used. It was only in Spacewar 3.1 that the fuel was actually burned, and the rate of the fuel consumption was a function of the visual extent of the exhaust trails and their random length animation. Yet another case of “aesthetic realism”.
Hacker News comments: news.ycombinator.com/item?id=26993407