1. What is the best development environment for game programmers?
Obviously there’s no simple answer to this. It totally depends on the team, the project, the platform, the engine—all of those variables should be considered when choosing a development environment. For example, if you’re building a console game, you’re forced to use whatever toolset the hardware manufacturer dictates, supplemented by whatever hacks you can come up with to make your own favorite tools work. If you’re making a Mac game, forget about any Microsoft tools! And if you’re building a Flash game, then, well, you build things with Flash, unless you somehow turn OpenLaszlo into a game builder.
So let’s just say you’ve got a C++ engine and you’re on a PC platform, which is probably the case for most casual game developers due to the openness and ubiquity of the platform. The best environment here for game development is easily Visual Studio. It’s got a great compiler with useful C++ language extensions, .NET support for building tools fast, and the best debugger available anywhere. Although VS isn’t open like Eclipse or Emacs, and its add-ons (such as VisualAssist by WholeTomato—which I love) tend to cost money, out of the box it gets you moving fast making games. Longer term, it takes some time to learn how to deal with its odd quirks, particularly its GUI performance, but its great tools make it completely worth the effort.
The development environment is much bigger than just the tools you buy or download. It’s the entire ecosystem of tools, people, processes, standards, content pipelines, and whatever else goes into making a game. The “best” environment is one that lets a game design get expressed by developers into working features as quickly and as accurately as possible.
By “quickly” I mean that it allows you to get things into the game fast, that it shortens the time between thinking of an idea, creating it, and seeing it work in the game. Rapid iteration is key—the more ideas you can try out in a short amount of time the better. So here you’ll need tools like automation (for art exports and game builds), runtime compiling (dynamic scripting language or VC++ Edit & Continue), on-the-fly reloading of content, and a forgiving engine that isn’t strict about resources being perfect or missing. Get it written and working fast, and don’t worry so much about it being correct until later.
By “accurately” I mean that the environment knows when something isn’t right by verifying content as it loads, and that it tells the developer how to fix it easily with proper feedback. The game shouldn’t crash when something simple is wrong (such as spelling the name of an object wrong). Rather it should: (a) notice the problem and warn with useful info about how to fix it; and (b) do so loudly and in a way that the developer can’t miss the warning. A good assertion and logging system, combined with effective on-screen elements (such as error/warning counts that don’t go away) will work well here. This will save a huge amount of time and frustration, and keep engineers focused on writing more code and diagnosing fewer problems.
2. Can you provide an overview on how to debug a crash, a hang, and a lock?
The quick answer is: Go buy Debugging Applications for Microsoft .NET and Microsoft Windows by John Robbins and read it end to end. He walks through many scenarios and procedures for diagnosing crashes. This is a must-have book.
There are so many different problems that could happen in a game and so many tricks for diagnosing and resolving them that it would be impossible to cover them here, but I’ll touch on a few.
So let’s talk about crashes. First, find out whether or not it’s really a crash. Most people—even many developers—say “crash” for pretty much anything that goes wrong, from a simple error dialog coming up to a hung application to a Windows blue screen. In fact, a true crash is when the game has halted due to an illegal operation (like an access violation or stack overrun). So for starters, you should get confirmation that it really truly is a crash and not a game error. Confirm what type of issue it is for certain before starting to debug it or you’ll waste lots of time.
Most crashes can be diagnosed simply by looking at the call stack and registers and inspecting the crashing line of code. The top of the stack tells you what went wrong, and the rest of the stack tells you (usually) how you got there. The registers in debug builds can often tell you if you’re referencing a null pointer or a pointer to deleted or uninitialized memory (pointer registers holding 0xDDDDDDDD or 0xCDCDCDCD can be a telltale sign). A simple top-level exception handler can put up the stack (with symbols resolved from the PDB) and CPU registers on a crash, and 80% of the time an engineer can figure out at a glance what’s wrong without a lot of time wasted diagnosing the issue. More advanced diagnoses could involve using a crash dump so an engineer can do a postmortem analysis. Because it takes so much time, you should only do direct debugging (stepping through the code on the machine) as a last resort. Most of the time, though, you can figure out the issue by simple inspection.
The tough crashes happen when multiple threads are involved, or when there are “latent bugs.” In these cases, Something Bad happens but the crash does not happen immediately. These can be very difficult to debug and, aside from proactively putting integrity-check assertions all throughout the code (a best practice regardless), the only reliable way to catch such bugs is to periodically log the state of systems involved in the crash and review the log output after a crash, looking for clues—old-school “printf debugging.” There are many tricks for special cases, but there’s not enough space here to write about them all. Check John’s book!
For a “hang,” I assume we’re talking about temporary glitches, such as when performance is choppy or we have periodic freezes. This can be solved with an in-game profiler that shows the performance costs of different major systems over time, hopefully with a simple scrolling graph to catch historical data for hangs in different systems. You can usually guess what’s making it temporarily slow simply by observing what happens in the game. For example, a mouse click might cause a resource to load which makes the file system portion of the profiler spike temporarily. To get real data of course, resource monitors and call graph profilers can tell exactly what is going on.
And finally, the best approach to debugging a “lock” depends on the type of lock. If it’s a deadlock among threads, there are many published articles (including a good one by John Robbins) on how to figure these out using some easy changes to your thread sync classes. If the lock is caused by an infinite loop, with CPU at 100%, just break in with a debugger. Or if debugging on a non-developer system, a cheap way to diagnose the hang is to use a separate thread that watches for a certain key sequence such as Ctrl-Break (which you’d press when you notice a hang). Upon catching the lock, then, the sequence freezes all threads and shows a dialog with the stacks of each thread. Then the problem becomes very similar to debugging a crash. And finally, if the game appears locked but it’s not maxing out the CPU, it’s probably just the UI that’s not updating—possibly because it’s locked waiting for another thread or synchronous API call to finish. The hang-watchdog thread solution will work well here, or you can always break in with a debugger to see what the problem is. Locks are generally easy to figure out.
3. Does it matter what programming language I use?
It matters for a variety of reasons, some of which are: ease of hiring/contracting programmers to work on your game, ease of integration of third party libraries, performance considerations (CPU, memory usage, disk footprint), community support available, feature set, dynamic capabilities, and a million other things.
In some cases you aren’t given a choice. Make a Flash game and you must write code in Actionscript. Work in Unreal and you’ll be writing a lot of Unrealscript. Sometimes it’s the opposite: Choose a language and you force the engine. For example, if you want a C# game, you must force end users to install the gigantic .NET Runtime to play your game. Not a big deal for CD-based games, but download-only will suffer. Although I hear the static, .NET linkers are getting more compact every day. . . .
Practically, though, just about everybody works in C++ and for good reason: It’s about the best general-purpose, high-performance, widely supported language available. Nearly all engines these days are primarily written in C++, and many add a scripting language to support domain-specific features, provide runtime compiling, simpler programming, etc. Integrating and effectively using a scripting language in a C++ engine is no small task, so be very careful in this area. It’s very easy to drop a scripting language into a game engine so scripts can call C++ functions, but it’s a lot tougher to make the integration easy to maintain and understand—or to fit well with the engine architecture, for that matter.
4. How much time will I save by using an off-the-shelf engine solution?
Initially, a lot of time. It’s far faster to license an engine and build a game than to roll your own from scratch first. And without the right experience on hand to build that engine, you may end up with a difficult to maintain codebase that encourages hacks and buggy game coding while making it difficult add new features. It’s a lot of fun to build an engine and get something on the screen, but developing and maintaining engine technology is very different work from making games and isn’t a good strategic choice for every studio. In the end, a proprietary game engine may simply prove to be more trouble than it’s worth.
Also, every minute spent building, tweaking, bug-fixing, and extending a homebrew engine is a minute not spent on the game. It’s hard to justify working on the authoring tool when the GarageGames guys have done such a nice job on theirs and are constantly working on making it better. On the other hand, no engine is perfect, or perfectly suited to the game you’re making, or has the features you need for your team to make the best games possible. It’s also a risk to build your games on top of technology over which you have no direct control.
So there’s no easy answer to this. The good news is that it’s easy to change your mind later. Casual games aren’t super complex, so if a particular licensed game engine doesn’t work out so great, you can try another one in a few months!
5. Can you recommend any good scheduling software, bug trackers, or source control software?
I don’t know of any good scheduling software, but that’s ok—I’m not a producer! I do know that Microsoft Project is about the worst thing out there, except for everything else. If I ever schedule anything, though, it’s in Excel.
My favorite bug tracker is Jira by Atlassian. It’s cheap (cost is per-server, not per-seat), very customizable, has great tech support and a big lively community. What’s more, it is constantly updated with new features and extended with new plugins by Atlassian or third parties. For small budget studios, there are free alternatives such as Bugzilla. Although I haven’t used them myself, I’ve generally heard bad things about their usability for non-programmers. Atlassian also offers a great wiki called Confluence that I really like and we use heavily at my studio.
The game industry favorite for source control is easily Perforce. They just won another Front Line award from Game Developer magazine for being awesome. I’ve been using Perforce for about 5 years now and I wouldn’t switch (though I regularly check the competition). Perforce is fast, small, and has great integration support. I also like that it works well remotely and that it is so easy to script automation for it—and they’re even making their client GUI usable for non-programmers. The big problem is that Perforce is very, very expensive. Tight budgets should probably go with Subversion + TortoiseSVN.