Future Intrigue vs. the Wasteland of the Now

I promise that one day this journal will have something more entertaining than my I’m-Planning-On-Making-This-Cool-Game ramblings. In the interim, I present to you my general (and likely highly incomplete) plan of action (not including creation of art/level/music/sound assets, which will sort of happen as necessary):

  1. Get the graphics engine to the point where it can display a level, though without the greatest of visual quality (probably simple directional lighting, crap texturing, nothing that will make a pretty screenshot. It won’t look pretty, but it’ll work).
  2. Implement the driving-on-track code (i.e. keeping the vehicle on the track, bouncing/sliding against walls, controlling the vehicle)
  3. Implement some form of AI for the opponent cars. At this point, the game will be “playable” in a weak sense
  4. Begin implementation on the sound/music code. Get basic engine sounds, collisions, etc working.
  5. Begin to improve the graphics engine, by implementing the lightmap generator, getting new shaders written, particle systems, etc. Add some polish
  6. Begin work on the menuing system. Get a title screen/etc.
  7. Work on enemy AI. Make it drive better, make it tuneable (i.e. difficulty levels).
  8. If I’m going to do network code, I’ll probably want to start work on it right around here
  9. Start polishing the sound engine a bit (Add ability to have ambient sounds in the levels, doppler effect, all sorts of other audible cues)
  10. Get the graphics engine to the point that no more code changes will be necessary
  11. Begin fleshing out levels, start chaining them together into circuits
  12. More polish. Make the menus look cooler, tweak performance, all of that jazz
  13. At this point, the game will be highly playable, so anything past this is pure candy. HDR rendering? motion blur? If there’s time.

There are also some considerations that I will be attempting to make over the course of the whole development:

  • The game needs to be, above all else, fun. If I’m not having fun playing it, then why should I even be making it?
  • I am going to try my hardest to minimize load times. That is a very big priority for me. I hate waiting for games to load.
  • The driving control will be simple and easy. I have a great idea for mouse-driven steering (which may or may not be original, but I haven’t seen it personally) that I prototyped a while back…It’s definitely fun, but it needs tweaking. Probably in the form of a control options screen, with a good default setting.
  • The graphics code should be easily extendable. I’d like to be able to add higher-quality versions of the existing effects in the future (i.e. add some PS3.0 support for full-scale displacement mapping or such).

Hm. For the three of you out there that happen to keep tabs on this journal, if you see something (rather, fail to see something) important that I’m missing, please let me know. I’m new to this whole actually-trying-to-FINISH-a-game-in-this-lifetime thing.

The story thus far…

One Point Five Years Ago

Early last year, I was playing around with a simple terrain engine. It was your basic height-field based terrain engine. It was also crap-tastic. But hey, you’ve gotta start somewhere. Thus, I started with this:


(Click To Enlarge)

Kinda lame, but it was a good test. Each chunk was LODified by using a Binary Triangle Tree, which was a great simplification method, though I did eventually switch to using progressive meshing (though leaving the edges in-tact…not the greatest LOD scheme ever). It was then that I had a vision. Well, not so much a vision, but an idea. Well, not even an idea. More of a thought. Cliffs! That’s right, cliffs. And caves. Those were two things that I would love to have, but they’re impossible with a straight-up heightfield renderer. So I set my tired code aside, and began my next crazy scheme.

Terrain Idea The Second!

So, I thought: what if I could model a level in a manner similar to making a topographical map. Something like this:


(Click To Enlarge)

In this system, each shape could be drawn, and given a height value. The editor would fill in the drawn shapes with polygons, connecting them to the other inner shapes (and outer shapes), adding slopes when asked (or making a given shape a plateau).

Sound crazy? It was. I coded it for about three months, working on logic to triangulate a complex polygon (overlapping not allowed) which contains children (which are holes in the parent polygon). Then I worked on smoothing the polygons by adding curves (see the first two screenshots for a comparison). Each edge was essentially a bezier curve, where the middle two control points were placed based on the angle of the connection to the next/previous line segments.

Now, right about now, you may be thinking to yourself: “How does this solve the problem of caves? How did you handle the LOD switching? Isn’t this a lot of work? What’s the meaning of life?” To answer your questions, in order: It doesn’t, I didn’t, Way too much, and free beer. This particular concoction was way too complex, and not near enough to what I wanted. So it, too, was scrapped.

The Not So Distant Past, Or: How to Totally Copy SSX’s Idea

