Friday, August 26, 2011

CDN SpeedGame Postmortem!

Would you believe it - I don't even have enough free time to make a little speedgame?!? Maybe I was over ambitious but I'll get to that.

So my entry into the Christian Developer Network's 2011 SpeedGame was going to be a Robot-Unicorn type game but with a cat. We each had to pick a verse as a theme for our game and I chose Proverbs 15:24 - the lolcat Bible version.

Proverbs 15:24 - Smrt kittehs go up, not down to da basement.

The basic gist of the verse is wise people are on a path leading upward and they turn away from death/hell beneath. I made a game about a cat that falls asleep during a thunderstorm and dreams that it is running away from the storm, jumping from platform to platform as the storm gets closer and closer. Really simple concept - I mean you just have two controls, jump and fire. Jump to stay on the platforms and fire to deal with obstacles in your way. The obstacles would slow you down and if your cat doesn't keep ahead of the storm approaching from the left side of the screen it gets soaked and you lose! This post is about the game dev process and the hiccups I had along the way that I'll share my solutions for and hopefully they will be helpful for other Ogre game devs.

But first - a simple rundown of the tools and libraries I used for the game:

- Ogre 3D graphics engine (duh)
- Box2D physics
- OpenAL audio
- Gorilla GUI
- OIS for input

- Blender 3D for models
- various free model and sound websites for the developer/test content

OK, so in the roughly 20 days we were given to do actual dev work on the project I decided to build a cross platform twitch based game. That was the first hiccup. I spent roughly 2/3 days just getting basic Ogre working on Windows, OSX and iOS. What I did was download the SDK for Windows, OSX and iOS and then I set up this folder structure to house it all.

- design <-- all my design files
- GameiOS <-- iOS specific XCode project
- GameOSX <-- OSX specific XCode project
- GameWin <-- Visual Studio 2010 project
- lib <-- Box2D and OpenAL libs/source
- media <-- all models, sounds, graphics etc.
- src <-- all the shared source code

Cross Platform Luv

Windows was cake to setup for just about all the libraries. iOS was a bit more difficult because you have to compile the libraries for the right architecture to run on the device and different ones to run in the simulator. OSX had issues with just working at all. I tried to use the XCode 4 templates to create a new project but even when I got it to compile it would crash on startup. Eventually I found that if I moved the log manager initialization to a line after Ogre::Root was initialized then the crash went away and I could proceed. So all that debugging on OSX and the extra iOS configuring took me a couple days of free time.

Oh, and OSX fullscreen mode just doesn't seem to work -- which was annoying because I had to restart my computer to regain control.

After getting the demo app working cross platform I put it all in a GIT repo (always a good idea to backup your code).

Physics Physics Physics

The next step was actually implementing the game, so I created prefab boxes in Ogre for the player model, the platforms, the bonuses and walls - everything and tried to hook up the Box2D physics. It wasn't that hard to create a Box2D hull for all the objects because they were all square initially - however I ran into major issues getting the Box2D step() function to be framerate independant. In fact, to this day the physics speeds are different on each platform even when I confine the framerate to roughly 60 fps, and this annoys me to no end! I even got a helpful hint from azrialelf on the Ogre forums that he just created a framelistener and told Box2D to step with the evt.timeSinceLastFrame as the time delta. This does work OK, but it still doesn't behave the same on all platforms and still seems to be affected by framerate somewhat.

One other big gotcha with physics on iOS and OSX is that the demo app run the main loop with a timer set at 60fps where as the windows run loop is not timer based and runs as fast as your gfx card can go. This really brought out the Physics step problems because my windows game would run at like 2000 fps and the physics wouldn't work at all while the iOS version would be really slow and the OSX version would be fast -- even though they used the same physics settings (they shared the same code). My plan to address this is to just tweak it so it feels OK on each platform and not kill myself trying to figure it out.

OpenAL Lacks Decent File Import Capabilities

OpenAL was surprisingly easy to set up for all platforms. The only issue I ran into was that there didn't seem to be builtin support for reading any audio formats - so I just grabbed some code off the internet for reading .wav files without ALUT. I did find solutions that involved using iOS/OSX libraries, but I wanted something that would work across platform. Eventually, I plan on adding the ogg vorbis file libraries and using those to load compressed audio files.

