🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

02.04 - Game Anatomy 101

Started by
14 comments, last by Teej 21 years, 10 months ago
The Basic Idea The way that games are made on a computer is not much different than the way a movie is shot on film. A film reel contains thousands of still photos that when viewed in quick succession make you believe that what you''re seeing is actually moving. For this effect to take place, movies are shown at somewhere between 24 and 30 frames per second. The same principle exists for games -- a game prepares frames of animation and displays them one after the other rapidly enough to give the impression of constant movement. One difference here though is that with a game, each frame is drawn taking into consideration the input from the player, the physics of the game environment, logic, AI and other factors, before the results are placed onto the screen. Do you remember that Game_Main() function from the previous article? It’s a function that’s got its foot in the message loop of the Windows application, and consequently gets called repeatedly. If the purpose of Game_Main() was to generate one frame of animation, well then, wouldn’t that fit in nicely? That’s exactly what’s going to happen. So long as Game_Main() gets called a decent number of times per second, and each iteration of Game_Main() prepares and displays a single frame, we’ve got a game on our hands. Like any program, our game would like an opportunity to initialize itself at startup, and tear everything down at closing time. For this facility, we turn back to WinMain() and notice that there’s a perfect place to call an initialization function before the message loop, and a termination function before WinMain() has completed its execution (which is the end of the Windows application). What we end up with is something like this:
  1. Register window class
  2. Create a window
  3. Call Game_Initialize()
  4. Enter Game Loop – this calls Game_Main()
  5. Call Game_Terminate()
  6. End of application
At this point, it’s starting to look like a real Windows game template! If we tuck all of this Windows code into a separate file and supply prototypes to the three game-related functions, we can reuse this code by inserting appropriate Game_Initialize(), Game_Main() and Game_Terminate() functions. When you think about it, the contents of Game_Initialize() and Game_Terminate() depend entirely upon what’s required by the code in Game_Main(). Therefore, that’s where we’ll start our little foray. Inside the Game Engine What we do know is that Game_Main() needs to end up drawing a frame of animation to the display. What we don’t yet know is how to actually accomplish this. This article is going to focus on a generalization of events, and successive articles will ramp you up to an actual implementation method, so hold onto your pants. Get it out of your head that there’s a single correct way to write a game. However you manage to alter the colors of the pixels on the display is your business – if it works, it works. Unfortunately, what works doesn’t necessarily work well. We’d like to be able to take advantage of the trials and tribulations of others and apply a little hindsight, and learn about what works well. In other words, a little conformity can be a good thing – we’ll jump off the bandwagon when it’s time to get creative. First off, it’s important to realize that the screen you’re staring at right now is a reflection of a piece of memory somewhere in the video card. Every time the video card draws a screen, it’s taking a look at this memory buffer for pixel-color information. We’re definitely going to want some control here. Assuming you had a function that changed the color of a pixel by manipulating a location in this memory buffer, you’d be very disappointed at the performance hit you’d be taking. It turns out that there’s overhead involved in requesting access to the video card’s display memory, locking the memory for writing, altering the appropriate pixel’s color value and relinquishing control back to the video card. A better approach is to create a memory buffer that’s the same size as the display’s video memory, and use this ‘working copy’ to assemble the frame ahead of time. Once ready, you copy the entire contents of this buffer directly to the display’s video memory, and voila – your image appears on the display. There are variations of this technique, and although I can tell you we won’t be doing things quite this way, the concept of an off-screen memory buffer is consistent. That’s all you need to know at the moment. Preliminary Reconnaissance Alright, so let’s move our assumptions forward: pretend that we now know how to take a memory buffer, alter its contents as to create an image for the current frame of animation, and have this buffer copied into the display’s video memory. Where does that leave us? Let’s compare notes: (once per frame = one iteration of Game_Main() )
  • collect input from the user
  • process user input (update internal data)
  • perform physics, logic, AI
  • play sounds
  • prepare the current frame
  • render the current frame to the display
