Tuesday, November 3, 2009

Pong Postmortem: Completing a Game in 24 Hours!

For the uninitiated (or techno-illiterate), a "postmortem" is a wrap-up discussion summarizing the good, bad, and ugly of a project following its development. What follows is a summary of the creation of my first completed game, a clone of the Atari classic Pong.

My Pong clone was created in 24 hours, though not in the type of all-nighter hack-a-thon you might expect or even a typical three work days. I have a full-time day job, so development is typically done late evenings, but fortunately I kept track of the amount of time spent on specific components. Note that I started with a working Direct3D application from Luna's book Introduction to 3D Game Programming with DirectX 9.0c: A Shader Approach. Here is the hours-to-effort breakdown:

  • 10 Hours - I dedicated the first 10 hours to rendering the basics of the game: the board, two paddles, and the ball. This included creation of graphical "placeholders"; I'm not an artist but I realized I could come back and make the art fancy after everything worked. Getting the ball in motion and then allowing it to bounce off the walls and paddles (Collision Detection) was the second major focus. Finally, the simple mechanic of allowing the player to move a paddle up/down brought the game into a playable state.

  • 4 Hours - The primary effort of the next stretch was to implement a basic computer opponent (Artificial Intelligence), and I started with a perfect opponent whose vertical position matched the ball's position at every moment. When adding different game modes, this perfect opponent became part of the game's Practice Mode. I added the ball's motion blur effect just to improve aesthetics and moved hard-coded values to an include file for easier maintenance and testing.

  • 4 Hours - In this phase I worked on creating a computer opponent that moved more realistically but was also fallible; a perfect opponent gets boring to play against! I added different difficulty levels (easy/medium/hard), which works by choosing a random "reaction time delay" between when the player hits the ball and the computer opponent is allowed to hit the ball. Obviously, as difficulty increases, the computer's reaction time improves to make it a more formidable opponent.

  • 4 Hours - At this point the game was playable with differing levels of difficulty but no clear way of selecting game settings. I created the menu system and added scoring to determine the winner.

  • 2 Hours - The last step before I considered the game completed was to work on the art, which could clearly still use some work! :)

Final Thoughts:
I knew this project would be relatively simple because there are only four game objects to keep track of: two paddles, one ball, and one board. However, due to its simple nature, I was inclined to hack it together quickly and did not follow strict OOP (object-oriented programming) principles. The majority of the game code is in a single monolithic file. I also resorted to reusing an existing class designed to output simple statistics to display text-based menus. But worse, the same class used to show all menus and text became my game state manager since I needed to know which menus had been processed. I then extended it to display current score values and to show which player had won the game. Although I could have put a lot of time into doing it the right way, the purpose of this effort was to get something done. In future endeavors I plan to follow better OOP design.

The best part of this project is that I actually completed a working game! I am proud of the subtle but effective motion blur effect. The game doesn't have all the bells and whistles (seriously, no sounds or music yet) but it is playable, implements Collision Detection and Artificial Intelligence, and has a clearly defined winner at the end. Some may even consider it fun :)

Friday, October 30, 2009

PONG Clone Completed!!!

It is with great pleasure that I announce I have finally completed a game of my own! There are some obvious improvements that could be made (adding sound, better art, etc.) but it is a fully working game with Artificial Intelligence (AI) for the computer opponent, basic menus, scoring, and clear winning conditions. I'm particularly proud of the ball's motion blur, a subtle effect that makes the game look more polished.

The left paddle is controlled with the W (up) and S (down) keys. Likewise, the right paddle is controlled with the O and L keys.

Download the Game Now!

I would be very appreciative of any feedback; just leave me a comment here on the blog to let me know what you think. I will provide a breakdown of the effort spent on this simple game (done in 24 hours!) in an upcoming post.

Thursday, October 29, 2009

Finishing a Game: Pong Update

