Thursday, September 1, 2011

Velocita Part III

I was actually glad that my drive gave up. I told myself that it'll be cleaner and more robust if I started over , but I wasn't that smart. It was the time when Direct3D 10 was release and I had an nVidia 8800 Ultra powering my machine and I was aching to find out how pretty my game will look if I took the time to get some effects working. I was really pumped about geometry shaders and the magic you could do with them, like mesh extrusion for motion blur etc. I rewrote the same game in Direct3D 10 with the same physics and the same code structure. Minor changes like no support for .x files was a little hiccup and the new shader code took a little time to get familiar with.

I worked a lot on the graphics, I put in a slightly modified version of the SSAO implementation from the CryEngine 'Finding Next Gen' paper. I reworked all the models in the game to add a little city with a lake and some houses. I even threw in a fully procedural water shader to have it reflect the world properly. The game was looking more or less the same and I didn't go through the trouble of adding any geometry shaders. So I started working on this idea I had where I'd blur the environment map that is being generated in realtime and then put that onto the car so that the color from the surroundings would reflect from the car to fake global illumination. It was a cheap imitation of GI but worked rather well, whenever I drove across the red house my car would turn slightly red from that side. I knew it would work after I saw how well hemispherical Lighting worked on the skull model from the DirectX SDK.

Inspired by the smoke in Need for Speed ProStreet, I started working with soft particles. It was easy to get them going. A few comparisons with the depth buffer that my SSAO shader was already working with, removed all the hard edges that the particles were creating when they intersected with the world. But that wasn't it, I wanted true 3D particles in which I could immerse my car while I did donuts around a fake pole without a collision model. I tried all sorts of things but nothing really worked, I was trying to make a 2D screen-aligned quad to look like a 3D particle by tracing the view ray and calculating the angle it makes with the imaginary 3D particle that is suspended in the world to alter the texture on the 2D quad. Coming home from school to tweak a few variables to see how the particles look was a fun game in itself until I realized I was slowing down.

After being distracted by the graphics of the game for quite a while I came to realize that my physics were still dysfunctional, every time the car hit a bump it'd fly into the sky at the speed of light. I needed the suspensions to work properly which involved a lot of work which is when the structure of the game slowly started to change. The previous physics model that I was working with was strictly 2D so it was a quick fix rather than an actual 3D physics model. As I started implementing the suspension I figured out how the car needs to be defined as a rigid body on which I can add up forces and torques to have it react the way I want it to. It obviously took quite a while to get that done, I ran into some nice tutorials that explained rigid body dynamics which were easy to understand and implement. I'll be honest though, I couldn't understand all the 3D math involved but the physics were simple manageable. It was shaping up slowly though there were a lot of errors everywhere, bugs emerged as I tried to take stuff out from the 2D physics implementation into the new 3D one. I positioned all the forces in their right places, the traction frictional force was supposed to be under my rear wheels instead of the center of the car and the lateral frictional forces on the side of the car under the wheels and after lots of hard work and fighting with stability issues with Euler integration, I had finally finished my car physics simulator.

Tuesday, August 9, 2011

Velocita Part II

I had made quite a mess of the project by now, I had all the buildings look 3D by keeping track of the angle of the car from the position of the building and projecting the image of the building in the opposite direction to fake the effect of height. I figured that the best way out would be to start all the way from the beginning. So I did just that, but this time in DirectX. I had myself convinced that it was Allegro that was slowing down the game, and not the multiple textures that were being loaded at runtime!

This version of the game was less complicated and stayed a 2D car physics simulator for the longest time. All you could do was drive around and pull a few powerslides. The sound and graphics were almost the same, except with light trails and motion blur! It took a while for me to get to know the DirectX 9 API especially because I was starting off with 2D. Soon after I was done setting it all up, I had a dear friend draw out some images of a few cars from the top down perspective. We used a camera on a tripod to take shots of the artwork and cropped it to put it into the game. Even though we had a more realistic car it was still just an image. I was bored of looking at a static image of a car which was not fitting in with the graphics of the rest of the world which were still being prepared in MS Paint. That was when I decided that it was time to step things up a bit.