Blender? I barely know her!

The next step after I got the basic physics working with some silly sounds and keyboard/mouse input, was to create some models in Blender and get them in game. My idea was simple - create a platform object that had two meshes, one as the actual mesh and one that was the physics mesh. Sounded simple but was actually pretty crazy. Turns out making an object with two submeshes is actually no big deal. You just enter into edit mode for the object and select each mesh in turn and assign them to different materials. I named one material Platform and the other Physics. Then in my Ogre code after I imported the model I looked for the submesh with the Material name "Physics" and used the vertices from that Submesh for the Box2D Chainloop physics hull - oh yah, you have to use the latest version of Box2D from the repository to get this nifty hull type. The crazy thing about this process was I had to walk the edges in the Physics mesh to form a closed loop for the Box2D hull. Fun fun.

The biggest hiccup with Blender was getting the model with the two submeshes into Ogre with all the vertex data intact. When I used the latest version of Blender and the latest version of the Ogre exporter for Blender the files that were generated used shared vertex data, and when I tried to read that shared vertex data in Ogre it didn't exist! Crash-o-la. Solution? Use the older version of Blender and the older exporter that doesn't use shared vertex data and it works. Boom.


I chose to use the Gorilla GUI for Ogre because it was two files! - and I saw it in action in the Ogre forums and had to try it.

It's super basic and you have to do everything, but it is fast and once you get a feel for what it can do it just makes sense. I also found the demo console app to be really handy.

In the End...

I just didn't have enough time to finish. I wasn't supposed to be working on this alone, but my other teammates had other things come up. None of the art or animations were made and I never added the background music and ambient sounds that would have really helped it. Of course, even a legit background would have helped!

I learned a lot from the experience and did have fun and plan on bringing the game to a releasable state in the future. Until then I will return to OGE, My First Planet and Spacescape dev work in my free time.

Wednesday, July 6, 2011

Let there be Bogeys

(click to enlarge)

It hasn't been very productive these last few months. Got the usual family stuff that is, obviously, more important than this - but what I have done is experiment more with MyGUI and added bogey trackers to some mine objects.

The bogey trackers are actually 2D GUIe widgets and each corner of a box surrounding a mine is it's own widget. The performance ain't hot let me say that much. I'd like to also try 3D bogey trackers and actually put billboards in 3d space around the targets, but I kinda doubt that will be any faster.

I've also tried to smooth the input and framerate a bit more. In the process I implemented a mouse look system for the ships that is similar to the one in X3.

In the process I broke my multiplayer input so now client ships can't move, and there is still a bit of jitter when moving fast, ugh. I plan on attempting to fix the network bug and then do some renovations to the lasers & thrusters. After that it's some basic menus - joy! One of those menus should be a menu to jump to another planet or solar system, so that will open a whole new can 'o worms.

Here's a little vid I recorded - just shows the bogey tracker.

Sunday, February 20, 2011

Helpful Mercurial Tips

I spent a good bit of time trying to setup a Mercurial repository server on a Windows 7 Server that uses wamp.

I had to install TortoiseHg and Python 2.6.6 and the latest Mercurial in that order so that Mercurial would add it's libraries to the Python install. All that is important because the file that comes with TortoiseHg doesn't have the right Python modules you need to make the Mercurial hgweb.cgi work. Also I needed to install mod_wsgi on the wamp server which uses Apache.  Lastly, here is my hgweb.cgi

    # An example hgweb CGI script, edit as necessary
    # See also

    import os; os.environ["HGRCPATH"] = "C:\wamp\www\hg"

    # Path to repo or hgweb config to serve (see 'hg help hgweb')
    config = "c:\\wamp\\www\\hg\\hgweb.config"

    # Uncomment to send python tracebacks to the browser if an error occurs:
    import cgitb; cgitb.enable()

    from mercurial import demandimport; demandimport.enable()
    from mercurial.hgweb import hgweb, hgwebdir, wsgicgi
    application = hgwebdir(config)

Nobody Likes To Fly In Space - They Want To Drive