As I've stated in some older posts, I've been planning to work on a Pong clone for some time now. I was digging through a new book and learning the internals of Direct3D lighting, texturing, blending, meshes, etc. And I've learned a LOT (especially about vertex and pixel shaders) since those older blog posts, but one problem with the book I'm using is that it teaches small bits without building a game project. Even with all of my learning I still had not created a whole game, and I do know that in order to have a decent game career portfolio I will need to have at least one completed game (though probably two or more) to even be considered.

So I took a step back from all the fun advanced 3D stuff for a bit and am proud to say I'm making progress (translation: nearly completed) on my Pong clone. I will post the game itself and implementation details soon!

In other news, my wife and I finally purchased a Nintendo Wii since the retail price came down to $200. Wii Sports and Boom Blox are pretty cool. And just a quick news update in case you missed it- the Unity game engine is now available as a free download (was supposedly $199). Check it out and let's create some awesome games!

Tuesday, September 29, 2009

Sine Language Lesson, Part 2

In Part 1 of this post I discussed some useful applications of the sine function without really delving into the details of how it works. Specifically, we focused on the equation y = sin(x). Here is a more useful variation of the sine function as demonstrated in the Ocean Waves demo:

y = A * sin(K*distance - F*time + S)
  • A = amplitude
  • K = angular frequency
  • F = time frequency
  • S = shift
Amplitude represents the height of the wave; it typically ranges from -1 to 1 but can be set to an arbitrary value (e.g. set A = 25 for the wave to range from -25 to 25). The angular frequency represents how quickly the wave travels vertically. The time frequency represents how quickly the wave travels horizontally; note that F*time can be omitted from the sine function to view a static snapshot of the wave at a point in time but is included in the Ocean Waves demo to provide the effect of a wave in motion. Finally, the shift parameter allows us to move the wave by a horizontal offset so it starts from a new position (e.g. setting S = -π/2 would map it to the cosine function).

The Point Light demo from Part 1 sets the light source position's Z-coordinate using a simple sine function and then calculates the X- and Y-coordinates as sine functions using the computed Z value as the distance parameter. The Ocean Waves demo combines multiple sine waves to achieve the illusion of irregularity (not all waves in the ocean are the same height and hit shore at the same regular time interval). For example, to apply the effects of y = sin(x) and y = 12 * sin(3x), we can simply write y = sin(x) + (12 * sin(3x)). Observe that the two functions are added together. Watch the web preview of Combining Sine Waves to see the concept in motion.

I hope this post encourages you to investigate some potential uses of sine/cosine functions, as well as return to Part 1 if you missed the demo programs. It seems some things we learned in high school actually did turn out to be useful!

Wednesday, September 23, 2009

Staying Motivated

I can't believe I started this blog more than six months ago. I remember thinking initially, after seeing many game development blogs trail off after just a couple months, that I would surely put out at least five posts every week. Ha! Let's just say I may have been a little ambitious. It's easy to push forward full steam when something is new, but the question of true dedication comes when the going isn't so easy.

I've seen forum posts regarding burnout on the game development dream and even noticed one of the blogs I followed (and had linked here) seems to have disappeared. So... how do you stay motivated when your enthusiasm wanes? I think part of it is remembering what you enjoyed about it (whether it is game development or another hobby) in the first place, and looking forward to what you will be able to do with practice. In my case I'm reading through a very dry, technical graphics book right now and sometimes it is flat-out boring; but I know that by reading it and working through the examples I will in time be a better game developer.

Quite honestly, I think everyone loses their enthusiasm at times. If you stay away from an activity too long it can be hard (though not impossible) to get back into it, and if you play with something too long it can start to feel like work. But the best approach is to just stick with it. Don't give up!

Check out Brenda Brathwaite's blog post for more inspirational thoughts on staying motivated. I'm proud to say that even though I'm not posting as frequently, I am still learning new graphics tricks (today was Direct3D meshes) and will not be disappearing any time soon!

Sunday, August 30, 2009

Sine Language Lesson, Part 1

