I read somewhere that the blockbuster title 'Gears of War' had only about half a million lines of C++ code: ~250,000 specific to the game, and ~250,000 for the entire Unreal 3 engine.
I was surprised. Steve Yegge seems to be pretty well known as a programmer, or at least, as a programming blogger, but his 'modest' web game was more than a million lines of Java.
Apparently, if you're disciplined enough (they coded in layers, much of which was in a strictly functional style) you can do a lot with a little.
Ah.. Gears of War is also a single player game. Steve's game is closer to an MMO. Once functionality needs to happen across 60 different computers in a synchronized fashion, code can get pretty complicated. And sometimes a multiplayer setting can actually force you to write functionality that only makes sense in a multiplayer setting.
For example, Steve's game levels are tile-based, but I doubt he restarts the server whenever he makes a small change to a level. That means the level needs to be editable at runtime, which means changes need to be streamed dynamically to all clients that might be watching. The changes also need to be serialized to the database periodically, so that they aren't lost when the server does reset.. And you need code to make sure two players' views of that level don't get out of sync if they are both editing it at the same time. That tileset loader code you wrote now needs to be able to support additional tiles at runtime, which means you need a collision tree that can be rebalanced quickly without hogging valuable server resources. And what happens if a player was standing in a valid tile, but you just removed that tile? You get the idea.
My employment's game is easily over a million lines of code at this point, and the client alone is about 700,000. Not only that, but the client is completely recompiled for every change - so it takes about 10 minutes from the time you've made a change until you've tested it. People avoid compiling the engine like a genetically-engineered flesh-eating virus, so you're coding for maybe hours before you test all your changes. And since debugging requires changing code, each mistake costs you another 10 minutes. The whole process is like putting together a 10,000-piece puzzle upside-down.
Some bits of advice for large C++ projects:
* You need to have split your functionality into about 20 different DLLs before you get to the point of being an oh-god-why-is-it-so-massive project.
* You must write most of your objects using the interface pattern (a pure virtual interface in the header file, and your implementation exclusively in the source file). No private function or variable declarations should be written in the header at all. This facilitates extremely fast compile times. Here's an example of what I mean: http://dl.getdropbox.com/u/315/example.cpp
* Sometimes you need to ignore what senior programmers think is best to get your goals accomplished. Remember, they got you into this situation in the first place.
Just because you can generate a hypothesis doesn't make something true. Its pretty difficult to compare the difference in required code for a modern 3D engine, with lots of single player functionality like scripting and AI, and a multiplayer game with a lesser graphics engine. It should be noted that there are some simple multiplayer games that are hardly any code at all though. 500k lines all up for Gears of War certainly seems massively less than the industry average for that kind of project.
Just because you like Yegge's post and/or game doesn't mean his code needed to be that big. Judging from his post on code size it's not like he cares particularly.
I'm intrigued that nobody has mentioned UnrealScript in this context. I'm pretty sure they haven't dropped that for UE3, and language-wise that's apparently somewhat like Java. Historically, Unreal games have had most of their logic written in UnrealScript.
And yeah, 500000 really isn't much in gamedev. I worked as an engine programmer for the year following graduation and worked on a almost-2-million-LOC behemoth (including tools, so the game was probably nearer 1-1.5m) which wasn't an MMO or even had that much data to look after at run time. (the Wii only has 88MB of RAM)
I can echo the long compile and linking times mentioned elsewhere. Almost none of the code used templates, which would have been an obvious candidate for driving up the compile time. Linking really isn't fast anymore either once you hit a couple hundred compilation units.
Of course, the code was a complete mess. Few people cared much about the quality of the code base, particularly as the game was released about 9 months late and everyone just wanted it out the door. (it was delayed mostly by management pushing for features rather than having bugs fixed for the 2/3 of development and large-scale changes imposed by the publisher late in development) Not a particularly pleasant experience, but boy did I get to practice my skills in understanding and debugging badly written, undocumented code. Typically code that nobody who still worked at the company had ever touched or seen. Or maybe that was the crazy overtime talking.
Just because you can generate a hypothesis doesn't make something true.
No, it doesn't. But I've seen what I described happen many times over three years.
Its pretty difficult to compare the difference in required code for a modern 3D engine, with lots of single player functionality like scripting and AI, and a multiplayer game with a lesser graphics engine.
It's not. There are many shared concepts. Scripting and AI, for example.
Just because you like Yegge's post and/or game doesn't mean his code needed to be that big.
That seems like why he wrote the post. Also, my likes and dislikes are irrelevant.
I'm not doubting adding networking adds complexity. I don't think the comparison of complexity between the graphics and AI of gears of war vs the networking of Yegge's game is easily made. The interesting thing about Gears of War is that most titles of that caliber take a lot more than 500k lines. Yegge's game as a comparison point seems pretty fair to me, and I just don't buy the fact that the extra networking necessarily makes the code so much more complicated than Gears of War - thereby invalidating the comparison.
It's not the networking. It's the fact that changes need to happen at runtime, and sync to any number of clients that may be watching.
Also, your hypothesis that the prettier game the more complicated one is false. 2D physics and AI can be horrendously complicated, or elegantly simple. There's no way to tell just by looking at the game, except on a very rough level. Take the game Gish for example. I don't know how complicated that little blob's physics is, but it could be extremely tricky.
Amusingly, the game rules are the least complicated component.
I meant syncing the game state to be included under the term networking. Amusingly, Yegge's post about the length of his game was all about how massively bloated it was because of Java. His own estimate of what size he would like the game to be was 150k-200k. Apparently impossible in Java, but presumably what he felt he should be able to achieve that even given the game's distributed state management.
You need to have split your functionality into about 20 different DLLs before you get to the point of being an oh-god-why-is-it-so-massive project.
How does separating out code into DLLs help? Linking is fast.
You must write most of your objects using the interface pattern (a pure virtual interface in the header file, and your implementation exclusively in the source file).
This is something which you should always do -- not just for large C++ projects. Separating interfaces from implementations is ALWAYS good design.
Unfortunately, no. The linking step at work is the most time-consuming. Visual Studio takes four minutes (and growing) to link the client, no matter how small the change.
By the way, do you have any samples of C code from your project I could read? I'm writing my game engine in C, so I try to learn as many different C styles as I can.
I totally agree with the breaking up of the project to smaller DLLs, as long as you write your tests for each DLL separately it can save a great deal of time, as you only have to recompile the DLL&test with the bug-fix.
Though neither persistant nor massively multiplayer. Both of those things add a huge amount of complexity. I don't envy the job of one person writing an MMO - although I guess it's a possible direction I'll be taking in the future.
I enjoyed the following at the end of the article (with context added by me):
Think about that last analogy: A million [lines of code costs a million] times the cost of the flash chips [it is stored on]. Yet accounting screams over each added penny in recurring costs, while chanting the dual mantras "software is free," and "hey, it's only a software change."
I've worked at a place like that before. They would pay a full team of developers for several months to roll our own custom solution to something we could have bought off the shelf for $1000. People just don't see software as expensive to develop... and unless it's open source, it is.
They need to come up with a new metric. LOC is so wrong for so many reasons. Running tested features seems like a good way to measure project progress but I don't know how it would relate to overall project complexity. http://www.xprogramming.com/Blog/Page.aspx?display=RunningTe...
I was surprised. Steve Yegge seems to be pretty well known as a programmer, or at least, as a programming blogger, but his 'modest' web game was more than a million lines of Java.
Apparently, if you're disciplined enough (they coded in layers, much of which was in a strictly functional style) you can do a lot with a little.