Creating a Project

This might sound a little hokey but every project I work on has its own code word. I picked this up from Microsoft and I love it. You should let your project team choose the code word, but try to make sure that the name chosen is somewhat cryptic. It's actually really convenient if you end up at the bar with a bunch of software developers from other companies. You can talk all day about finishing a build for "Slickrock" or that "Rainman" needs another programmer. Cloak and dagger aside, there's a real utilitarian reason to use short code words for projects.

The code word becomes the name for your top level directory. This is where all of your project files should be stored. Other files such as special build files or Visual Studio.NET SLN files should also be named using the code word. If you follow this standard, you can write one build script for your whole project, even if you have multiple projects taking place simultaneously.

Beyond that, a code word for a project has one other use: If you end up making multiple versions of the same product, you can use different code words to refer to them instead of version numbers. You are ready to start your project: choose a code word and create your top level directory. May whatever Gods you believe in have mercy on your soul:

 mkdir <codeword>. 

Creating a Bullet-Proof Directory Structure

Over the years of developing complex projects, I've experimented with different directory structures trying to find the ideal structure that will work with most projects. I've learned that it is important to have a good working directory structure from the start. It will help you work your way through all of the stages of developing a project—from writing your first lines of source code to testing and debugging your project. You also need to keep in mind that you'll likely need to share aspects of your project with others during the development process even if you are the only one writing all of the source code. For example, you might need to hire an independent testing team to work over your game. If you organize your project well, you'll be able to share files when you need to.

Keeping all of this in mind, here's my recommended directory structure where you should store each project you develop, including your game engine:

  • Docs

  • Source

  • Obj

  • Bin

  • Test