I started browsing the web for other creative ways to generate terrain. It was then that I came upon THIS article. What a brilliant idea, I thought! Use curved surfaces to model terrain! So I started work on Terrain III: Terrain With a Vengeance. Not too long afterwards, I had a decent curved-surface terrain. The beziers were calculated in a vertex shader, given the matrix representation of the surface as a 4×4 matrix. Each vertex buffer simply contained the u and v coordinates (in the range [0, 1]) for the patch of the given resolution (different vertices in the vertex buffer were used for different tesselations). However, there were two big problems:

  • The vertex shader was somewhat slow, with the extra matrix multiplications (three 4×4 multiplications and a dot product for position alone)
  • There were cracks between the patches, due to floating-point rounding errors.

So, I thought, what if I calculated the patches in software in a big dynamic vertex buffer, using a better method? I ended up using de Casteljau’s Method on the edges of the patches, because it does not have the same floating-point issues that the matrix representation does. However, I continued using the matrix method on the interior points, for speed reasons. Each patch was cached into the vertex buffer using a cheap LRU cache. This eliminated the “sparkles” caused by the floating-point errors, and significantly improved my framerate. And now, screenshots:



(Click To Enlarge)

This method worked well, but there were issues with locking/unlocking the buffer. Also, 800 patches meant 800 DrawPrimitive calls, which is, how you say, lame. Thus, I rebuilt the cache algorithm (Yes, I have the technology) to cache items into a set of smaller vertex buffers (that I called “slices”), which were each bound to a specific material (i.e. grass, etc). Thus, they could be batched up better. Soon, 800 patches meant only about 30 draw primitive calls. Which was way better, but there was still a problem. With great caching comes great framerate instability. Since the caching algorithm would sometimes not have to do anything, but sometimes it would have to cache a lot of patches, the framerate became very unstable. Even though it was running faster than 100 fps almost the entire time, it was still highly visible stuttering (especially when I fillrate-limited it a bit). Plus, there became the question of how to actually MODEL such a terrain (I was going to have to write a super-complicated terrain editor). So I wavered. It seemed that there were many, many problems with this implementation and that, while it’s definitely cool, I don’t know that I’m going to be able to do what I want within my newly-created timeframe. So I decided to set this method aside as well, and move on.

The Present, But Not the Birthday Kind

And that brings us to now. I’ve decided that I’m going to use a simple mesh format for the terrain, though with LOD data built into it. That way, I can use an existing modeling program (I’m looking at you, Blender) to do the modeling, build some simple texture/material/atmosphere editing utilities (or one texture/material/atmosphere editing utility), and just use that. Break it up into LOD-able chunks, and I think I have a winner!

Also, I’ll probably keep the track editing interface that I already have (though I’ll have to improve on it, obviously, since it’s…clunky, at best). But it provided me with these:


(Click To Enlarge)

Which are fairly representative of the types of tracks I’m aiming to have.

Alright, class, that’s the end of your history lesson for today. Up next: New developments in code!

This journal will self-destruct in 2.5 months.

Okay. I’ve set my deadline. The plans are in place. It’s now a matter of getting it done.

The Goal

A futuristic racing game. Similar to F-Zero. No weapons, no powerups, just racing. But I want it done by the end of October. Impossible, you say? Probably. But I’ve gotta try. And trying is the first step towards failure. Or something.

The Obstacles

I’m doing the whole thing myself. No artists, no musicians, no sound people, no budget. But I’m picky, so it still has to look good. I’m not very good at programming physics or AI, so I’ll have to brush up on those before I’m done. Textures will probably be mostly digital camera pictures edited to tile.

Components

  • Graphics
    • Terrain/Track
    • Foliage
    • Sky/Starfield
    • Clouds
    • Ocean Water
    • Vehicles
    • Shadows
    • Optional stuff, given time (HDR, motion blur, etc, etc)
    • Not to mention all of the modeling and artwork
  • Physics
    • Vehicle handling/control
    • Sticking to the track (even in loops/upside down areas)
    • Collision/Collision Response with track
    • Collision/Collision Response with other vehicles
  • AI
    • Getting AI to drive along track
    • Getting AI to avoid other vehicles
    • Advanced steering behaviors (skids, etc)
  • Sound
    • Doppler Effect
    • Environmental effects (echo, reverb, etc)
    • Background music
  • Input
    • Make Mouse/Keyboard control not suck
    • Enable joystick/wheel control
  • Network play (Given time)
    • Generic input structure to get input from AI, keyboard, or network sources
    • Research how to handle network play

Okay…that’s good enough for now, I think. This journal has helped me get a grasp on exactly how much I have to do. I definitely have my work cut out for me.

Side note: I don’t have internet access at home for the next few days, so updates will be less exciting than I would like for the next little bit.