Games would be dull and boring without multimedia programming. As human beings, we are very sensitive to animation, sound, and all the technical features that make a game attractive. Thus, coding a good game certainly involves being very careful with its presentation. You could argue that some really good games can be crafted with little or no presentation values, and you would be right. A game such as Tetris does not need much in terms of the audio-visual experience. But it is dangerous to generalize this as a rule. The vast majority of games require a carefully designed multimedia wrapper for the gameplay to become engaging and immersing. We need to see starships and asteroids to get the feeling of space flight, and we need carefully designed ambient sounds to really believe we are in a scary scenario.
The presentation layer helps convey one of the key features of good games the capability to provoke the willing suspension of disbelief. This happens when good movies, books, and games mentally immerse us in the scenario in which they take place. Take a good movie, for example. In the first 10 minutes, the viewer forgets about the real world. The viewer's job, problems, duties, and so on are simply gone, as he or she gives in to the magic of the narrative. The viewer spends the next hour or two immersed in the story. In fact, the viewer does not feel like he or she is in a movie theatre at all. It feels like he or she is chasing the bad guy, solving the mystery, and so on. That is what willing suspension of disbelief is all about.
Some movies try to tell compelling stories with minimum presentation values. The Dogma movement serves as a good example. Although this trend will undoubtedly emerge in video games as well, and many good games will be created, presentation will still be important for both Dogma and non-Dogma games. Dogma games do not trust the competence of human actors but instead need to resort to synthetic storytelling, which is rooted in technology. Because games are far more technology driven than movies, presentation is still necessary, even for a simple game.
On the other hand, let's not forget that the vast majority of games are produced for the masses, and in this context, presentation is essential. In addition to better gameplay, consumers request better graphics, more and better sound, and production values in a constant progression. It's a catch-22 situation that arises from the constant improvement of computer hardware. So, even in those games where game logic is top priority, you had better keep an eye on the presentation values to ensure that you reach a broad customer base.
Let's now explore the constituent parts of any multimedia pipeline. The focus will be given to graphics and sound as the two main factors in providing a top multimedia experience. Our generic pipeline will be similar to the one used for game logic and be divided into rendering the game world, rendering nonplayable characters, and rendering the player. Keep in mind that this is just a framework to illustrate the constituent parts and does not imply any order of execution. For implementation purposes, elements can be rendered in a different order.
The first step is to render, visually and sonically, the game world. Here we will focus on the passive elements of the world, such as walls and grounds, as well as the simple, logic-based devices such as opening doors. The line will be drawn between objects requiring little or no animation, which will be handled here, and fully animated objects, which will need a different processing scheme altogether.
Rendering complete game worlds in real-time is almost impossible except for simple games like Tetris. For any involved title, some filtering must be applied prior to the main render call to decide what should be taken into consideration and what shouldn't. For example, very distant or invisible zones of the world can probably be culled away because they provide little or no information to the player and would just decrease the frame rate due to the added complexity. So, any world-rendering pipeline will more or less consist of two parts: selecting the relevant subset and taking care of the actual rendering.
For the graphics pipeline, the selection routine is implemented via clipping, culling, and computing occlusions, so the resulting representation is just the visible part of the game world from the player's viewpoint. This way we can focus on drawing what actually matters to the player. These routines are the core of any modern-day graphics pipeline and will be analyzed in full in Chapter 12, "3D Pipeline Overview," Chapter 13, "Indoors Rendering," and Chapter 14, "Outdoors Algorithms." An optional, auxiliary process is sometimes applied to the visible data, which computes the relevance of the data and chooses a suitable level of detail to render it. A tree that is seen 500 meters away probably doesn't need 10,000 triangles because each triangle would occupy a tiny fraction of a single pixel. Thus, a low resolution, more efficient representation can be used instead without the detrimental effect on performance.
Now that world geometry has been reduced to the visible part and assigned a suitable level of detail, it is time to actually paint it onscreen. This is achieved in a two-step process. First, geometry is stored in an efficient format in a step usually called geometry packing. Second, this packed geometry is sent to the hardware, where it is processed. Graphics hardware is extremely sensitive to packing methods; performance increases tenfold just by selecting the optimal delivery mechanism. We will explore packing and rendering in Chapter 12, "3D Pipeline Overview." If you need API-specific rendering information, Appendix B, "OpenGL," and Appendix C, "Direct3D," should provide you with the information you need.
Audio rendering works in a slightly different way than graphics. We can't just filter what is visible and what is not. An enemy behind you might not be visible, but his footsteps are still audible. However, filtering is also applied, generally by using some distance versus volume metric. Attenuation can be computed in order to know which sound sources are effectively audible to the player. Once these sources are identified, we can focus on sending the audio files to the sound card.
Rendering NPCs is quite different from rendering inanimate geometry. They need a specific pipeline due to their animation properties. However, we can still begin by filtering the character lists, so only characters close to the player and affecting him are processed. Again, a visibility step is pretty common. Only characters that survive a clipping and occlusion test will be moved on to the pipeline. This is especially important for fully animated characters. Working with dynamic, animated geometry is more expensive than static, passive elements, and thus must be applied only when needed. Optionally, some games will use an LOD pass to create a simplified representation of characters located in view but far away from the viewer.
Then, the main animation routine must be computed. There are a host of variations, from keyframed to skeletal animations and so on. All of them will be covered in Chapter 15, "Character Animation." But the end result for all of them is the same: static geometry data that represents the current snapshot of how the character must look for a given frame.
At this point, a character has been simplified by a static geometry representation, which can be processed as if it were regular world geometry. It must be packed using an efficient representation and sent to the hardware for display. Notice that, for their internals, some animation methods will require specific rendering algorithms, so characters will need to be rendered separately from passive world geometry.
The main player is nothing but a very special-case NPC. But its rendering pipeline is simpler than those of secondary characters for two very simple reasons. First, the player is generally visible, so there is no need to allocate time to check him for visibility. After all, he's supposed to be the hero, so it makes no sense for him to remain hidden. Second, there is no need for LOD processing as well. Most games display players in a central role, so they will always use high-resolution meshes.
Thus, the main player will only undergo an animation step, packing, and a render step. The animation will sometimes be of higher quality than that of enemies because the player is in a central role and more details are needed. But there isn't much difference between a player and an NPC.
Our framework for presentation has thus been introduced. It is a very involved process that you should review until it is fully understood, so let's recap for a second, using the following pseudocode:
World presentation Select visible subset (graphics) Clip Cull Occlude Select resolution Pack geometry Render world geometry Select audible sound sources (sound) Pack audio data Send to audio hardware NPC presentation Select visible subset Animate Pack Render NPC data Player presentation Animate Pack Render
As a global reminder, use the pseudocode listing at the end of the "World Update" section to review the complete framework. It is a long sequence of operations, but should cover most games on the market. In fact, I recommend that you take some time and decompose one or two commercial games into their constituent parts using the framework. Time spent doing this will be priceless when we start analyzing each of the individual segments. Notice how the following pseudocode can also act as an index to the contents in this book. Pointers to relevant chapters are given for each section, so you know where to look for additional information.
Game logic Player update Sense Player input (chapter 5) Compute restrictions (chapter 22) Update player state World update (chapters 6 to 9) Passive elements (chapter 4, spatial index) Pre-select active zone for engine use Logic-based elements Sort according to relevance Execute control mechanism Update state AI based elements Sort according to relevance Sense internal state and goals Sense restrictions Decision engine Update world End Presentation World presentation (chapters 11 to 14, 17 to 21) Select visible subset (graphics) Clip Cull Occlude Select resolution Pack geometry Render world geometry Select audible sound sources (sound) Pack audio data Send to audio hardware NPC presentation (chapter 15) Select visible subset Animate Pack Render NPC data Player presentation (chapter 15) Animate Pack Render End
Caveat: Networked Games
The previous models do a really good job at depicting most single-player games. But networked titles need to impose some minor changes to the model so they can fit into it. These changes fundamentally affect the game logic section and, specifically, the player control and NPC sections. Just remember that, from another player's standpoint, your character is really just an NPC whose position is updated by another machine through a network connection. Generally, two changes are all that is needed to edit the model.
The player update section must change to make sure every player update is followed by a broadcast message that sends the newly computed position to other gamers through the network. The players receiving the information from the network will then use it to update a special breed of NPCs that actually do represent other game players. Thus, the second change affects the core of the AI system. Networked games can still have AIs for automatic monsters and so on, but a special type of AI must be reserved to represent these other players. This special-case AI module receives data from the communications channel and reflects it to the local gaming environment.
With these two changes in mind, a networked game is not that different from a regular, single-player title. All it takes is a bit of practice to understand that we are the player on a computer screen, but other users just see us as a very particular kind of NPC. We will cover NPCs in depth in Chapter 10, "Network Programming."