Last week I did an informal poll to see how many people could run the game. The failure rate hovered around 4%, which is pretty bad. Bad enough that I don’t think it would be a good idea to put the game up for sale. If 1,000 people bought it, I’d end up with 40 people who paid for a game that didn’t work. And when they emailed me asking for help, I wouldn’t be able to do anything but shrug.
In the old days, Windows would give you quasi-helpful error messages like, “Unable to load foo.dll”. It wouldn’t tell you why. Is foo.dll missing? Or corrupted? Or does it depend on some other thing that the user doesn’t have? Is it for a newer / older version of Windows? You don’t know. But at least you know the problem is with foo.dll, so when the user sends you the bug report you know where to look.
But these newer versions of Windows don’t like to confuse the peasants with things like information, and so now Windows spits out a generic “This program can’t do the thing.” message. Great. Now the user enters the useless error message into Google and gets back a million different possible causes. They don’t know what the problem is or where to look. More importantly, neither does the developer.
All I know is that for some people, one of the many DLL files I depend on isn’t available. Or it is available, but it’s the wrong version. I included all the DLLs I know about with the program, but for some reason some things appear to be missing or incompatible. What I have figured out:
- Windows version doesn’t have anything to do with it.
- 32bit vs. 64bit seems to be irrelevant.
One of my problems is that I have no experience with deployment. In all the years I spent writing software professionally, I never had to package the software up for the end user. I was either writing in-house tools for myself and my colleagues, or I was adding to an existing codebase where someone else was in charge of deployment. (Also, most of my professional work was a decade ago, and I think deployment has gotten more complex since then.)
Let’s look at the parts of this game…
I program at a pretty raw level. I write stuff in C++ and I don’t use big fancy game engines. In programming, we call this “working close to the metal”. Well, it depends on who you’re talking to. It’s all a mater of degrees. To some people, C++ and a bunch of libraries isn’t anywhere NEAR the metal. The guy who wrote Rollercoaster Tycoon in assembly? Yeah. THAT guy was close to the metal. In any case, if you’re close to the metal then you’re down in the guts of the machine, managing memory and manually handling tasks that would be automated in more robust systems.
But even down here close to the metal, there are still things I don’t want to do manually. And so I depend on external tools. I depend on software written by other people to get things done, because some problems are tedious and the solution fits nicely into a black box. For example:
I use SDL for talking to the operating system. It lets me create a window, get keyboard and mouse input, and figure out what joysticks might be connected. This would normally take thousands of lines of messy code, all of which would be linked to just one specific operating system. (Windows, OSX, or Linux.) If I wanted to support other operating systems, I’d need to write alternate versions of those thousands of lines of code.
But SDL puts all of this interface crap into a black box. In my program, it takes just 300 lines of code to get the job done, and that code will talk to any of the big 3 operating systems.
This is where I get really close to the metal. The vast majority of developers out there have some sort of graphics engine (or even a game engine) for talking to the graphics hardware. For example, you might use Unity or Unreal Engine to talk to OpenGL, which talks to the graphics card. But I prefer to talk to OpenGL directly.
Normally loading PNG images is this enormous task. It’s a complex format and it normally would require thousands of lines of code to properly support all the different types of PNGs out there. But DevILDEVeloper Image Library. The author wanted to call it OpenIL but the OpenGL folks complained because they were worried people would think that OpenIL was part of OpenGL. lets me reduce that to a single line of code.
“Here is a PNG file loaded into memory. Figure it out, and give me back the raw rectangle of pixels.”
Open Audio Library. It loads .wav files, plays sound effects, and can even handle things like positional audio and such.
Font loading is an insanely complex task. Fonts themselves are a really complex file format. Turning a font into a series of readable characters of the desired size is even worse. Without Freetype, I wouldn’t be able to load fonts and so I’d be stuck making text-less games.
Well, I could also use bitmap fonts, where you just stick a bunch of letters onto a single image. That’s a very hack-y solution that doesn’t scale well to different displays. You can use bitmap fonts if you’re going to a retro feel with giant chunky pixels, but if readability is important then you need to use proper fonts.
Visual C++ Redistrubutable
If you develop using Visual C, then the user will need some redistributable file. I’m sure you remember hitting “install” on a Steam game and it sits there downloading (even though the game package is already downloaded) and installing “Visual C++ Redistributable Package xxxxx”. There are a million of these stupid things, and I’ve never figured out how you’re supposed to figure out which ones your program needs.
One of these tools is broken. Sometimes. For some people. On some versions of Windows. For unknown reasons. Something is missing.
My first suspect is the Visual C stuff. Maybe there’s some redistributable package that some people have and other people don’t.
My second suspect is the audio Library. I’m using a SUPER old version of it. Everyone tells you that you MUST upgrade the old version because it’s terrible and it sucks and you’re a bad person for using it. But the new version doesn’t have a tool to load WAV files. And without the ability to load WAV files, what’s the point? I really need that and I really don’t have the time or desire to figure out how that worksOr to shop around for an existing solution that won’t add yet ANOTHER library to my project, or bloat the project with a dozen WAV-loading source files, or be encumbered by some stupid licensing, or require yet another library, etc.. Doing that properly would be a big job, just to get back to where I am right now. And since the audio works, I don’t have a lot of incentive to go to all that trouble.
Shamus, Why Don’t You…
I know how you are, internet. You want me to use that one tool that will solve all my problems. Which just so happens to be your favorite tool.
C# people think I should drop what I’m doing, learn C#, then translate my entire game to that.
Unity fans think I should drop what I’m doing, learn Unity, then translate my entire game to that.
Python people think I should drop what I’m doing, learn Python, then translate my entire game to that.
And so on.
But I’ve been doing this long enough to know just how insanely expensive it is to learn a new system. I have ten people all promising me that my life will improve if I abandon my years of experience and spend weeks or months painstakingly crawling up a new learning curve. Maybe one of those people is right. There’s no way to know which one. I could spend weeks teaching myself something new (and thus not getting anything useful done) only to discover some awful restriction or limitation that I just can’t tolerate. Or maybe I’ll discover a different problem, just as big and as annoying as the distribution problems I was running away from in C++.
This is an interesting project. I’m glad I’m doing this with something simple. Hopefully I can figure out this deployment stuff and get the game up for sale. I’m thinking of doing a short Early Access period just to catch all the bugs, basically using you folks as my playtesters.
 DEVeloper Image Library. The author wanted to call it OpenIL but the OpenGL folks complained because they were worried people would think that OpenIL was part of OpenGL.
 Or to shop around for an existing solution that won’t add yet ANOTHER library to my project, or bloat the project with a dozen WAV-loading source files, or be encumbered by some stupid licensing, or require yet another library, etc.
The Best of 2011
My picks for what was important, awesome, or worth talking about in 2011.
Batman v. Superman Wasn't All Bad
It's not a good movie, but it was made with good intentions and if you look closely you can find a few interesting ideas.
Games and the Fear of Death
Why killing you might be the least scary thing a game can do.
Trashing the Heap
What does it mean when a program crashes, and why does it happen?
The product of fandom run unchecked, this novel began as a short story and grew into something of a cult hit.