Testing the Game
as a Whole
By this point your script should have gathered everything from source control and the network, carried out any processing, and have a basic game "footprint" image for testing out.
A good test to do is to copy the footprint into the Program Files directory and launch the game. You probably want to doctor the footprint a bit to put the game in a rolling demo or self test mode. In Creatures 3 we added script files to automatically load a world and hatch some Norns.
You can use Bash's job control to kill the game after 5 or 10 minutes when the test has completed.
echo Launching Creatures 3... cd //c/program\ files/Creatures\ 3/ # Note the ampersand on the next line, which launches # the game engine in the background. ./engine.exe& ENGINE_PID=$! echo -n Waiting 5 minutes to see if any errors are made... for TIME in 5 4 3 2 1; do echo -n $TIME.. sleep 1m if [ -f "$ERROR_FILE" ]; then error Full game test failed fi done echo ..doneThe Creatures 3 game engine always writes errors to a log file. This is to make it easier for testers and customers to report bugs or problems. It also makes it easy for the script to detect any problems. With the ecology in the game running, and the Norns playing about for ten minutes, we could be sure that the build worked. This guaranteed that our testers got something reasonably good to play with -- their time not wasted on overt errors.
# This uses the stored engine Process ID to terminate it kill -9 $ENGINE_P
At this point, Creatures 3 also used the game engine to generate a special asset for the build. The game featured a pre-generated Norn "starter family". They had to be constantly kept up to date with changes in genome and engine archive file format. As ever, the scripts took the strain.
The two parent Norns were automatically created during the self test. They were aged, taught all vocabulary, and allowed to walk round and play for a while. They were also encouraged to be friendly with each other so they would breed more easily on the players' machines. After this quick introduction to life, they were exported. The build script then copied them from the Program Files directory back to the build image.
The script does some extra checks at this stage. For example, it ensures that the female starter Norn doesn't actually get pregnant!
Numbering each build is a good idea. You can keep a file on the network with the last build number, and then increment it each build.
echo -n Incrementing build number...
echo -n from $BUILD_NUMBER...
BUILD_NUMBER=$((BUILD_NUMBER + 1))
echo -n to $BUILD_NUMBER...
echo $BUILD_NUMBER > "$BUILD_NUMBER_FILE"
The number can be displayed in game, and used to generate the network directory name where you copy the finished build.
Dancing with InstallShield
Creatures 3 used InstallShield for installation. This section of the build script doctors some of the configuration files, compiles the InstallShield scripts, and builds an installation. It then copies that and makes a CD Image on the build machine.
For the Internet-based sequel to Creatures 3, called Docking Station, we used our own custom installer. The build ran our own special compression scripts at this stage. It then uploaded the files to the internal web server for testing. With one command we can make a new build live to the general public.
It's bit fiddly calling InstallShield from the command line. You need to both Compile the scripts, and Isbuild the final image. All our file groups are set in dynamic mode in the IDE, so any new files are automatically pulled in.
PATH="//c/Program Files/InstallShield/InstallShield 5.5 Professional Edition/Program":$PATH
echo Compiling scripts...
Compile "InstallShield\Script Files\setup.rul" -i"InstallShield\Script Files;C:\Program Files\InstallShield\InstallShield 5.5 Professional Edition\Include" -v0 || error Compile
mkdir -p "CD Image/Install"
echo -n "Cab
# choose sourcefile by rewriting install shield input file
echo [DYNAMIC] > "InstallShield\File Groups\Source.fgl"
echo WILDCARD0=*.* >> "InstallShield\File Groups\Source.fgl"
echo INCLUDESUBDIR=YES >> "InstallShield\File Groups\Source.fgl"
echo FOLDER="$BUILD_PATH_WINDOWS/Source Data" >> "InstallShield\File Groups\Source.fgl"
echo >> "InstallShield\File Groups\Source.fgl"
echo [General] >> "InstallShield\File Groups\Source.fgl"
echo Type=FILELIST >> "InstallShield\File Groups\Source.fgl"
echo Version=1.10.000 >> "InstallShield\File Groups\Source.fgl"
rm -Rf "Temp"
isbuild -p"$BUILD_PATH_WINDOWS\InstallShield" -m"Default" -b"$BUILD_PATH_WINDOWS\Temp" || error isbuild
echo Copying data
to CD Image...
cp -R Temp/Disk\ Images/Disk1/* "CD Image/Install/"
rm -Rf "Temp"
Notice the lines that move InstallShield's completed files from /Disk1/ to the appropriate place in our CD Image. This is a great saving - before build scripts it was a real pain to have to manually move the files.
InstallShield's compression features aren't used, so the files are uncompressed on the CD. This makes it easy for people to check what was in a particular build, and also for users to retrieve corrupt files without a complete reinstallation. Customer support loves it too -- they can recommend a manual installation if a customer is having unforseen trouble with InstallShield.
Unfortunately you can't quickly patch a build by changing these uncompressed files. If the size of any file changes then you have to recompile from within InstallShield.
With the CD Image is complete, it can be manually tested on the build machine or installed directly from there to other machines.
The final stage is to copy the CD Image to the network. If the network was busy we found it could take twenty minutes to finish the copy. People often tried to install the image while it was incomplete.
To get round this problem of over-eager testers, Creatures 3 copies the build to a folder called "new build still being copied". When it has finished it renames it to the appropriate name, number and language. For example, "build 98 spanish".
The builds were all put in a standard "completed builds" directory on the network. This makes it very easy for people to find them.
In addition to copying the CD Image, it might be worth taking a back up of source code and scripts here as well. The completed build folder would then be a toolkit for remaking exactly the same build. Very useful for remasters, where someone wants the identical build but with minor modifications.
People like to know what is happening, and to feel in control. When the Creatures 3 build script finished its job it sent an email to a special mailing list on our mail server. This announced the new build, with a link to its location on the network.
To do this you will need a command line email program. There isn't one built into Windows, but you can find a list of some on WinFiles.com.
If there was an error in the build then a complete log of the script's output was sent to a developer on the team. He would then chase up the problem, fix it, and set a new build going.
It would be hard to overemphasise how important error handling is. The build needs to abort as soon as there is a problem. The default behaviour of Bash is to carry on blindly if you don't put in any error checking.
Every command line program returns an error code. This is 0 for success, or a number to indicate different types of failure. For example, diff returns 0 if no differences were found, 1 if there were differences, and 2 for an error (such as file not found).
You can automatically make the script stop if any simple command returns an error by using set.
If you're using pipes a lot you need to be slightly careful with this, as an error in the pipe isn't detected. The variable $? will be set with the return code of the last command in the pipe.
Logging error messages for emailing to a developer is a little tricky. The easiest way is probably to call your whole script from another script.
The outer script can pipe all output (stdout and stderr) to both the screen and a file using "tee". When it has finished it can check the error level. If it is greater than zero then the output log can be emailed to the appropriate person.
This example outer script from Creatures 3 takes a list of languages as parameters. For each one a function "go_build" is called with the language as a parameter. The function then runs the main build script "c3build" with the appropriate build stages, including the language.
# code to email /tmp/build.err to developer
./c3build prepare $1 check test compile commit || build_error}
rm -f /tmp/build.err
# run build, trapping messages for COMMAND in [email protected]; do go_build $COMMAND 2>&1 | tee /tmp/build.err done
Whenever there is an error, the contents of the log file are immediately emailed to the developer.