Before starting off, I had myself convinced that it'll be really simple, just the same physics but models instead of images. All  I though I had to do was learn how to load in some models of a car, a set of wheels and a simple world and position them properly. Obviously, I had no idea what I was getting myself into and I ended up spending the next three years on a 3D car physics simulator before it was complete.

Everything went according to plan, importing models, positioning the camera and running the same simulation on it. I learned how to set up a DirectX window, load up models, store them as meshes, get textures, set rendering states, position lights(fixed function), set transforms and draw meshes using subsets. I ran into pitfalls on every step. The tutorials in the DirectX SDK weren't any help at all. All you could do is copy a whole sample project and tell yourself that you've successfully learned how to set up instanced skinned meshes which didn't sound very exciting to me. Books, forums and other helpful articles on the internet were of great help,  I had a car run on an open field with a camera looking down on it. I accomplished the task quite easily, but it was sad to see how my car reacted when it went over a bump - it didn't.

I applied a not-so-quick fix to the game where the car oriented itself according to the height of the wheels from the ground mesh. A few raycasts to the ground were easy to figure out but I got really stuck when I started working with matrices and quaternions, I hadn't braced myself for 3D math. Though the car was now reacting to the heightmap, it misbehaved when it went off a cliff so I knew that we needed a proper suspension set up to makes those reactions more physically acceptable.

That was when my hard drive gave up on me and I lost all my files.

Saturday, August 6, 2011

Velocita Part I

I meant to buy a book on DirectX but I'm glad I got Game Programming All in One (2nd Edition) instead which focused on Allegro. Slowly and patiently trying out all the functions written in the book and keeping note of the ones that I thought were important, it was the book that introduced me to game programming fundamentals. From simple 2D vector graphics to loading bitmaps and drawing animated sprites, I was armed with the tools to make my first top-down car physics simulator. I learned the API by working on Velocita side by side, everything that was usable would be copied from the book and pasted into the project. The end goal was a free roaming car physics simulator in an open world and I had myself convinced that I can't go wrong with it. It was my first and last lesson on Feature Creep, something I'll never forget. So I took a small simple bitmap of a car and a large 5000x5000 bitmap showing the top down view of a city baked in MSPaint. The map consisted of a few extra squares and rectangles for buildings, bitmaps that doubled up for the collision model as well.

I included a particle system for the dust, smoke and skidmarks, had Gourad shaded sprites for doing a day/night cycle and translucent images for car and street lights. Tinting all the sprites in real time in Allegro wasn't one of the brightest ideas I had. As the game slowed down to an unbearable framerate, I tried a few tricks to speed things up a bit, and soon I discovered scrolling. If only I had read a few more pages of the book, I would've saved a few days work, but figuring it out myself was a great experience. Cropping the visible part of the world map around the position of the camera and blitting(copy) to screen was an amazing find in my opinion.

The game entered it's longest stage of development when I started working on the physics of the car. I had no clue as to how car physics worked but I didn't let that stop me, soon I saw myself trying out random mathematical functions that related the throttle and steering to the speed and angle of the car respectively. Failing miserably, I searched on Google for a simple article that explains 2D car physics for games. After looking for days and rejecting a few dozen complicated articles, I found that one article that I still have saved on my computer to this day - "Car Physics for Games by Macro Monster" or the "Monstrous Car Physics Tutorial". Even though the article was simple, I had a hard time understanding it. My brother did most of the work actually and later helped me understand how it all really worked. This article is very dear to me, I spent days staring at it, brings back good old memories of being in class and having the printed pages hidden inside the history textbook!

The racing game came to life when the car started to react in a more realistic way, with the sound of a skid playing in the background with it's volume and pitch attached to the speed and angle of the car respectively. You could now go to specific buildings to select custom colors and spoilers for your flat 2D car and change the weight or cornering stiffness to adjust it's performance. Obviously influenced by Need for Speed, all these features slowly found their way into the game which came as no surprise. I soon found myself trying to incorporate a 2D side scrolling shooter in one of the buildings, with frame by frame animations exported from flash, and muzzle flashes from Max Payne 2, by taking snapshots from the game by pausing it in the middle of an action sequence, a not so minor distraction that I'm not particularly proud of.

I had no track of time whatsoever. There was nothing to worry about and no deadline to take care of, it was pure fun, creating whatever came to mind. I wouldn't call it all a waste of time, I spent days trying to have the cop car figure out the position of the racer by shooting rays into the world not realizing that the position of the racer is already sitting in a variable which is accessible to me. I did a lot of stupid things, like, planting a dummy pixel on the tip of the gun so that the program can iterate through the world map to find the colored pixel and spawn a bullet at the right location. The good part is that a lesson was learned even though countless days were spent doing foolish things, I ended up with lots of experience of doing all the stuff the wrong way.

Friday, July 22, 2011

What To Learn From Dark

I always wanted to do a 2D side scroller shooter and I though this would be a great time to start with one. I used Allegro and Dev C++ and was very comfortable with them, so with permission to use an external library from my school teacher I started working on Dark.

I wanted something like a 2D Assassins Creed loaded with guns and fully procedural character animations and fast paced action. I first figured out an IK solver to create bones for my characters then put them together to make a walking bipedal. After that was done I started trying out different techniques to create a procedural animation system that would make the dead collection of bones come to life. I failed. I came up with some very simple walking animations that worked on footsteps calculated by analyzing the structure of the terrain underneath but never got it to look acceptable. I even tried to turn it into a ragdoll which would balance itself by applying it's own muscular forces, like a ragdoll with a brain, which obviously didn't work out. All that time didn't go to waste though, I ended up using the ragdoll after the characters died, with springs connecting the feet to the pelvis for a more natural fall unlike a traditional ragdoll. After spending countless hours on that system, I gave up and made a small application that allowed me to save and load keyframed animations. After implementing keyframed animations, I tried to turn it into a semi procedural animation system where the character would not let any bones cut through the world.

With all the worlds made out of lines, I made an object editor that allowed me to create simple objects and import them into the map editor. These objects also included guns that the player and other NPCs carried. To create reloading animations, I also tagged weapon objects with color coded parts which moved when the right hand of the character approached it in the reloading animation. So the barrel of the gun moved as the player reloaded the weapon after replacing the old clip that fell to the ground.

Which reminds me, I also tried to incorporate a 2D physics simulator into my game that allowed these objects to move and fall when shot, you could even make chandeliers by sticking objects to the background with strings and springs. The physics engine never reached it's final stages, I never implemented impulses and contact normal forces which made the objects act funny. I wouldn't discover and understand the Runge Kutta numerical method for another year for the suspensions in Velocita.

The game was still bland, there were many other things to add and time was running out. I made breakable objects like glass and wood which were again just simple lines which took damage. With a little clever trigonometry I had pieces of wood flying off the surfaces from the point of contact to make a hole in the wall.  Talking about dynamic objects in the world, the particle system was fun for the smoke and the shells coming out of the gun, but they just weren't what I wanted for the blood. There had do be amazing blood in the game for good feedback to the player. I like to call it rope physics, but really, they were a set of particles connected with strings, bright red strings, which replaced the bullet after it made contact with the enemy, so that after you've taken your last shot, and you're falling to the ground in slow motion, you can see the the blood spray behind your character.

There is much to learn from this game. Most importantly, Box2D and Chipmunk are great physics simulation libraries! Recreating something that's already been done is good if you want to learn how it's made but if you care more about your game then choose whats best for the application.

If I was told to find the missing ingredient in the project, I would say that it's design. The project started off without a design written down on paper. My brain is the last place I'd choose to keep an idea, because after a little while, it's not the very same idea you originally had. With the initial goal to create a free running platformer, I ended up building a simple shooter with sloppy physics, overdone effects, and ugly animations. There were countless bugs too, untraceable and very irritating. I never even started with making the final levels of the game. All I have is five tutorias to show off all the features of the game.