Design Fundamentals

I’ve been working on a new side project with a friend of mine. I’m thrilled to have found something that’s both an interesting challenge and something good to have on the side. It’s already teaching me new things that I would probably never have the opportunity to explore at work, for various reasons.

One of these things I’ve learned is that there are many things that I use in my coding are things that I take for granted but that are not natural or obvious to initiate coders. My friend is a coder who’s got some experience of coding through College, but I’ve realized that going from initiate coder to Software Engineer takes a lot of experience and that there are many things I’ve picked up along the way.

I got my share of that experience by creating a game engine in a startup, and doing a lot of other mildly complicated things. I had the fortunate position of having a colleague with whom I could discuss all design decisions to the bitter end, and the time to make a fair few mistakes and figure out how to turn them into successes.

What your path to getting that experience is, I can’t tell. Only you can walk that path, but at least I can set up some signs along the way to help. I’ll be starting a new series of posts called Design Fundamentals, where I’ll explore design concept that are fundamental to wrap your head around. Hopefully even experienced coders can gain something from these posts.

The posts will try to gather in one place only what a given design technique or pattern means, but also how to use it, why it’s useful and various tips and trips.

I’ll be using C++ as the language for these posts, as it’s my language of choice. Much of the information may benefit you if you’re coding in another language, and in fact the only recommendations I have for you when it comes to languages is pick one, and make it your native one. Become an expert in one language, don’t try to go wide. There’s a good point in learning to code in a few languages — but don’t make it your focus to become as good in all of them.

This post will serve as an index — all future posts in the series will be linked from here.

Let’s Make a Game Engine!

I occasionally get asked about the game engine I wrote back at independent games dev Limebird Entertainment. Specifically, people want to know how you start such a massive project. 100,000 lines of code later, it’s easy to point at each and every subsystem you have, explain what they do and how, and what the important design decisions were. You could probably even explain the reasoning that led to it being created at some point.

A Blank Slate by kiwikewlio

But where do you start? When you’re sitting there with a blank slate, what’s on the first row? The problem here is you’re starting something massive that you probably know next to nothing about. Do you open up your editor and create a file? Which file? Or do you start designing your architecture on paper or a whiteboard?

It’s a reasonable question to ask, and also an utterly pointless question to ask. My answer is “anywhere”. The important part is not where you start, but that you start — and that you keep going.

Identify one piece of code you need, and start writing it. You’ll be facing a million decisions anyway — what build system do you put all your stuff into to get it all to build on all your target platforms? How do you set up unit tests for your code? What version control system should you use? How do you design system X? How does that fit with system Y? All of these questions are things you need to deal with, and the only way to deal with them is one decision at a time.

One of the important things to realize is that the normal way of working in a development team doesn’t really mean much in this situation. How do you prioritize one component against another when you’ll need them all to get anything at all? Do you even know all the components you’ll need? You may think you do, but you’ll find out you don’t. The important part is to get going and keep going until you can start iterating properly on your code base.

Still, some tips:

  • As your first code file, pick something you’re reasonably familiar with to get going. Regardless of the scale of the project, there’s going to be some small part of it that resembles something you’ve done before — do that first, to get up and running. It helps to be in familiar territory when compiling your first class, because that one first class is going to be where you get your environment up and running.
  • Don’t over-engineer. Stay well within the bounds of what you’re reasonably certain that you’ll need. At this point, you want to keep moving to new parts of the project, so you can quickly reach a point where it starts doing something you want — so don’t waste effort on things you might need down the line. This sounds like simple advice but is actually quite hard, since you have no idea what you’re doing at this point.
  • Accept that whatever you do will be replaced. You’re new to the things you’re doing. The first things you write will be incredibly uninformed and will undoubtedly be rewritten a few times as you learn about the system you’re writing. The important part is not that you write the perfect system the first time around, the important part is that you write the system and learn from it. Once it’s running, you can go back and fix it. Sometimes, the only way to get a system just right is to have done it once before.
  • Make it do something. You can write core systems and design your architecture all day, and even with unit tests and all kinds of fancy techniques to prove to yourself that it works, you dont’ actually feel it until you have something that runs. Even if what you have is just a simple rotating triangle, the thrill of having a rotating triangle in your own game engine is a lot better than seeing the TriangleRotationTest pass.