The Docs directory is a reference for the development team. It should have an organized hierarchy to store both design documents and technical specifications. I always put a copy of the contract exhibits and milestone acceptance criteria for my team, since these documents specify our obligations to the publisher. (You don't want to ever forget who is paying the bills!) While I'm developing a project, it's not unusual to find detailed character scripts, initial user interface designs, and other works in progress in the Docs directory.

The source code lives in the Source directory. It should be organized by the programmers in whatever manner they see fit. The project's solution file or makefile should also reside in the Source directory, and be named according to the code word for the project. The rest of the source code should be organized into other directories below Source.

When a project is being built, each build target will place temporary files into the Obj directory. On most projects you'll have at least a Debug directory to hold the debug build and a Release directory to hold the release build. You may have other build targets, and if you do, put them in their own directory.

Best Practice

Visual Studio.NET does a really bad thing by assuming that software engineers want their build targets to clutter up the Source directory. I find this annoying, since I don't want a single byte of the Source directory to change when I build my project. Why, you ask? First, I like to be able to copy the entire Source directory for publishing or backup without worrying about large temporary files. Secondly, I can compare two different Source directories from version to version to see only the deltas in the source code, instead of wading through hundreds of useless OBJ, SBR, and other files. Thirdly, I know I can always delete the Obj directory to force a new build of the entire project. I also know that I never have to backup or publish the Obj directory.

The Bin directory should hold the release build and every game data file that is used to create your project. You should be able to send the contents of the Bin directory to a separate testing group or to someone in the press, and they'd have everything they would need to run and test the game. You also want to ensure that they don't get anything you want to keep to yourself, such as confidential project documentation or your crown jewels - the source code. If you take the time to set up a directory that stores the files that you may be providing to others from time to time, you'll likely avoid sending out your source code or internal project design documents.

The Test directory should hold the debug target of the game, and special files only for the test team. It usually contains test scripts, files that unlock cheats, and test utilities. Most importantly, it should contain the release notes for the latest build. The release notes are a list of features that work, or don't work in the latest build. They also contain quick instructions about anything the test team needs to know, such as how to expose a certain feature or a part of your game that needs special attention. As you are developing your project, I strongly encourage you to keep the release notes up to date. If you hand your game over to a testing team they won't have to pull out their hair trying to figure out how to get your project to work.

You'll discover that Visual Studio.NET doesn't like this directory structure very much, and it's a pain to create projects under this standard. VS.NET assumes that everything in the project lives underneath the directory that stores the solution file. It may be a pain to get VS.NET to conform to this structure but trust me it is worth it.

The directory structure is useful because it caters to all the different people and groups that need access to your game development files. The development team gets access to the whole thing. Executives and press looking for the odd demo can copy the Bin directory whenever they want. The test group grabs Bin and Test and they have everything they need. The Docs directory grows quickly, so separating it from Bin, Test, and Source helps you manage the size of your builds if you must FTP them to someone like Microsoft.

If you store the build targets in the Source directory, like Visual Studio.NET wants you to, you'll have to write complicated batch files to extract the build target, clean temporary files, and match game data with executables. Those batch files are a pain to maintain, and are a frequent source of bad builds. If you pound VS.NET for a little while to get a better directory structure started, you won't have to worry about a nasty batch file during the life of your product.

The files stored in the top level are helper batch files or scripts for the automatic build software. One of these helper files copies the right directories depending on who needs them, a batch file called updaterelease.bat.

 @echo off :: UpdateRelease.bat ::=============================================== if '%1'=='' goto usage if '%2'=='' goto usage echo Updating %1 :: Remove and recreate the desintation directory rd /s /q "%1" md "%1" :: Call parallel batch file for the game engine cd ..\Engine call updaterelease %1 %2 :: Set project by the code word set PROJECT=Jokerz cd ..\%PROJECT% if '%2'=='test' goto test if '%2'=='bin' goto bin goto usage :test :: ————————————————————————— :: This copies all the files needed for testing: ::   Source tree - all the source code ::   Obj tree - symbol files and map files ::   Test tree - testing scripts, debug exes, etc. :: echo d | xcopy Source "%1\%PROJECT%\Source" /s/e echo d | xcopy Obj "%1\%PROJECT%\Obj" /s/e echo d | xcopy Test "%1\%PROJECT%\Test" /s/e rem NOTE THERE IS NO GOTO - IT FALLS THROUGH TO THE :bin label rem rem NOTE We don't copy the Docs directory - it's way too big!!! :bin :: ------------------------- :: This copies the Bin directory :: echo d | xcopy Bin "%1\%PROJECT%\Bin" /s/e :nuke ::------------------------- :: This deletes intermediate or temporary files, :: if they were copied :: del /s/q %1\*.scc %1\*.obj %1\*.sbr %1\*.ilk %1\*.pch :: ------------------------- :: Make a file inventory dir %1 /s > %1\FileList.txt echo Done updating %1. SET PROJECT= set errorlevel=0 goto exit :usage rem —————————————————— echo ================================================================= echo Usage - updaterelease [target directory] { test bin } echo    test:  copies Source, Obj, Test, Bin, Engine echo    bin:   copies Bin echo    All commands will remove SCC, OBJ, SBR, ILK, and PCH files. echo ================================================================= set errorlevel=1 :exit 

Our nightly builds for the Jokerz project were stored in S:\Nightly\Jokerz, a spot on our network. When the nightly build is completed the automatic scripts call the batch file and the files are copied:

 updaterelease S:\Nightly\Jokerz test 

Where to Put Your Game Engine

In case it wasn't clear, your game engine should get its own directory, with the same directory structure in parallel with your game. It should get its own updaterelease.bat file. On one project I worked on, our game engine had a terrible code name: Engine. It was stored in an Engine directory with Source, Docs, Obj, and Lib instead of Bin. There was some debate about separating the include files into an Inc directory at the top level. That's a winner of an idea because it allows the game engine to be published with only the include files and the library. The source code would remain safely in our hands.

Setting Visual Studio Build Options

I mentioned that you have to coax Visual Studio.NET to move its intermediate and output files outside the directory that stores the solution file. In the project settings dialog (or project properties in .NET) you set the output directory and intermediate directory to ..\Obj\Debug for the debug build and ..\Obj\Release for the release build. Plenty of temporary files are stored in the output directory—the precompiled header file, browser files, and other garbage. Put these files in the Obj directory tree to keep the Bin and Test directories free of these files. The executable is placed in the right spot by setting the output file of the linker.

Under the linker settings, you set the output file name to..\Test\MyGamed.exe for the debug build and ..\Bin\MyGame.exe for the release build.

Best Practice

You can distinguish the debug and release files by adding a 'd' to the end of any final build target. If for any reason the files need to coexist in the same directory you don't have to worry about copying them or creating temporary names. Both executables can still find source code in ..\Source, and debug symbols in ..\Obj\Debug or ..\Obj\Release.

With the target directories set right, Visual Studio.NET has some macros you can use in your project settings.

  • $(IntDir): The path to intermediate files

  • $(OutDir): The path to the output directory (..\Bin\ or ..\Test\)

  • $(TargetDir): The path to the primary output file

  • $(TargetName): The name of the primary output file of the build without the extension

  • $(TargetPath): The fully qualified path and filename for the output file

Use these macros for the following settings:

  • Debugging / Debugging Command: $(TargetPath) will call the right executable for each build target

  • Debugging / Working Directory: Should always be ..\Bin. It works with all build targets

  • C/C++ / Precompiled Headers / Precompiled Header File: $(IntDir)$(TargetName).pch

  • C/C++ / Output Files: $(IntDir) for the ASM list location, object file name, and program database file name

  • C/C++ / Browse Information / Browse Files: $(IntDir)

  • Linker / Debug Settings / Generate Program Database File: $(IntDir)$(TargetName).pdb

  • Linker / Debug Settings / Map File: $(IntDir)$(TargetName).map


There are plenty of third-party tools that work with Visual Studio. Most of them make the same assumptions about project default directories that Visual Studio does. They'll still work with my suggested directory structure but you'll have to tweak the search directories for source code and symbol files.

Best Practice

The macros also help to keep the differences between the build targets to a minimum. For example, $(IntDir) can stand for ..\Obj\Debug or ..\Obj\Release because they are the same in all build targets and they don't disappear when you choose "All Configurations" in the project settings dialog.

Building Configurations

Every project should have two build targets at a minimum: debug and release. The release build will enable optimizations and remove symbols and other debug information. You could create another release build target, one that enables debugging symbols, but I'd advise against it. It's relatively rare to have to debug into a release build and it's easy enough to enable debugging a release build on someone's development machine and recompile. A separate build target bloats the build process.

Best Practice

Try to keep all your build targets alive and working every day. If you ignore any build configuration, especially the release build, it could take a very long time to figure out why it's not working properly.

Game Coding Complete
Game Coding Complete
ISBN: 1932111751
EAN: 2147483647
Year: 2003
Pages: 139 © 2008-2017.
If you may any questions please contact us: