Content on this page requires a newer version of Adobe Flash Player.

Get Adobe Flash player

Story

Sweet Water is the monicker ironically given to an infamous prison ship floating out in deep space. All the worlds' toughest criminals are sent there to be isolated from society. When an unkown force causes a disruption on the ship, your character seizes his chance for escape.

Game Mechanics

Sweet water is a 2D platform shooter with 3D elements. The goal is simple enough: escape Sweet Water by fighting through the guards with whatever weapons you can find. The world is physics-based through the Bullet Open-Source physics engine. The emphasis is on strategic combat, ammo management, and exploration.

The game controls are as follows:

Key Technologies

Particle Systems

One of the first things we decided this game needed was cool particles. So we set about making an editor for particles that could export directly into our game. This way, we could edit particle effects in real time and find the perfect settings to match the effect we were going for. Our particles are texture-mapped 2d sprites. We implemented bill-boarding on the particles to ensure they look right regardless of camera orientation.

Particle Editor
The particle editor in action.

Resource Manager

With the size of our engine and the number of assets we had, we wanted an easy way to manage all of this. Our solution was a resource manager that controls every asset of our game. Sounds, textures, fonts, models, and shaders are all added to our game via .ini files. Within these .ini files, we specify all the parameters for each assest and they are attached to each material in our game. The resource manager loads in each resource dynamically on-demand. If the resource is already loaded in our resouce manager, it just returns a reference to the resource instad of loading it again. This allows us to swap out a sound effect or change the blending mode of a texture without having to re-compile our game. A major time-saver.

Pixel Shaders

Another big priority for us was per-pixel lighting. This was implemented in a pixel shader with GLSL. We also decided to implement normal mapping on all the textures in our level geometry. There's not a lot to say on this subject, so here is a picture illustrating the difference.

Normal Mapping Difference
The left is without shaders, the right is with. The difference is fairly profound.

Level Editor

We discussed different solutions for creating a level editor. In the end, we decided the best solution for us was to design our levels in 3Ds Max. We wrote a plug-in that exports our level geometry directly into our game. This allows us to bind textures to our level and place enemies or particle emitters within 3Ds Max and have them spawn in the appropriate locations in our level.

GL State Manager

As we were working, we found ourselves with lots of bugs caused by incorrect GL states. Inevitably, someone would leave depth test on or disable lighting. This would result in a lot of tedius tracing through our code to set the correct GL states. Eventually, we decided to implement a GL State manager to do this work for us. Each material in the resource manager now also specifies the GL states that it needs to draw that material. The GL State manager will set up the correct environment automatically and draw the entity.

References

Libraries and Tools