Hacker News new | ask | show | jobs
by WheelsAtLarge 1380 days ago
What makes Quake so portable? Developer seem to be able to move it to just about any platform.
6 comments

Unlike most games of the era, Quake was designed to be portable. It's not tied to the PC / MS-DOS platform in the same way as many other cutting-edge games were. For example, there was a lot of x86 assembly used at the time, often just intermixed with C code with no clear boundaries to enable porting to a different architecture.

AFAIK, Quake was originally developed on NeXT boxes and ported to PC later. The level editor was a native app using the NeXTSTEP APIs which Apple renamed Cocoa:

https://quakewiki.org/wiki/QuakeEd

So, it's a fun kind of homecoming that it now runs on the wrist-sized NeXT box.

Just for a fun comparison.

The original NeXT computer: 25MHz Motorola 68030 plus copro, 8MB RAM, 256MB storage, 300W power usage, $15k in 2021 dollars, weighed a lot

The Apple Watch Series 7: 1800MHz t8301 CPU (but scales up and down), 1GB RAM, 32GB storage, 50-100 mW (I think?), $399, weighs 35g or so

What a difference 33 years makes!

The watch has similar specs to the first MacBook Pro from 2006!
The watch is more powerful than the netbook I'm typing on right now.
I sometimes think we have an 'embarrassment of riches' today - more computing power than we know what to do with!
No, we know exactly what to do with it: run a bunch of Electron apps to use it all up.
I think that even Doom was developed on NeXT (the game, not just the level editor), the alpha came out for NeXT before DOS.
Except the little detail that there is very little NeXT on that wrist-sized box, other than Objective-C is still the main language.
...the OS should be quite similar too, assuming watchOS is anything like iOS and macOS, because macOS essentially is the present day incarantion of NextStep due to the NeXT-Apple reverse takeover ;)

...not very relevant for DOOM of course, because that's just plain C for the most part, but interesting little tidbit nonetheless.

Except plenty of stuff has changed since NeXT days.

Objective-C driver kit no longer exists, its C++ replacement is on its way out, being replaced by a userspace version.

The watch uses watchOS UI KIT, is isn't either UI Kit nor Cocoa, so three generations apart from NeXTSTEP UI framework, which is anyway being replaced by SwiftUI.

watchOS uses a customized version of bitcode as deployment format, which is now being transitioned to actual native code in upcoming versions.

Related to Doom, watchOS doesn't do OpenGL, or NIB files from Project Builder.

So almost nothing like NeXTSTEP.

For a brief moment NeXT was trying to spread Openstep far and wide. What a future everyone could have had, rather than those locked into the Mac ecosystem. Which is most in this country, actually, so same thing I guess.
Many Java haters have little idea that Java itself and JavaEE were heavily influenced by Sun working alongside NeXT in such attempts.

https://cs.gmu.edu/~sean/stuff/java-objc.html

https://en.m.wikipedia.org/wiki/Distributed_Objects_Everywhe...

Quake has a software renderer, that probably helps.

But most importantly, ID software released the original source code for it quite early. Not that many game development companies do that. I would've loved to see more Blood ports, but I don't think the source was ever released? So I believe the existing ports were reverse engineered. Duke Nukem 3D source was only released in 2003 it looks like.

The quality of the source code of Quake 2 is quite high. Doom is.. a bit messy but OK. There are already abstractions that make porting easier. I'm guessing Quake (haven't looked at the source yet) is somewhere in between. That helps too.

The top sibling parent has the correct explanation, however, I'll expand a bit.

Games prior to Quake were bound to specific O/Ss and/or hardware components.

DOOM was still bound to DOS AFAIK, so it's not portable without significant changes.

Older games are even worse - not only they were bound to DOS, but also to the display adapters of the time (CGA/EGA), which required some sort of emulation (or translation, depending on the approach) in order to be ported.

Games based on the Build engine (written by Ken Silverman), like Duke Nukem 3D and Blood are... simply written in very poor form. Carmack is a tidy programmer, Silverman isn't. Quoting Fabien Sanglard:

> Looking at the innumerable ports that spawned Doom/Quake, I was always puzzled to see so few ports of Duke Nukem 3D. The same question arose when the engine was ported to OpenGL only when Ken Silverman decided to do it himself.

The answer is in his analysis: https://fabiensanglard.net/duke3d/code_legacy.php.

DOOM was definitely made with DOS in mind, but it also ran on NeXT from the beginning. It's pretty portable actually. Since you cited Fabien Sanglard, I guess I should mention that his book about DOOM's source code (Game Engine Black Book: DOOM) explains how the portability stuff (as well as almost everything else) worked in great detail.
Several of us would regularly play it in a Chemistry computer lab on SGI workstations. Annoyed the hell out of the students doing molecular simulations, regrettably.
I really miss one name here: Michael Abrash

John Carmack is awesome. However, to take the next step after Doom, he brought Michael Abrash on board.

> DOOM was still bound to DOS AFAIK

Doom was literally developed on NeXT computers (the precursors to modern Macs, ironic considering Doom was single-handhedly responsible for turning the public perception of PCs from boring office machines to cool gaming systems):