It would seem that there are two types of tasks that Game_Main() is responsible for – those that interact with hardware, and those that manipulate data. Re-arranging this list a little, we get External
  • collect input from the user
  • play sounds
  • render the current frame to the display
Internal
  • process user input
  • perform physics, logic, AI
  • prepare the current frame
Take a good look at these two lists. You may have thought coming into this tutorial that the External list was representative of game development, when in reality it’s those items on the Internal list that count – straight coding that you’re already capable of doing. Once we can get our external requirements out of the way, we’ll have the resources available to implement code for any game we can imagine. You can almost consider these external items as ‘technicalities’, having no real basis in game development whatsoever – this also emphasizes what I was saying about your choice of programming language being design-independent. It’s only when we try drilling at the game’s internal elements that we need to choose our tools and apply some ‘elbow grease’. Looking at the Road Ahead I hope I’ve convinced you that we need to learn input, display and sound output techniques before we can truly turn our attention towards the ‘brain’ of the game itself. We’re trying to get ourselves acquainted with the programming tools so that we can use them later, not fumble with them. The rest of the Ladder series is devoted to integrate a sufficient amount of each of these areas into your working set of skills. Let me emphasize the word ‘sufficient’ – we’re not trying to learn more than we need to. As is with many things in life, game development works on a need-to-know basis. When you need to do something in particular, you’ll know when it’s time to summon up the reference documentation… Please reply to this article with your comments and questions.
Advertisement
This stuff is confusing.

If E=MC2, how can F=ND3?
If E=MC2, how can F=ND3?
I can understand where you''re coming from, and the best advice I can give is to continue with the articles in the series, and at some point things will work themselves out. For instance, you''ll be given a simple game template that you can look at, play with, and ultimately learn from.

Keep in mind that there are some things that we''ll be using, but not necessarily going into in-depth. One example of this is with Windows functions -- all we want to do is get our game window up and active...It''s not all that important to understand the philosophy of Windows event-driven programming.

If you give it a little time and there''s still some questions, you''ll need to ask them in the appropriate article so that someone can assist you.

Teej
** Nodding ** ..Right.. I''m following so far. (This is fun! - I really hope I can keep up.)

MSVC++ installed, DXSDK installed and paths to include files set up! It''s 1.50am, but I''m stirred up enough to continue for now..!

Teej, your style is brilliant - I feel we should be paying for such quality explainations. (Especially refreshing to see a comprehensive guide that isn''t full of spelling errors and poor layout too!)

*** Hi! I''m a signature virus. Copy me into your signature to help me spread! ***
The explanations are flowing from one concept to the other smoothly. I love it!
Blah, I says.
These articles are really flowing smoothly. I''m following along with A. LaMothe''s ''Tricks of the Windows Game Programming Gurus'' as well and the two go hand in hand together PURRfectly.

Great job all round!

Stu
I love how everything is explained in a so clear manner. There no "Well you have to do this because it''s that way", we get the full reason and soon the results.

I got my DirectX SDK Downloading as I type this and I''m reading on!

Patrick
Awesome tutorial Teej! Breaking into external & internal- am so happy coz the external stuff- was beginning to fear that it would take the fun out of the really fun stuff- the internals!!!
Great Teej!

I was looking for tutorials since some time now and they all tell u need to understant directx here is the documentation, un need to know API here is... and so on

With your tutorial I really have on overview of whats the purpose of thos "utility" and how they are used in the averall process a game developping.

Now that I understand that I will get into it way more easy

You have done an amazing job, thx.
Like I said when I first enrolled. I''m tired of learning C++/C with no real projects to play with. So far so good Teej, I''m looking forward to learning more as I read on.

Thanks for taking the time out to teach us all,



Keep On Smiling
:) Keep On Smiling :)

This topic is closed to new replies.

Advertisement