So where did I start? We had a very brief discussion on how our design would look like, and what code we needed on a very high level, and then set off coding. I remember coding up our first version of a 3×3 and 4×4 Matrix math code on my laptop at my grandparents cabin in the countryside that summer. It was somewhat buggy, and I didn’t really know what I was doing… but it got the ball rolling.

The Classics

I spent last weekend at a LAN party. Some of my friends regularly arrange small LAN parties with 10-15 people, and this one was a good one with maybe 12 people who stayed there most of the weekend. Over the years, we’ve accumulated a bunch of games we always play, to the point where we play mostly the same (old) games every time. It’s a bit weird, really, and I’ve given it some thought.

I think one of the reasons is that there simply aren’t as many great LAN games being made any more. Most multi-player games tend to be aligned for Internet play, and as a result don’t work all that well locally. We played some Left 4 Dead this time, which is an awesome game for LAN as well as online (if you don’t have it — seriously, get it), but with the cap of 4 people for a campaign game that was sort of limited to the times where we had only a few people around, with most people choosing to go to bed or off to find a snack or whatever.

Another of the reasons I think causes this is, strangely, we buy more games. This seems counter-intuitive, as buying more games should mean having more games to play, but seeing as most games don’t play well together with pirated versions that means we can’t play games not everyone has. The result is that in general only one game will be a smash hit enough to have coverage at one of our LAN parties (The Orange Box did it for Team Fortress 2, and Left 4 Dead did this time around as I mentioned).

Some older games came with functionality that countered this — Total Annihilation could be installed as a Multi-player Spawn version, and when you started a game only a certain number of people needed to play the “full version” (with the CD in the drive) — one CD for every 3 players I believe. Really, more games should do this for LAN play.

There’s also a number of classic games that are just outdated but still best in their genre — even some games that are hardly known, and some forgotten with time. The first game that caused this was Carmageddon II. We played that game through countless nights of hysterical laughter for a huge number of LAN parties, until at one point the game’s outdated code simply wouldn’t work with newer computers and operating systems (not a huge surprise, as it was IPX-based for multi-player). We’ve mourned the game since, to the point of trying to set up a dedicated network with dedicated computers only to play that game (which failed).

Another game that stuck around was Rune, which chances are you’ve never heard about. When I first played it at a LAN party it was already an aging game, and then later I managed to dig up a single online store that still sold it and the multiplayer version, Halls of Valhalla. We bought a stack of copies of both games, and we’re still playing it every party. No other melee fighting game has come close to the same kind of frenetic fighting feeling.

Operation Flashpoint has also stayed with us, regardless of the “sequel” Armed Assault which didn’t really add much to the game, but had significantly higher requirements. Flashpoint is the one and only game we play as a sort of large-scale co-op experience. The game engine is slow and looks sort of bad but the game play is unmatched anywhere else. The built-in map editor (despite all its quirks) has kept the game going. Far-out mods like LEGO models also help provide endless amounts of wicked fun.

One more game is actually the indie game Soldat. It’s a highly addictive, frenetic 2D side scrolling infantry combat game controlled simply with the mouse and WASD to move around.

I could go on for a long time. Total Annihilation held for so long I thought we’d never stop playing it, but eventually we did. Some of the Age of Empires games really rocked (we actually played AoE II this time as well). Flatout and then Flatout 2 are some of the nicest aggressive driving games out there (pale, in comparison to Carmageddon II, but still). We played  the Trackmania games for a long long long time, though now I seem to be the only one who still loves it. We played Battlefield 1942, Desert combat, Galactic Conquest, BF: Vietnam, Battlefield 2, and Battlefield 2142 for a number of LAN parties.

The new stuff this time around came mainly from mods. I found this wonderfully wicked steam mod called D.I.P.R.I.P. Warm Up which is another version of the whole “Car with guns” theme, extremely well implemented with the wonderfully entertaining Uranium Run and Destruction (bombing) game modes. It seems to lack a following currently — it was a blast to play, but the most I ever saw was two servers up.

Of course, Battlefield Heroes is coming along nicely, but without the ability to easily play with friends it isn’t ready for a LAN party… yet. Still, it’s a great game for all those little periods of time where there was nothing in specific going on, and I think some of the guys got seriously hooked.

I wish some of those games were still available for people to try them out. Regardless of the lack of fancy graphics, some games are still the best games around. Also, suggestions for more games and mods to try appreciated!

WordPress Themes