Upcoming Events
Southwest Gaming Expo
11/20 - 11/22 @ Dallas, TX

Workshop on Network and Systems Support for Games (NetGames 2009)
11/23 - 11/25 @ Paris, France

ICIDS 2009 Interactive Storytelling
12/9 - 12/11 @ Guimarães, Portugal

Global Game Jam
1/29 - 1/31  

More events...


Quick Stats
6760 people currently visiting GDNet.
2341 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!



Link to us

Link to us

  Intel sponsors gamedev.net search:   

A Hobbyist Game Engine Post Mortem


What Went Wrong

1 - Creeping features

Even though I had carefully laid out my plans, I could not help adding a few more features. I added:

  • To AI scripting system: basic subsumption and rule-based system.
  • To texturing: multitexturing and bumpmapping.
  • To rendering: render to texture interface.
  • Faster font rendering.
  • PNG bitmap loading.
  • OFF mesh format processing.
  • A XML file parser.
  • A scenegraph file format.
  • A curve generator using three different methods
I stopped myself before I added any more features: I then was considering mirror rendering and thinking about basic shadows. Creeping features always occurred when looking at/playing other games (a shame I tell you ? ). I wanted to add more chrome to my display (bump-mapping, render to texture), to diversify object loading for simpler game resource integration without using third party converters (PNG and OFF for example).

I stopped myself when I understood I was thinking more in terms of engine elements than direct implementation. This proved to myself that I had finally come to understand how a graphics/game engine works and how I can extend such an engine, even if it is a third party engine.

2 - Not made here syndrome

Under the guise of learning things (or not having external dependancy), I discovered I was in fact writing code and reinventing the wheel. I wrote for example a file system which let me indifferently load a resource from a package or from a physical disc. Even though it worked, it was of lower quality than code available on the Net which was better realized, cross-platform and compatible with multithreading (like PhysicsFS by Ryan C. Gordon for file system abstraction).

After discovering this, I created interfaces for any features I wanted to integrate so that I could add third party elements and still provide a unified interface. This had an unintended good effect: it helped to isolate poorly designed 3rd party interfaces (which at compile time created a lot of warnings). Thus I learnt I could use third party libraries provided I designed an interface to isolate from my code (this also simplified testing third party libraries since all I had to do was implement the library using my own designed interface). I ended up using Audiere and IrrKlang libraries for the sound system part of the engine.

3 - Side development

This was a direct consequence from both previous problems. When I did not have existing code, I first realized a simple small application as a proof of concept. When the proof of concept was ready, I kept rewriting it until I was satisfied with its design and architecture. Once done, I refactored the code for integration within the engine. Some development went right (subsumption system), some went wrong (file system), and one went utterly wrong (sound system). I spent a lot of time rewriting the same kind of code over and over when I could have designed an interface and be done with it (which I ended up doing for the sound system to link with a 3rd party library).

4 - Cross-platform?

Cross-platform development is demanding and there is little information on the Net. Moreover, there was one obstacle I did not have time to overcome: to test the engine on a linux box. I used virtual machines to create linux boxes but I encountered many other problems like learning how to properly configure a linux system (moreover on a virtualized configuration). As a hobbyist, I did not have the time to both learn the linux side and develop the engine. So I used whatever information I had (taking care of endianness, strictly defining engine types, multiple header inclusion depending on preprocessor directive, …). Still, even though the code is very clean and follows my home-made rules for cross-platorm, it never was tested on a linux configuration.

5 - Planning

I had originally planned to develop this engine during one year as it seemed realistic. However, I forgot to include editors in my planning, which were sorely needed for creating resources for my samples, and of course additional features were not even planned at the beginning (more on the spot when I decided I needed that feature). Moreover, I had not taken into account the extensive debugging for cross engine bugs (e.g. when some state changes under OpenGL pollute the rendering of some scene nodes).

It took two years to develop the engine due to all the previous faults. Still that was quite tight since I was a hobbyist married with a kid and with a day-time job. But I did not want to quit before all the planned features were implemented and the engine stabilized. I am however glad that all added features were interesting in their own since I kept learning new areas I was not familiar with. Had it not been the case, I would have had a big morale problem. Managing ones morale is essential to progress in such a project.

6 - Personal objectives

Since I added new features to the list and created editors, this meant that the project was beginning to take a life of its own: I understood that I would only program to maintain and evolve an engine (interesting since you do learn a lot of things, mildly to not rewarding if you do not take care of your morale and if nobody use the engine). I had to choose between developing this engine or write small games and small code projects using more third party libraries.

Conclusion

I wanted to learn developing a cross-platform engine with no external dependencies. The goal is partly achieved: I learned how to develop, test, stabilize, maintain and document an engine. I also have completely implemented the original feature list. The engine however is not cross-platform until tested on a Linux box.

When comparing with the list of engines at Devmaster.net, I found out that it was quite a nice little engine that could be evolved and satisfy a few basic needs. Still, during the two years of my engine development:

  • other engines also improved and are now more than sufficient to satisfy the needs I had.
  • I developed all the necessary skills to understand and adapt these engines to my needs.
  • New hardware architecture appeared (dual core 64-bit machines, and more to come). Even though I took some steps to ensure no side effect with ulterior compilation on 64-bit platforms, I cannot guarantee this. In fact this means more tests to do on different configurations and I cannot virtualize to insure the stability of my engine on 64-bit architectures.
Was it a waste of time? Definitely not. The knowledge I gained was invaluable (understanding quaternion, refactoring code, scenegraph optimization…).

Can a lone programmer (even a hobbyist one) succeed writing an engine? Yes, provided she has previous succesful programming experience, she plans carefully and focuses on features that are within her reach. Success in realizing the plan brings enlightenment.



Contents
  What Went Right
  What Went Wrong

  Printable version
  Discuss this article