NightStalker - by Menelaos Levas & Ioannis Zapitis Building and Running the game To build the game simply copy NightStalker.c, sound.c, sound.h, and Makefile as well as the graphics and audio directories into a single directory and type make. To run, simply type NightStalker. The game runs on SG Octane. Computer graphics techniques As far as requirements go, the game implements a single texture map, (so that the requirement is satisfied) hardwired into the code, but makes very little use of it, due to performance considerations. Lighting and shading is used only on the people. Since the background and the light source is fixed, there was no need to compromise performance to calculate light information for the walls etc, although smooth polygon filling was used sparsely to yield a pseudo lighting effect (which is particularly visible in dark doorways). To reproduce the dark grimy night feel of the setting, fogging was used with fog color set to black. Fogging also helps with occlusion culling. Special effort was paid in designing a solid, noir atmosphere for the game's setting rather than just picking inconsistent, bright colors to make the game's world more aesthetically pleasing. Five additional techniques were implemented for the game: Collision detection At the geometric level, collision detection is fairly simple, and consists of bounding rectangles that limit were the camera position can move. This way, the player cannot walk through walls. Bounding rectangle data are read from the bounds text file. At the framebuffer level, a more sophisticated mechanism is used. Enemy targetting is carried out using the back buffer as described in Chapter 14 of the OpenGL programming guide. People are drawn on the back buffer using a single color, unique for each person, with fogging, dithering and smooth shading disabled. Then the color of the pixel at the point were the player shoots is sampled, and the person that has that color (0 if no person is picked) dies. This occurs after z-buffering so the person in front is the one that gets shot. In order for this technique to run quickly, the scissor test is used to limit the back buffer rendering into a single pixel (were the player fires). This way, firing hardly slows down the game even though more work happens in the background. Furthermore, since only a single pixel is actually written, the backbuffer and z-buffer need not be cleared for the next frame rendering (the dirty pixel is under the crosshairs anyway). If any obstacles exist in the scene, they need to be rendered as well, as they may obscure the person being targetted. These were hardwired in the code due to lack of time but they could have easily been implemented in a more modular manner. On-screen control panel The game uses a simple HUD to show the targetting crosshairs and a life indicator, which turns red if life begins to run low. Other information such as game over, game completion and don't kill innocents are also prompted as required. Text is drawn using GLUT's provided functionality and the crosshairs are rendered under orthographic projection. Sound was more of an afterthought but still, a very important addition to the gameplay (being able to hear when you get shot is vital). Our sound routine, simply modifies the simple example provided to work in plain C. There is a different sound effect when the player and when the enemies shoot (very subtle but very important), and one of three scream effects is picked at random, whenever someone dies. Occlusion culling Since the background is static, what the player can see when he/she is at a specific location can be determined as the backgroung is designed. Thus occlusion culling goes hand in hand with the hierarchical scene graph, described below. Hierarchical Scene Graph The most complex feature of the game is the hierarchical structure, which makes it possible to build objects, and then use them to build an entire world hierarchically. The objects are defined by means of a simple scripting language called 2dl (display list description language) which compiles text documents into hierarchical OpenGL display lists. A simple program called 2DLViewer was also designed, which reads in 2dl text files and displays the object defined, enabling the user to rotate it around. (to use simply type 2DLViewer FILENAME) The game reads in two 2dl files. One of them defines a huge number of objects, both generic and specific instances at certain locations in the game world. The second file defines the domains of the game. Each domain calls on the objects loaded from the objects file, to actually draw the scene. This way, when the player is within a specific domain, only the objects called by that domain are drawn (see occlusion culling above). The people are also build hierarchically although their vertex and normal data were hardwired into the code (instancing and assigning colors etc occurs through the bounds text file though). By grouping the body, arms and legs in a suitable hierarchy, it is possible to demonstrate very nice animation when they raise their arms to shoot you or to surrender or when they are killed. Game content An important design choice was not to use any ready made content for any part of the game. All the objects that are seen in the game were all created with 2dl and a lot of effort. The humans were created vertex by vertex and normal by normal. The sound effects were also home made using a PC and a simple microphone. The only content that was obtained was the newspaper texture map which was grabbed from the web site of a newspaper were the front page is displayed (http://www.simerini.com.cy, the website is in greek and so it will appear messed up if the proper font/document encoding combination is not used)