Books for Game Developers
mrelusive.com
mrelusive.com
I opened the collection of links, which is quite good if a bit old. But then I had a subconscious mental itch, and thought, wait... where had I heard the name mrelusive before? That sounds _really_ familiar.
And then I remembered - oh, right, mrelusive, JP-what's-his-name. I've read a huge amount of his code. When I was working on Quake4 as a game programmer and technical designer, he was writing a truly prodigious amount of code in Doom 3 that we kept getting in code updates that I was downstream of.
And he was obviously a terrifically smart guy, that was clear.
But I had cut my teeth on Carmack's style of game code while working in earlier engines. Carmack's style of game code did, and still does, heavily resonate with my personal sensibilities as a game maker. I'm not sure if that particular style of code was influenced by id's time working with Objective-C and NeXTStep in their earlier editors, but I've long suspected it might have been - writing this comment reminds me I'd been meaning to explore that history.
Anyway, idTech4's actual game (non-rendering) code was much less influenced by Carmack, and was written in a distinctly MFC-style of C++, with a giant, brittle, scope-bleeding inheritance hierarchy. And my experience with it was pretty vexed compared to earlier engines. I ultimately left the team for a bunch of different reasons a while before Quake4 shipped, and it's the AAA game I had the least impact on by a wide margin.
I was thinking about all this as I was poking over the website, toying with the idea of writing something longer about the general topics. Might make a good HN comment, I thought...
But then I noticed that everything on his site was frozen in amber sometime around 2015... which made me uneasy. And sure enough, J.M.P. van Waveren died of cancer back in 2017 at age 39. He was a month younger than me.
I didn't really know him except through his code and forwards from other team members who were interacting with id more directly at the time. But what an incredible loss.
Curious to hear what aspects of Objective-C you feel influenced id?
Well, 'id' is the generic object type in ObjC. ;-)
I remember I had a handful of conversations with Bryan Dube during development about Q4 deathmatch. He was a super sharp game programmer / technical designer who had done a ton of the work on Soldier of Fortune 2 deathmatch previously, and had worked on the Urban Terror mod for Quake 3 before that. And he was much more focused on multiplayer than I was.
We talked a lot about weapons (as I had done most of the code side work on weapons in Soldier of Fortune), but I'm now remembering him being really keen at the time on adding more high skill play to Q4 deathmatch. We all loved rocket jumping, and I remember him really wanting to add other kinds of high skill movement.
So that much I definitely remember. More than that and my memory is kind of fuzzy. To be honest, lots of team members loved deathmatch and Quake, and all of us were of course talking about gameplay possibilities all the time, so it's possible the idea originated somewhere else on the team.
// RAVEN BEGIN
// bdube: crouch slide, nick maggoire is awesome
https://github.com/bc85/quake4/blob/master/game/physics/Phys...Nick Maggoire is an animator. Super nice guy. No inside voice at all. I shared an office with him for a while :) I haven't kept up with him, but after Q4 he left for Valve where he's been ever since, it seems.
That comment strongly suggests to me that Nick did the animations for players crouch sliding. Or, that's my hunch anyway.
And I loved Masters of Doom, too, although it was weird reading it and occasionally seeing people I knew show up in it, briefly.
I actually did all the effects work on the weapons (muzzleflashes, smoke, explosions, bullet holes and surface sprays, and all the extensions to Quake2's particle systems to make that content possible) and all the single player weapons system game balancing, as a matter of fact. Both the sound design and animation / modelling on the weapons went through a number of iterations to get them really over-the-top and delightfully powerful / ridiculous, too - I was lucky to work closely with a great sound designer and a really talented animator on that.
https://mrelusive.com/publications/pubs_bytype.html
His ACM contributions: https://dl.acm.org/profile/81504687994
And he died in 2017 :( "Carmack paid tribute to him with the comment that he was "the best developer I ever worked with, my right hand, and a good friend. It was an honor.""
https://www.gamedeveloper.com/programming/obituary-jan-paul-...
I like how there's a whole book on quaternions. I've never understood them and I'm convinced every definition I've read was written by someone who also didn't understand them. I might try to find a copy if I ever dabble in 3d again
Edit: To clarify, I understand the need for quaternions (to avoid gimbal lock), just not how to use them manually. Euler angles are simple enough, I can change whichever axis by some degrees or radians. But with quaternions I never understood what was going on under the hood
Instead of representing a rotation by roll, pitch, and yaw... you represent rotations by a 4x4 matrix. As this is a 3-dimension problem being represented in a 4-dimensional matrix, you have some weirdness to the math (IE: you need an additional constraint) but otherwise things get easier.
---------
"Why is it easier?" Because roll / pitch / yaw systems have Gimbal Lock.
That's... pretty much all you need to know as far as I'm concerned. Its a different system of representing rotations for reasons that the "classic" system messes up in.
------------
The math for quaternions is hard, but... who uses math these days? Just go into Blender, click the Quaternion button, and click the up/down buttons on the Quaternion matrix to see how the different values rotate the object.
Once you practice both "classic" (pitch/yaw/roll) vs "quaternions" for... I dunno... 10 minutes? It becomes blatantly obvious that quaternions are easier to use. Its not even close. And I'm not sure if anyone has to implement the math of them anymore in any circumstances, so its just a matter of practicing them inside a 3d modeling program to see how to use it.
After you've learned how to use quaternions, then you go back and learn the math behind it. If you care to. Or don't, its not like you need to know what the matrix represents exactly...
---------
EDIT: Consider animation. If you've got an object that's rotating from (roll: 90-degrees, pitch: 90-degrees, yaw: 0-degrees), into (roll: 0-degrees, pitch: 180-degrees, yaw: 90-degrees), and you change this by going...
(90, 90, 0)
(89, 91, 1)
(88, 92, 2)
...
(2, 178, 88)
(1, 179, 89)
(0, 180, 90)
Did the object rotate and "look" correct in all frames?
Now do the same with the 4x4 matrix quaternion. This is all just a simple click in Blender + animation keyframes. Does the object look better?
Weird crap happens in the roll/pitch/yaw form. Weird in ways that's difficult to describe in words, but easy as crap to see in 30-seconds of Blender. So just pull out a 3d modeling program and look at the damn thing, its really obvious.
Maybe reading this comment helps: https://news.ycombinator.com/item?id=37527928#37529562
Basic concept, 1 dimensional form: you want to represent a direction in a 2D plane. You can use one number, a heading angle, but at some point you reach a full circle and the number has to wrap. This creates annoying special cases. So another approach is to use a 2D vector, a point on a circle. Those are usually normalized so that x^2 + y^2 = 1. No angle is "special". You can average and filter such vectors without problems, for example. This is called a homogeneous representation, because it behaves the same everywhere in its space.
Now upgrade to 2D - latitude and longitude. Near the poles, small positional changes cause huge latitude changes, and computation error increases. This is a serious problem in navigational systems. So it's common to represent latitude and longitude inside of GPS systems as a 3-component vector, a point on a sphere, in what's called "Earth-centered, earth fixed" form. Now you can average or difference measurements without special cases. (Yeah, WGS-84 to compensate for planet not being a perfect sphere, etc.)
Now upgrade to 3D orientation. That's a quaternion. It's a point on a 4-dimensional hypersphere. This can be mapped to a 3D vector pointing in space and a roll around that vector, or to pitch-roll-yaw, etc. As above, a quaternion is a unit vector. It's hard to visualize this, so just shut up and calculate.
Quaternions don't specifically need to be unit vectors or points on a 4-D hypersphere. They are any number with 3 imaginary parts and 1 real part. Being a unit operator is a property of a rotation (this holds true even if you aren't using quaternions or if you extend to n-dimensional rotations), not a property of quaternions.
Edit to add: When I say "you don't need to understand how they work to use them", I mean, you can literally implement all the math to multiply, conjugate, scale and invert quaternions from basic math operators and floating point numbers in C, and use those operations to rotate 3d objects around in your program successfully, all without having any idea why they work. I know this, because I have done it.
The basis for my understanding how to use quaternions, and how to build the basic operations on them comes from this site, which is quite concise and dense, but contains the necessary information if you can beat your head against it persistently: http://www.tutis.ca/Rotate/7quaternions.htm
(normalized) Quaternions are just the intermediate representation of axis-angles, they describe the component-wise algebra of combining axis-angle rotations [Euler-Rodrigues formula](https://en.wikipedia.org/wiki/Euler–Rodrigues_formula)
Game engines just leaves them as quaternions for performance reasons.
A 2D analogy would be
“angle” <-> [quaternion]
“45deg” <-> [sqrt2 , sqrt2]
The [ Re , Im ] form is convenient for manipulating by coordinates, but the “final” succinct representation is still “angle”, because the component-wise form has more degrees of freedom than necessary.Summary:
Quaternion = sqrt( exp(axis_angle) )
= exp(axis_angle/2)
= cos(angle/2) + axis*sin(angle/2)
And (lw,lx,ly,lz)*(rw,rx,ry,rz) = (w,x,y,z)
where
w = ww-xx-yy-zz
x = wx+xw+yz-zy
y = wy+yw+zx-xz
z = wz+zw+xy-yx
where
ww,wx,wy,wz = lw*rw,lw*rx,lw*ry,lw*rz
xw,xx,xy,xz = lx*rw,lx*rx,lx*ry,lx*rz
yw,yx,yy,yz = ly*rw,ly*rx,ly*ry,ly*rz
zw,zx,zy,zz = lz*rw,lz*rx,lz*ry,lz*rzOne reason being, I suppose, processors are now much more superscalar-friendly so a matrix multiplication doesn't take much more time than a quaternion multiplication does. And with matrices, you get the whole package: not only rotations, but translations, scalings, and even projections, - all in one go. So you have simpler code, simpler data structures, and you don't lose performance so... why bother?
I didn't even include quaternions in my book. Well, not that I didn't want to. We had a whole discussion with the publisher about whether we should keep the whole chapter (complex numbers, conformal transformations, non-commutative 3D rotations, and quaternions) and I lost.
This seems about correct. The book in the list also seems to fall into that category.
Quaternions are actually really simple and pretty once you understand them. The idea is that you specify and axis and an angle. The axis alone gives you a 180° rotation. 1 is the identity and gives you no rotation. If you interpolate between those on a circle (cos/sin) you can get any rotation around that axis.
One may wonder why one needs the sandwich product to rotate a vector when simple multiplication is enough for complex numbers. The reason is that in 2D there is only one plane of rotation and all vectors lie in it. In higher dimensions vectors can be decomposed into a part that lies in the plane of rotation and a part that's orthogonal to it (parallel to the axis in 3D) that is untouched by the rotation. With the sandwich product the quaternions cancel out for the orthogonal part but combine for the part in the plane. This also makes it obvious you have to take half the angle.
Finding the quaternion that rotates between two vectors is also easy. You just multiply them, then take the square root to get the half-angle. Taking the square-root is extremely simple: assuming your quaternion is normalized, you just add 1 and renormalize! Obviously this doesn't work if that quaternion is -1 (can't normalize 0), but it makes sense geometrically: a 360° rotation (-1) is the same around any axis so no axis can be recovered, but for its square root (180°) you have to pick one. It's just not well defined.
Of course all of the above can be shown with a few lines of algebra, and with geometric algebra the whole thing becomes even cooler.
Game Feel - Steve Swink - 2008
The Art of Game Design a Deck of Lenses - Jesse Schell - 2014
101 Things I Learned in Architecture School - Matthew Frederick - 2007
Writing for Games: Theory & Practice - Hannah Nicklin - 2022
Procedural Generation in Game Design - Tanya Short/Tarn Adams - 2017
Procedural Storytelling in Game Design - Tanya Short/Tarn Adams - 2019
A Theory of Fun - Raph Koster - 2013
Designing Games: A Guide to Engineering Experiences by Tynan Sylvester (RimWorld)
To add to your list: I have a copy of Designing Games: A Guide to Engineering Experiences that I recently started reading.
Raph illuminated things about the psychology of what makes games fun that Id never realized nor seen before.
Challenges for Games Designers: Non-Digital Exercises for Video Game Designers - Brenda Romero / Ian Schreiber
Books For Game Developers - https://news.ycombinator.com/item?id=6309464 - Sept 2013 (32 comments)
Normally we downweight lists (see https://news.ycombinator.com/item?id=37518838 from yesterday) but the top comments in this thread are so good, I'm exempting this one.
Many toilet hours were spent reading dead-tree versions gdmag and ddj back in my youth.
I didn't see [1] Game Programming Patterns.
If you’re interested in how to put a game together, MVC is an obvious model to follow.
For those who don’t understand what I mean, you firstly worry about data and have a way to represent that. That data only been the “actors” state and position in the game. Nothing graphics related. Nothing to do with how they interact. This is the “model”.
You then have completely separate code that can move those actors around by changing the values in the model. This will include state changes like collisions. No graphics involved.
You then have separate code that draws the actors in the model based on their state.
It isn’t obvious to many but this allows you to concentrate on the various areas that need coding. It also allows you to, say, easily change parts of the code as needs be.
• Game Development Essentials: An Introduction (3rd Edition) • Game Interface Design (2nd Edition • Mobile Game Development • Game Industry Career Guide • Game QA & Testing • Game Audio Development • Game Level Design • Online Game Development • Gameplay Mechanics • Game Simulation Development • Game Artificial Intelligence • Game Project Management • Game Story & Character Development
• Game Development Essentials: An Introduction (3rd Edition) • Game Interface Design (2nd Edition • Mobile Game Development • Game Industry Career Guide • Game QA & Testing • Game Audio Development • Game Level Design • Online Game Development • Gameplay Mechanics • Game Simulation Development • Game Artificial Intelligence • Game Project Management • Game Story & Character Development
Care was taken to ensure his website would remain active, and it's heart-warming to see that people are still finding it useful.
Johannes Marinus Paulus van Waveren was absolutely brilliant and the kind of person who left a lasting impression on those who knew him. He is sorely missed.
It has been recently published (April 2023) and not yet in any lists.