People have been asking me about Vulkan. Maybe you’ve seen it in the gaming news: Vulkan is coming! Vulkan is the next big thing! Developers are excited about Vulkan! Being a naturally curious gamer, you want to know what this new thing is and what it means. So you look it up, and you find something to the effect of:
Vulkan is a graphics and compute API from Kronos Group that provides high-efficiency, cross-platform access to modern GPU.
It’s a definition that explains one thing you don’t know in terms of half a dozen other words you don’t know. All you know is that it has something to do with graphics, and figuring out what this is and why it’s happening is starting to look like more trouble than it’s worth.
Sorry about that. We programmers are really bad at explaining things. We over-use jargon and are generally bad at adjusting explanations for non-technical people. But you’re in luck. While all the other programmers are min-maxers who dumped their skill points into logic and mathematics or whatever, I actually snuck a few points into communication skills. So I think I can untangle this for you.
But we are going to need just a little bit of jargon. Going back to that original definition of Vulkan, there’s at least one mystery term we need to sort out. That’s this one:
You don’t actually need to know what this stands for. It doesn’t matter. It’s just an acronym of more jargon”Application Programming Interface”. See? Not very interesting., and if we try to define those terms then we’ll end up needing to define other terms and we’d be here all day. For our purposes, API is just a tool. Or actually it’s a way of using a tool made by other programmers.
See, back in the day – and I mean WAY back in the day – back in the days of big iron, mainframes, and punch cards – back when I was just a wee baby Shamus – most projects were written from scratch. You need to sort a list of stuff in alphabetical order, or handle something the user typed, or print something out? You just sit down and hammer it out yourself. It’s not like you could go on the internet and ask for help. The web didn’t exist yet.
But as time went on, things began to get complicated. So maybe a game developer is working on sound code. In the early days, it’s easy. You just write a little code to have the speaker blurt out one sound. But as the years go on, and games become more complex, you sometimes need to layer many sounds together. And you need sounds to pan between left / right speakers so the player can tell where that monster is coming from. Distance attenuation. Surround sound. Doppler effects. Reverb.
Eventually our hard-working programmer will think to themselves, “Gosh. It sure is a lot of work to add all of these features to my sound code. Hang on. I’m obviously not the first person to write something like this. Lots of other people must have written sound code. Maybe I can use their solution instead of writing my own, and I’ll be able to spend more time working on the game parts of my videogame.” So they go out and see if anyone else has already solved the problem and is willing to share.
Sometimes a programmer will share their solution out of the kindness of their heart. Sometimes they charge money for it. In any case, when a programmer bundles a bunch of code like this for other people to use, it’s called a library. You can think of a library as a black box. You know what it does and how to use it, but you have no idea how it works inside. You can find out if you want, of course. Assuming you’ve got the source code, you can just read it to see how the library works inside. But to a certain extent this would defeat the purpose of using a library in the first place. You don’t want to have to worry about reading someone else’s code. You just want to plug it in and have it work.
So API is how your program talks to this library. It is the control panel by which you manipulate what’s going on inside the black box. Maybe this sound library has a function to begin a new sound or set the volume of the sound effects. But if for some reason the programmer that made the library forgot to add a function to lower the volume, then you wouldn’t be able to do that. Which would kind of make this particular library useless.
The programmers out there are likely freaking out by this point because I’m being sloppy with terms and making broad over-simplifications. But I’m okay with that. This need for precision at all times is one of the reasons they’re sometimes bad at explaining things to non-coders.
There is a certain art to making a good API. You want the controls to be as simple as possible without taking away functionality. A well-designed library should be obvious to use and shouldn’t require you to worry about any messy details of what might be going on inside of that black box.
When you’re using a toaster, you don’t care about the voltage the device is using, the temperature of the heating coils, or the specific electrical resistance being used by the heating elements. You just know you want your toast to be medium. If a toaster forced you to worry about all those details, then the controls would be too complicated. If it just had an on and off button with no way to choose how dark to make the toast, then it would be too simple. A good API should be designed to hit that sweet spot between complexity and features, and it should gracefully hide everything you don’t need to worry about.
But Vulkan isn’t a sound library, and you’ve hopefully already figured out that it’s not a toaster. It’s a graphics library. So now it’s time to talk about just one more bit of jargon:
If you’ve done any PC gaming over the years, you’ve probably heard the term OpenGL, even if you didn’t know what it was or why you should care.
OpenGL stands for Open Graphics Library. It’s a library for making graphics happen. It’s one of only two libraries that can accomplish this. Any game made in the last 20 years or so is going to use either DirectX or OpenGL to draw polygons using your graphics cardYes, there are occasionally obscure examples that don’t use either, but let’s keep this simple.. I don’t care if the game looks like Crysis or Minecraft, somewhere between the game and the stuff that shows up on your monitor, you’ve got either DirectX or OpenGL making those visuals happen. At least, on personal computers. Let’s leave consoles out for now, since that’s another whole can of worms.
The problem with DirectX is that it was created by Microsoft and they decide where it will be available, which tends to be limited to Microsoft devices.
But now you’re asking, “Shamus, what about game engines like Unity, Frostbite, or the Unreal Engine?”
Well, I was hoping you wouldn’t bring this up, but now you’ve forced my hand. Graphics libraries are complicated. So complicated that it’s tempting to take the black box and stick it inside of another box to hide away some of the complexity. If you were to open up the black box of a modern game engine, you’d find they contain either OpenGL or DirectX. Or even both.
Game » Engine » OpenGL » GFX Driver » GFX Card » Monitor » YOUR AMAZED EYEBALLS
OpenGL dates all the way back to 1991. You may notice that this is several years before the first consumer-level graphics cards appeared. I know it’s strange to think about today, but there was a time when games didn’t require special graphics hardware. Games drew their simple graphics using nothing more than the processor that was already busy running the rest of the computer. As you can imagine, this was pretty slow.
Rendering graphics was very different in 1991 than it is today. Few games did 3D graphics, and those that did probably relied on flat-color polygons with no lighting effects. Over the years we’ve introduced texture maps, transparency, lighting, fog, shadows, specular effects, bump mapping, god rays, subsurface scattering, refraction, ambient occlusion, depth of field, motion blur, and dozens of other things. OpenGL grew in complexity as we came up with newer, better, faster ways of drawing things.
More importantly, we keep adding more and more processors to graphics cards, which means they can draw more things at the same time. If you’ve got a kitchen with one chef, it doesn’t matter how you send him the orders, since he can only do one at a time. But if you have fifty chefs then you can theoretically prepare things fifty times faster, but only if you can organize them so the entire group is always busy. So a lot of changes have been made to OpenGL to keep your graphics card as busy as possible. But this means changing the entire way you approach rendering. To do that, the authors of OpenGL needed to add a lot more buttons to the outside of the OpenGL black box. Every few years there was a new gizmo added on, a new way of doing things.
The trick is that you don’t want to remove the old things from OpenGL. You need to leave them there because some people are still using them. Sure, a modern AAA game should not be using the old ways, but OpenGL isn’t just used by AAA studios. It’s used by hobby projects, retro games, old engines, educational projects, and non-game applications like CAD and such. There’s a whole world of different projects out there who use the old bits of OpenGL because they’re so much simpler than the new ways, and because performance isn’t a priority for them.
But adding to a system like this causes a new problem, which is…
To explain this, I’m going to have to resort to the time-honored tradition of the terrible car analogy. Let’s imagine there’s this car that’s been modernized over the years. Instead of making a whole new model every few years, they took the existing model and added new stuff to it without ever taking anything away. It began as a Ford Model T in 1908 and they tinkered with it until it had all the capabilities of a fully loaded 2016 Ford Fusion. But like I said above, you can’t remove the old stuff.
So our 2016 Ford Fusion still has that 1908 crank on the front to start the engine. But it’s also got a push-button on the dash that does the same thing. Or you can use the ignition key. Or the remote starter. Or the phone app, but only if you’ve already enabled the Bluetooth systems.
In the 30’s they added an AM radio. In the 1950’s they added another radio that did both AM and FM. A CB was added in the 70’s, along with an 8-track player. Then in the 80’s we got another AM/FM radio, plus a cassette player. A car phone. A CD player. Satellite radio. USB music player. A GPS.
It still has the original kerosene engine in the trunk, and then a gasoline engine under the hood, which can be switched between using leaded and unleaded gas using some levers that are hard to find and confusingly labeled. Or you can use the electric engine. Or you can run in hybrid mode, although hybrid mode only works with the unleaded version of the gasoline engine. That fact isn’t documented, because “everyone knows it”.
The windows still have the old crank controls, but also electric control, although if you switch between the two systems it will get stuck and you won’t be able to close it all the way.
There’s a shifter for the original engine to the left of the driver’s seat, then controls for the automatic transmission on the steering column, then a manual transmission to the right. There are three different sets of headlights, two different sets of turn signals, and five different gauges for reporting the status of the three different gas tanks you have connected to your two different engines.
Try to picture this car in your mind. The controls would be horrendous. There would be so many levers, switches, knobs, and buttons for all of these different systems from all of these various time periods. It would look like some kind of steampunk space shuttle. There would be six ways to do everything and dozens of different, conflicting versions of the user’s manual.
Even if all you want to do is a very simple task – like driving to the store without crashing or breaking any traffic laws – you’ll likely have to deal with all sorts of confusing frustrations as you struggle to figure out which of the half-dozen similarly labeled things actually does the thing you need to do. The interface has become confusing and there are lots of systems – like the old-time AM radio – that nobody wants or needs and that only serve to confuse you when you’re looking for something else.
When a piece of software is under development long enough, this kind of thing tends to happen. When it does, the extraneous stuff is called cruft. OpenGL has accumulated a lot of cruft over the years.
Cruft is a bad thing, but in a strange way it’s also a mark of distinction. OpenGL only got this crufty because it’s been so useful for so long. Most software libraries don’t survive for a quarter century, and it’s to the credit of OpenGL that so many people found it so indispensable for all these years.
It’s not just the software that acquires cruft. The documentation does, too. You’ll find a tutorial saying, “NOTICE! Don’t use (this old system) anymore! From now on, you should use (some other system that’s not nearly as well documented) at ALL TIMES!” This tutorial doesn’t have a date on it, but it’s actually from 2004. It’s all outdated and the “new” way it talks about is now terrible and wrong, because there’s something even newer you should be using. The well of documentation is poisoned, and a generation of young coders are busy soaking up bad habits and destructive advice.
But cruft isn’t just an annoying headache for coders. It’s actually really bad for our games. Because…
Simplicity is Stability
In an ideal world, programs would fall neatly into one of two categories: Either it’s Totally Wrong and it doesn’t work at all, or it’s Totally Correct and it works flawlessly. But there’s a third option that’s actually far worse than being wrong and broken, which is being Nearly Correct.
Nearly Correct is bad because to our programmer it looks indistinguishable from Totally Correct. The programmer moves on, assuming their software works. But because it’s not Totally Correct, it will exhibit problems. Maybe it will run slower than it should. Maybe it will have occasional, inexplicable visual glitches. Maybe it will crash, but only on some systems and in some rare circumstances.
As an API accumulates cruft, the number of “Nearly Correct” solutions increases. More solutions fall into the dangerous “Nearly Correct” zone. It’s easier to create bugs, harder to detect them, much harder to track them down, and impossible to be 100% certain that you’ve done things properly. Each new layer of features brings with it a new layer of confusion and uncertainty.
Now, the obvious solution is to just remove those old controls. Get rid of that old AM radio. And that CB? Who uses those these days? But the problem is that some programmers actually do use the old stuff. They shouldn’t. You’re only supposed to use the most recent features. But programmers don’t want to have to re-write code that works. So then they won’t want to use the new versions of OpenGL, which would split the community and further complicate the documentation, which is already byzantine enough as it is.
So rather than tamper with the existing OpenGL controls, Vulkan is an attempt to wipe the slate clean. Kronos Group – the people behind OpenGL – have gotten rid of the cruft and designed a totally new set of controls for us to use. These controls are designed around the way you’re supposed to render things today, and aren’t hobbled by 1991 paradigms. Rather than trying to get everyone to update all of their old engines, those old engines can continue to use old OpenGL and they’ll work as well as they ever did.
Vulkan is for people making new engines. If it works out, games written under Vulkan will be a little faster and (we hope) less buggy. As of this writing, a few games have been made with it. (Notably Talos Principle, and DOTA.) The real test will come when the really big games start using it: Open world games, shooters, and “cinematic” games built around 3D spectacle.
So that’s Vulkan. You don’t need to worry about it unless it’s your job to worry about it, in which case you should probably get started worrying about it as soon as you can.
 ”Application Programming Interface”. See? Not very interesting.
 Yes, there are occasionally obscure examples that don’t use either, but let’s keep this simple.
Two minutes of fun at the expense of a badly-run theme park.
The Opportunity Crunch
No, brutal, soul-sucking, marriage-destroying crunch mode in game development isn't a privilege or an opportunity. It's idiocy.
id Software Coding Style
When the source code for Doom 3 was released, we got a look at some of the style conventions used by the developers. Here I analyze this style and explain what it all means.
A programming project where I set out to make a gigantic and complex world from simple data.
A look at the main Borderlands games. What works, what doesn't, and where the series can go from here.