The following post is my first contribution to #altdevblogaday, a collective blog about game development by a group of seasoned AAA and indie game makers. Read the original text (and the valuable comments) here. This is a follow-up post to my original introduction of Ginkgo, our game engine. This time I’m talking about our base tech and research.
We‘re a small independent game developer. Three of us have studied computer science (actually two are still in their master studies), one is a studied game designer and one a graphic artist. That’s our small but skilled team. The company is owned by ourselves and we’re working on our own IP’s from design, production and QA to marketing and support. We’re not only financially independent but strive for establishing our own independent infrastructure. That comes at a price – our wages are far below industry average – but every value we grow is a value of our own company. The largest project in a long list of actions furthering our independence is our in-house engine. The engine is written by just two guys, Peter, the main engine architect and CTO and me, the pragmatic coder that knows all the finishing moves. We’re very different, yet we had to agree on a lot of issues before starting the project. In this blog post I’m going to describe our starting points for developing the engine. There was a recent blog post on our studio blog that detailed why we started to write our own tech in the first place.
Setting Our Limits
The first thing we had to agree on was a number of very strict limitations for the engine. We can’t produce a state of the art 3D engine with our limited budget and manpower. We formulated general requirements and decided on limitations of the engine. The main goal for the engine is to provide us with a tech that we can easily port to any platform out there. Our business model highly depends on agility and the ability to cheaply bring our games to emerging new platforms like e.g. the Mac App Store or the iPhone. So the number one requirement for our engine is portability. We’re making 2D games. While our rendering architecture would be suited for 3D content as well (more about that later) we’ve decided to focus on 2D for now. The main reason for that decision is that it is near impossible for such a small studio to provide the amount of content a 3D game needs. In other words: We’d rather deliver a highly polished 2D game than the crude and simplistic 3D game we could deliver with our limited resources. Other things that were off the list right from the start are e.g. networked multiplayer and streaming content.
The cornerstones for Ginkgo that we agreed upon are:
- An easily extensible 2D engine
- XML as the main data format
- Optimized for physics-based games
- Component-based design
- The only STL classes we’d use would be vector and string (and some maps, but we might replace those later)
- No networked multiplayer/replication
The engine would have a slightly different architecture if the main design would have been mine and not Peter’s. I’m a C programmer and I’ve mainly developed highly specialized software for art installations (e.g. talking boots and music-playing pinball machines), realtime audio and similarly one-sided areas of application. I’ve singlehandedly coded a number of iPhone games, but none of them were technically very sophisticated. I’ve had my days in the Open Source development, too. Peter is a C++ programmer, on the other hand. Where I’m using a void pointer he’s reinterpret_casting. While I think OOP is only perfectly suited for a small number of tasks (UI’s come to mind), he thinks it is the basis of good design. We’re constantly fighting over these issues and I think that’s important for our engine architecture and our design process. Compromises often lead to mediocre results, but talking things out is a very important thing.
A Component-based Core
What we easily agreed on is the component-based nature of our engine. We’ve prototyped in the component-based Pushbutton Engine (Flash) and Unity before and we knew it would help us keep the increasing number of classes with overlapping functionality that usually get written during a game project. Also, Peter had stumbled across Terence Cohen’s GDC 2010 presentation “A Dynamic Component Architecture for High Performance Gameplay”. At the same the DoD movement – and especially Noel Llopis’ take on it – was at the centre of my attention. I see the C programmer’s mindset at work and I’m pleased. Insomniac’s architecture was the blueprint for our core engine architecture.
Here are some additional coding rules we agreed on early:
- Templates instead of instancing, where it’s possible
- Never call a virtual function in a component’s update
- As little inheritance as possible
… And What We’ve Built On Top Of It
Most low-level features we implemented are based on publications by established game engineers. I’ll go through them one by one.
- Our initialization and termination methods are lifted from Jason Gregory’s excellent book“Game Engine Architecture”
- Our main game loop is designed as suggested in Glenn Fiedler’s “Fix Your Timestep!”. The paper describes a fixed timestep game loop ideally suited for integrating physics independent of frame time. It is ideally suited for libraries that request a constant tick rate, like physics libraries. We’re using Box2D for our physics part.
- Many subsystems of the engine depend on iterating over contiguous arrays of components or structs as outlined in Tony Albrecht’s “Pitfalls of Object-Oriented Programming”. Our components feature an update function. But they contain the minimally necessary data to perform their functionality and are iterated over by component pool. Our component pool architecture will be featured in a future post.
- We did not implement Marcin Chady’s messaging architecture though nowadays I think we should’ve gone for it. Instead, we access components directly if a call is time-critical or via delegates if we want a leaker link between them. Component-to-component communication will be a different post.
- Our rendering subsystem is following the guidelines outlined in Christer Ericson’s “Order Your Drawcalls”. We have buckets of arrays of faces that are sorted according to a render mask. More about that in a later post.
- Our particle system was designed according to Lutz Latta’s “Building a Million Particle System” slides from GDC 2004. I don’t know if I should write too much about our particle system. Maybe once it’s fully integrated into the engine. Currently, the main downside is that every game object can only have one single particle effect attached because the emitters are components just like the any other blob of data.
The Future Is Bright And Full Of Pragmatism
Now that you know where we started I can describe how we kicked off the project in the next post. I would also like to think aloud if the development of your own tech is even viable for a micro-studio like ours and how we manage to focus on games and develop our own tech at the same time with only one team consisting of five people. We’ve had our first user test with a prototype of our next game last friday, and it was awesome to see our engine (and the game) in action for the first time I will write about our upcoming game in the future, too, but it’s currently top secret.
If you have any questions or want me to focus on specific engine features, just tell me and I’ll gladly write about it.