https://en.wikipedia.org/wiki/Development_of_Doom#Programmin...

> DOOM was still bound to DOS AFAIK, so it's not portable without significant changes

DOOM was always extremely portable, the DOS and PC specific parts are well separated from the other code (DOOM was actually developed on NeXT machines, so separating the platform specific parts probably came naturally).

Well, extremely portable, I wouldn't say so.

If you look at the ancestry of SDL2-Doom, for example, there are three ancestors:

- doomgeneric, which seems not simple (https://github.com/maximevince/fbDOOM/compare/master...ozkl:...)

- the above is based on fbDOOM, which is quite simple (https://github.com/maximevince/fbDOOM)

- the above is based on insane-adding-machines/DOOM, which is also not simple (https://github.com/id-Software/DOOM/compare/master...insane-...)

The SDL port itself (https://github.com/AlexOberhofer/sdl2-doom) is definitely not simple.

Porting something that it's not based on a multiplatform library (which is commonly SDL for old game ports) is not an easy task in general.

On SDL, there's an SDL2+minimal ANSI C environment for plan9/9front called NPE.

The SDL2 audio and video libraries are just shims against 9front drawing/audio functions, and often they just work.

Plugging a DOS game to an SDL(2) library won't "just work".

Some concepts are inherent to the hardware and the O/S.

Hardware example: EGA (not the case of doom, but of other, slightly older games) uses bitplanes, it's not just an array of byes; audio cards used specific drivers.

O/S: timers may need to be emulated, as the game may not have a straightforward game loop; due to this, even exiting cleanly may not be trivial to implement.

Quake basically pre-dated hardware rendering on consumer hardware. To a great extent, the consumer 3D accelerator market exists because of Quake. https://fabiensanglard.net/3dfx_sst1/
Aaah the brief, heady days of “no serious gamer would use a hybrid 2D/3D card” and the Voodoo fill rate wars. Fun times!
Voodoo... that's a name I haven't heard in awhile... thanks for that fun memory. Those were interesting times.
Quake and id Software were pioneering things we just take for granted now.

I remember playing QuakeWorld when it came out, on Linux, over a dial up modem. You had ping times of 200-300ms and it was playable. You have to remember at the time Doom and other games were LAN-only. John Carmack used to keep a .plan file with some really cool details behind Quake/QuakeWorld development. Check out Aug 02, 1996 for some detail behind the netcode[1]. You can read the future of gaming being invented right there.

[1] https://github.com/ESWAT/john-carmack-plan-archive/blob/mast...

Yes! SW renderer was one of the reasons I chose that! :-) Also, source code for id tech games is so well written, architected and highly readable.
Blood uses the build engine which was open sourced at about the same time as Quake, there are numerous source ports and it can run on most platforms (although people have gotten it running on mobile devices, there's never been an official port). As nblood is based on eduke32, I'd imagine the only reason it isn't available on more platforms is that no one has volunteered to do it.
Build/Duke was also Ken Silverman's second game. Doom was probably Carmack's 50th

That said, it had some things Doom fans dreamt of, like an interactive level editor that was built into the game engine.

The Build engine's source code isn't enough to port any game running on it, since Build was made as a library (I believe most developers using Build in the 90s didn't have access to the source code).

Also, wasn't there an official Blood port by Nightdive Studios?

It may have been fixed up since but the official ND port had some problems at the time of release (if I remember a civvie11 vid correctly)

edit: just looked it out, it seems this has been address. I'm linking the videos because they're entertaining :D

vid on the original: https://www.youtube.com/watch?v=EkG29e-nE-A

and the patched version: https://www.youtube.com/watch?v=oFUPNlfWiYg

Also, the original build code is extremely hard to read!
Written in plain readable C, open source, iconic game. Same with doom.

This is also from an era where there wasn't that much abstraction and "software rendering" was the norm so the implementations tended to be much more straightforward, this makes it so that worst case scenario, you just write to whatever the equivalent of a framebuffer is in the target implementation.

Should we maybe take that as a lesson?
Specially for those cases that ship a browser alongside the application....
>What makes Quake so portable?

There's like 10 glue functions you have to write to do things like initialize your platform, get input, begin the sound loop, call the main loop, and then something to switch buffers to the display. It takes a quite short amount of time to do. Id provides a set of null functions that you can use as a starting place and incrementally add in video support, input, sound, etc. They made it super easy to port.

I've been fiddling off and on making a tiny CM-2 computer model with all the blinking lights on the front panels. Inside it's an rpi zero 2, and I'm using some 1.5", 128x128 SPI RGB OLED displays instead of trying to make itty-bitty LED arrays. Long story short I decided I should be able to run quake and quake2 on the thing. It only took two days to put in enough code to have them running.

I have chosen Quake because (arbitrary order): * great game * codebase is well written, highly readable, well architected, there are tons of documentation and also a lot of existing ports to look at for inspiration and reference * SW renderer -> meaning it runs everywhere, rewriting GL renderer to Metal or anything HW accelerated would be much more work
It helps that Carmack is a talented coder too.