Pieces Of My Game Engine
I want to talk a little bit about exactly what components are being used in my game engine. I’ve spent the last few months assembling an engine from a mixture of custom-built software and Open Source components. It’s built using C++ with an emphasis on modularity, a clean-coding style, simplicity and speed.
I’ve never built an engine before, but I’ve worked with plenty of them, both commercial and proprietary. A well designed engine will make or break an entire project. There are lots of way a game engine can go wrong:
- Evolution: It works for plants and animals, not for software. The engine evolves from earlier projects in a haphazard manner resulting in a Frankenstein of components and workflows. These situations result from short-sighted studio executives who emphasize immediate results over long term viability. In a move that would make any sane developer cringe, the boss proclaims that starting from a clean slate is, “too risky” (when the exact opposite is true).
- Fancy Engine, No Workflow: So you’ve got high dynamic range lighting, a killer hierarchical decision-tree AI system, physics-based animation synthesis and a list of other ‘box features’ ? Congrats, but it doesn’t mean jack S**T if it takes the artist 4hrs to export an animation and get it in the game. Along the way, the poor soul is forced to try 20 different methods he/she gleaned from 20 different wiki pages scattered across a network of documentation that seems to be in a perpetual state of ‘almost being done”.
- “We Can Do Better Than Those Guys!”: Yes, you could build your own engine to make that killer FPS you’ve always dreamed about. But is starting from scratch ever a good idea? You have to ask yourself, do you want to build an engine, or a game? How much time is it going to take to make something that can go toe-to-toe with Unreal or idTech? Chances are you don’t have the time or the resources, so shrug off the attitude, get realistic and look into licensing.
I thought about #3 long and hard before deciding to make my own engine. Ultimately, I decided that for the game I wanted to build, there was nothing available that could meet ALL these requirements:
- Run on Mac/Linux/PC using OpenGL acceleration and C++.
- Simple to learn and extend.
- Utilize a 2d physics engine.
- Use a ‘real’ content creation package as a level editor.
The last point was the real kicker. I’ve invested years in learning Maya and 3ds Max. Why would you flush that down the drain to re-learn yet another package for level design tasks. I had read this article on using Maya as a level editor and I had a strong desire to give this a try. It also jived with my main rule of development: “keep it simple”. Not having an entire extra level-design application to worry about meant I could concentrate on what mattered most, the actual game. That’s saying nothing of the advantages of having all of Maya’s modeling and texturing tools available directly in my level editor… how cool is that!!?
So, convinced that I probably should make my own engine, I went about researching if this would even be possible. I knew generally what components I needed. I spent a few weeks Googling, reading docs, pouring over source code and testing, testing, testing. What I came up with was a list of components which would theoretically do the job. With the exception of a few components which turned out to be duds, this original list turned out to be exactly what my engine currently uses (after many weeks of integration work).
So here it is at last. A list of components and the solutions I’m currently using. Some of these are likely to change as I get deeper into development. But for the most part, it’s a complete list:
- Cross Platform Windowing/Input System: First things first, you need a window to display your game in. I experimented with SFML (Simple and Fast Multimedia Library) but eventually decided to use it’s big brother, SDL (Simple Direct Media Layer). I can’t say enough nice things about SDL. It was written by the lead software engineer at Blizzard, Sam Lantinga. This library provides windowing, joystick, keyboard, mouse input and sets up the context for OpenGL (which is non-trivial if you want it to work across Mac/Linux/PC).
- OpenGL / GLSL Graphics: Yes, I’m building a 2d game. But I want a high-definition, high-fidelity, smooth-scrolling experience. Hardware acceleration is the only way to go (drawing HD sprites with the CPU is a sure way to kill your framerate). I also wanted to do pixel shader special effects so DirectX/HLSL or OpenGL/GLSL were my only real options. And since DirectX only works on Microsoft’s platforms, that left only one choice. These technologies are not without their quirks. I especially hate the wildly fluctuating hardware capabilities on the market. Finding the lowest common denominator that I want to support is something I’m still working on (it looks like OpenGL 2.0 will be it).
- OpenAL Audio: This is a great cross-platform audio mixing library. I can play lots of channels of audio at once and it even takes care of positional effects (which was something I initially thought I would be implementing myself). So I can provide a location a sound is playing from and OpenAL will take care of attenuating the volume and stereo-mixing it so that it sounds like it’s coming from the proper direction/distance relative to the player. Cool.
- Box2d Physics: Another Open Source gem. This is a truly impressive little physics engine designed and optimized specifically for 2d simulation. Erin Catto is the owner/originator of this project on code.google.com/p/box2d/. My ex-colleague and friend, Dirk Gregorious wrote the block solver used in Box2d which makes it a blazing fast and stable simulator. I continue to adopt the latest developments on Box2d from the Google code project. It’s an essential part of the gameplay for BEEP.
- FreeType Font Renderer: An Open Source font rendering engine. If I need to send text to the screen, it all goes through the freetype library to get converted to a texture before being sent to OpenGL.
- PNG Textures: I’m using the .png file format for textures. It has excellent support for alpha masking and ‘just works’. The folks at www.libpng.com have done a fantastic job.
- TinyXML: I’m using XML as the ONLY file format for transferring game data between my level editor and the engine. EVERYTHING goes through XML (meshes, rigidbodies, animation etc…). I refuse to use a binary file as an intermediate data container. I want to be able to READ what is going into my engine. I feel strongly about this because I’ve never been able to understand why so many programmers use binary files (I know they are smaller, but who gives a rat’s ass about file sizes these days?). Anyway, TinyXML is a great Open Source XML parser for C++. Just include a header file and away you go…
- GLee: If you want to use the latest graphics card features, you need to go through a few steps just to get the hooks in your C++ code. GLee automates this process across PC/Mac/Linux. Without out it, I simply wouldn’t be able to do all the fancy framebuffer object off-screen rendering, pixel shaders, post processing etc…
So those are the pieces I’ve scrounged up from all four corners of the internet. What follows is a list of features I’ve created myself:
- Scenegraph/Animation System: Skeletal animation is the basis of 99% of the animation you see in games these days. BEEP is no different. My scene graph allows exporting skeletons with animation from Maya to playback in the engine. Skinning support is forthcoming. None of this is particularly revolutionary or anything, but it does take some time and effort to get working right.
- UI / Interface System: I searched high and low to find an Open Source GUI that I liked. I even tried a few that I thought could work (I won’t name names). Alas, I decided it would be best to build my own. It’s pretty simple right now, just buttons actually. But I will be adding sliders and possibly text input too.
- Gameplay: A large part of my efforts now are in designing gameplay code. Things like player death, checkpoints, health and AI. This is in fact my main area of development right now. It’s taken a LONG time to get here, but I’m finally coding a game, instead of just an engine!! With so many pre-requisites getting in my way, it’s really nice to finally be here.
- A Million Other Things: I added support for mesh rendering, a shader system, a texture manager, viewport culling, rigidbody contact manager/callback system, force fields, projectiles, etc… I keep track of little things like this in my online bugtracker and implement them whenever I have a spare moment between large tasks.
Now that’s a pretty exhaustive list of engine features. In my next article, I’m going to switch directions and talk about about the art-style and art-creation pipeline.
But for now, it’s back to work for me. Today I’m working on a raycasting perception system for AI and player navigation.
-
kiaran
-
Chris Luce