While that’s an interesting idea – maybe for another day – I’m interested in looking at larger-scale problems than that. And since I’m lately itching to write a renderer again (the last one was 1998), that’s where I started.
The goal of this project is to explore the “pressure points” in writing games in C++1, to see if in some of these areas, the pain and delay can be alleviated. To make it as painful as possible, it’s of course going to be cross-platform. That means OS X and Windows, unless somebody wants to gift me a devkit for Xenon or PS3…
And even after that first bit of code, just hoisting out the most basic platform abstractions, a few lessons are to be had.
I hope to keep the preprocessor mostly banned, except in some very limited areas where the libraries abstract actual hardware. It’s cause for a lot of confusion in real-world projects, so let’s try to keep it out. It is interesting to think if you could achieve the same effect without a preprocessor, just with language constructs – and what those would be.
Too Useful to be banned
Some C++ features are too useful to be banned. Writing a render engine in pure C, as Vince suggested, is possible, but tedious. So I guess I have to loosen my stance and allow some features to creep back in.
Sure, you can prefix every single function, but it’s a messy business. It carries no performance cost to have them, so they’re in.
Mostly, to get the convenient syntax of member function invocations. On non-virtual members, this carries a predictable cost. (I.e. I can predict what code the compiler will generate without having to look up the class API). Casts and copy constructors are still out, since they can implicitly generate code that I won’t be aware of when examining code.
So, basically, C-style structs that have member functions and access protection are what’s allowed.
With both of these, I’m curious about their impact on compilation time.
Some features are missing from C++ that would be extremely useful:
Yes, the new standard has them – but at a high readability price.
Header files are a completely pointless waste of time, a remnant from the late 70’s. As a side effect, that would allow mapping platform-specific enums to abstraced enums without having to expose the platform-specific header that contains them.
Braces/semicolons do add a lot of noise. Can I get a whitespace-scoped language, like Python?
There are many issues I don’t care about right now. Consequently, I’ll go “off the shelf” with them.
I really don’t want to write the 22nd implementation of a vector class, thank you. I’ve written enough of that. Since they’re all owned by my employers, I’m opting for an open-source one. So far, CML is the chosen one. It is, rather poignantly, making the point that this is a facility that’s sorely missing from C++ for game development.
Window System Code
While I really do want to examine the effects cross-platform code carries, some things are too gross to be touched by humans. I started out using GLUT, but its shortcomings meant native window handling. That’s not what really concerns me here, so I’ll be basing things on SDL for now – at least for purposes of handling the windowing system.
I didn’t need to touch that yet, but if it comes to that, there’s dlmalloc, or Fluid Studios’ memory system (no link, since their atrocious website doesn’t have links – it’s all Flash. But you can find it by starting here), and probably many others. And unless I absolutely have to touch memory management, I don’t want to go there.
I’m not sure if that’s even relevant for much longer. I see the number of teams writing entire engines definitely shrinking, since it’s very expensive. Often, off-the-shelf engines (or something another team in your company wrote) will be good enough. Since I’m a systems-level gal, I hope to stay on a team that works on an engine, though. Hence the focus on it. ↩