I've had this idea ruminating in my mind for some time now. Math is a big part of graphics development and I'm certainly no expert, but I wanted to show off some cool things that can be done with sine waves. This part introduces the concept and shows some fun demo programs you can play with; part two will delve into the inner workings of the demos, which have been adapted from Frank Luna's Introduction to 3D Game Programming with DirectX 9.0c: A Shader Approach.

You may remember from your high school Trigonometry class (don't worry if not, it was a long time ago for me too!) those two periodic functions, sine (pronounced "sign") and cosine ("co-sign"). They're essentially the same function and you could map one to the other with a slight shift. Cosine has some unique applications of its own, such as determining light intensity based on viewing angle, but the demos below will focus primarily on sine waves.


Notice a few interesting properties from the graph above. One is that a sine wave repeats itself every 2π (π ≈ 3.14159) or 360 degrees along the X-axis. Another is that it oscillates between the Y values -1 and 1. We write the function y = sin(x) to indicate the Y value as a function of X; see from the graph above that Y = 0 when X is any multiple of π and Y is either 1 or -1 (the peaks and valleys) when X is an odd multiple of π/2.

Point Light Demo - Download Program!

This demo shows how sine waves can be used to animate a light source. Use the specified keys to combine waves, creating a variety of unique horizontal and vertical motion paths.

Before learning this elegant method, my approach to animating an object that sways back and forth, or moves repeatedly up and down along a pole, was to use code like this in my update loop:
    static bool moveUp = true;
    if (moveUp) 
    { if (shipPos.y < 100) shipPos.y += value; else moveUp = false; }
    else 
    { if (shipPos.y > -100) shipPos.y -= value; else moveUp = true; }
With sine waves, this code reduces simply to shipPos.y = 100 * sin(x)! Notice that I multiplied by 100 to get the desired range instead of the standard oscillation from -1 to 1.

Ocean Waves Demo - Download Program!

This demo illustrates the effects of adding sine waves and two different wave types, circular and directional. Use the specified keys to play with parameters and change the wave patterns.

As with the Point Light demo, you will need to have DirectX (from Windows Update) installed in order to run the program.

These are just a couple applications of the sine function. Because of its periodic repetition, it could have many potential uses; some fellow GCG forum members cited their implementations of a 3D carousel and a wavy spaceship flight path as additional examples.

I hope you enjoy the demo programs of this post, though I admit I still need to learn better methods of input handling. Part two will describe wave alterations, based on the Ocean Waves demo, in greater detail. Until then, feel free to let us know: What's the coolest thing you've done with sine/cosine waves?

Thursday, July 16, 2009

Quick Random Update

So, Gamasutra is on Twitter too. You may recognize them, or at least you should if you have any business as a video game developer/designer. Gamasutra is one of the most popular game-oriented websites with full-featured articles and commentaries on the state of the industry, game reviews, yadda yadda yadda. So now you can check out not only the website, but also the Twitter feed. Oops, sorry if that last link didn't work; I suppose I should have linked it the proper way: @Gamasutra!

Enough hype, this post is mostly me checking in for a quick progress update. I blasted through reading about lighting, textures, blending, and stenciling in my Direct3D book and then found out the exercises required a fair deal of re-reading. Lesson learned, I have to work through chapter exercises before moving on to more difficult chapters! The same applies to the Game Design Concepts course I'm taking -- it's much easier to keep up with the readings than work through the exercises, some of which I have to skip. FYI, you can follow discussion for the course on Twitter too; just search for #GDCU!

The topic of my next post will be the power of sine waves. Yep, I'm talking about those tricky oscillating waves you learned about way back in high school. I've found some interesting applications and want to show off some of the cool stuff you can do with them. And now that I'm finally understanding the basics of HLSL (High Level Shader Language) shaders, the part that tripped me up big time in the last book I read, you can expect some posts on that stuff too.

Just curious, when was the last time you used something from high school you never thought you would need again? What's the trickiest math you've used in game development, and does calculus ever figure into the equation (pun... fully... intended!)?