There are a lot of arguments out there about how much "fun" realistic space physics are and I am a believer that it's annoying to have to deal with so many ways to maneuver and the concept of the ship pointing one direction while flying another with the engines off!  So, I'd like to share with you how I decided to implement unrealistic but "fun" spaceship flying. Oh, and back in the day I did participate in the making of a game with realistic space physics.

Cassini Division 2004

To start with lets consider that most games use some kind of physics engine and those deal in forces primarily so we need to make each of the engines apply forces to the spaceship.  But we can't stop there because that is the realistic way and controlling a for-real spaceship can be so challenging that you don't have much time to deal with anything else like, say, shooting.  I mean, just think about all the controls you have to have in your ship to make your ship rotate in any direction and move in any direction!  Now, I have considered a game where each spaceship has a pilot and a separate player as the gunner, but lets not get distracted...

The easiest way to fly in space besides autopilot is to make it like driving - something that most people are used to.   You see, I want two things when I'm driving:
  1. I usually want to be traveling in the direction my spaceship is pointing
  2. When I hit the gas I want the spaceship to move, and when I let go I want it to come to a stop.

Handling the first issue is simple after you handle the second issue, just make the back engine the biggest and don't go putting big engines on the sides or front.  The second issue is not too difficult either - apply dampening to the spaceship so that it acts more like it is moving through liquid/air than through a vacuum.

By applying the dampening we ruin realistic space physics, but make spaceships easier to control.  Now since the ship is really moving through some kind of liquid/air it takes constant force to keep it moving and we now have an excuse for a fuel gauge and as an added bonus, when the spaceship enters the atmosphere or ocean we can use the same controls just fiddle with the amount of dampening.

Last thing I'd like to mention is the issue of 'max speed'.  When we have dampening then the 'max speed' of a spaceship makes more sense and we have the excuse for putting spaceships in the game with more powerful engines - where with realistic space games you can fly incredibly fast in a tin can with the help of some gravity, you just can't start or stop fast.

Oh, and collisions should work with our physics plus dampening model too and keep all that space debris from moving off into infinity where nobody could tell that it was once part of a destroyed spaceship.

On a more practical note, here is how I implemented the above physics model in OGE with Bullet.
1. Use btRigidBody::setDampening() to set the dampening on the Bullet rigid  body object
2. Use Bullet's internal tick callback to apply constant forces before the dampening is applied:
btRigidBody->applyCentralImpulse(velocity * deltaTime);
btRigidBody->applyTorqueImpulse(angular * deltaTime);

Tuesday, January 4, 2011

A New Year With New Goals?

The end of last year was somewhat unproductive for me on the planet front.  I was looking back at my calendar today and see that I spent most of my time doing real life work and being a dad.  I also spent a lot of free time playing games too instead of making them.

The two things I did work on that were planet related were OGE and Spacescape.  I made the developer list for OGE, and I might be the only active developer for now, but I hope that changes soon.  I spent most of my OGE developer time working on the RakNet networking and Bullet physics systems and have been trying to get a minimal networking example working with a small player controlled spaceship, some exploding mines and a planet.  Let's just say that networking + physics debugging can be annoying and I had no idea that making a spaceship NOT have Newtonian physics in space would be so challenging! - more on that later, maybe.

Spacescape got some bug fixes and minor features and I added the CMake build system to ease the pain for new developers and for me each time I develop on a new machine, especially one with a different OS like OSX. I also got my first and only Spacescape donation woohoo! and a bunch of feature requests, support requests and compliments.

On the table for this year are:
- Finish the OGE networking space example
- Re-asses and tackle placing objects on planets (vegetation, buildings, players etc)
- Fix planet underwater shaders
- Add simple clouds to planets
- Make the networking space example into a small game
- Release the planet plugin source
- Port Spacescape to OSX
- Divide Spacescape into "basic" and "advanced" modes so it is loads easier to use for the casual user.

Other possibilities include:
- Use method for computing planet normal maps
- Figure out additional light maps so we can have lights on the dark side of the planet
- Re-asses how distance/scale is handled when approaching the limits.
- Form a team of like-minded individuals

Hope you have a great start to the new year!