Contents

Introduction: 3D Engines

Setting Goals for the Engine

Feature List

Structures and Subsystems

Conclusion

Stucture and Subsystems

By now you know what your final goal is, and what your engine should do in order to reach this goal. Now it is time to get into the technical details, and define which subsystems and classes are needed, how they should work, and in what order they need to be written. Not everything needs to be described in full detail, but the more integral a subsystem is to the engine, the more important it is to lock down its functionality, or at least the interface.

There are three good reasons to spend time defining the system in detail before beginning.First, by scheduling the different tasks properly, it is possible to avoid people having to wait for each other to finish their tasks before being able to complete their own tasks. Bottlenecks can be discovered faster and circumvented, and you can see if the deadlines are achievable.

Second, a good schedule covering all tasks will also help the team to focus on what is actually important -the game - and not be fixated on working on the engine.

Third, there is a psychological factor: It seems much more manageable if there are a lot of small tasks rather than a few large ones, and it is easier to see progress occur.

How?

What I prefer to do is write down in detail which subsystems will be required, what their functionality is. Designing a directory structure and defining file types and their content is also useful.

Drawing charts showing how the different subsystems interact, and how the different classes and files are related can greatly help in giving an overview.

Recycle or Reinvent

One question to ask yourself is how much you want to use other people's work and how much you want to write from scratch. A lot of programmers take pride in doing as much as possible themselves, but again I think that it is more important to see what your goal is. If you are tring to impress a potential employer, I am sure he would be more impressed by seeing a programmer that gets the job done by any means possible than a programmer that can do everything himself but who takes much longer to do it. Sure, you learn a lot by doing everything yourself, but being able to work with other people's code is also an extremely valuable skill for today's developers.

For example, doing your own image loader will not help you to write a game faster, or improve the quality of the game. And unless you have some revolutionary ideas that no one has ever thought about before, a publicly available script system will perform almost as well as your hand-written one. True, you might get a little more performance and a little more user-friendliness by writing your own, but often the time is better spent elsewhere in the project.

Of course there are problems by using other people's libraries. Even if you can get hold of a preview version, the authors might want money if you use it commercially. This should not be a problem in our example case, as the team primarily wants to show its skills to potential employers.

Another problem is that the more the library is tied in with your engine, the more important it is to make sure that the library fits to your exact requirements, and the more important it is for you to tailor your engine to fit to the library. An MP3-player has very loose ties, and will easily fit into any engine, no matter how it works, but a physics library like Math Engine should be planned for from the beginning of the project. Once I spent days implementing a commercial library into my engine, just to find out that the way it did one certain thing was completely incompatible with my system

Debugging might also be a problem. Even though most of these libraries are well documented and thoroughly debugged, you might have crashes either caused by your own code or the library. But often the library source code is not released, and debugging gets practically impossible, and therefore it might be easier to implement your own system.

The question about what to do yourself and what to borrow from other people, like many other questions, depends on the team, the project and the deadlines. Again there is no clear answer.

The Schedule

Schedule important things to be done first. It sounds logical, but that is not always how it happens during a project, because different people have different ideas about what is important. The criterion that I like to use is whether people's productivity will go up when a subsystem is being worked on. I always have much of the ear- and eye candy at the very bottom of the list.

A good example is the rendering system. It is very important to get the objects on the screen quickly, both for the programmers to see if all of the code is working, but also for the artists to test the graphics and level designs. But on the other hand a feature like texture mapping is not very important at all. The gameplay programmer, the level designer and the modeller can still work fine without textures. Sure, it helps, but the productivity gains are marginal.

If it looks like it will take a while before your indoor routines will be ready, consider letting your artists start to create the indoor sections in a Quake editor.

Another example is the collision. Sure, collision is necessary, but getting the scripting system up and running is much more important, in order for the gameplay programmer to start working on player control, weapons, enemies and levels. This is especially important if it is a new, innovative type of gameplay, where lots of tweaking is expected.

Your overall goal should be to get as much performance out of other people as possible, and to spot bottlenecks before they occur. For example, if it looks like it will take a while before your indoor routines will be ready, consider letting your artists start to create the indoor sections in a Quake editor, and test in Quake, while you work on the code.

Modularity

If you are not used to writing large programs, you might not know how you should split up the different subsections, as they naturally all work together in some way or other. But it is a good exercise to do it, even for simple projects, and it helps you a lot as the project grows.

To give an example from my current engine, I have an input class, which contains joystick, keyboard and mouse, but which also contains my random generator and frame rate measuring. My reason for doing this is that this is practically all I need to have a complete record and playback functionality, and I do not need to access many subsystems to save a demo file.

Of course what you decide to have in each subsystem is up to you. But if you are aiming for later converting to other platforms or APIs, you should not try to shape the subsystem after the features or structure of the primary API or platform.

Another example of modularity is a complete plug-in structure. In my current engine, drawing functionality has been separated from the core, and a new effect, such as lens flares, can be added simply by writing a DLL, and adding the new effect to the elements in the editor.

Keep it Simple, Stupid (KISS)

A simple reminder: the less code you write, the less bugs there will be. Before you add a feature, make sure that it will be used thoroughly. Writing lots of highly specific code usually means more bugs than a little, more general, code that requires some parameters to be set in the level editor. And since the general code is run more often, and with different input, it will be much more thoroughly tested than the specific code.

Once again, this means less work for yourself, but more work (and more freedom) to your creative people.

Keep it Stable, Stupid (KISS 2.0)

My experience is that it is much easier to fix bugs as soon as they occur. If many bugs are left, you never know if it is a known issue or something new that causes a crash. And never work around a bug that you can't find and hope that it will disappear over time. This kind of bug tends to settle down deeply nested in your code, marry and have lots of little baby bugs all over the place.

Keeping your code more bug-free is also a blessing when it comes to milestones and demos. The bugs always resurface five minutes before the fat man with the wallet enters the door.

________________________________________________________

Conclusion