After giving it a lot of thought I settled on a central theme for my #altdevblogaday articles. My first series of posts will be about Ginkgo, our new in-house engine. I figured that this is is the right place to discuss its main features and get as much feedback as possible.
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. 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 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.