Categories
Game Development

The more I use Vault the more I like it

So I reinstalled Vault and have been using it locally without a problem for a few days. The more I use it, the more I like it, to the point now where I couldn’t see working without it. It’s so easy to use, and has a very nice search tab where I can find all renegade files, or all files not checked in, and various other search filters.

Apparently the 403 bug with Vault was due to some firewall or proxy restriction at work. I’m trying to find a way to get around that. Once that’s done then I’ll buy a registration.

Categories
Game Development

You never have a second chance to make a first impression

My title is a cliche but I was reminded of it recently as I was looking for a graphics engine for my web-based MMOG. While there are free engines available, Ogre 3D probably first among them, people who expect to make money generally work harder than those who don’t – RakNet vs. HawkNL being a prime example. So I was prepared to pay for a low cost graphics engine, and one of these is Power Render. I took a first glance at their website. Had this been the first time I encountered Power Render I would have taken a second. But instead I closed the page without further consideration. This is because I had used it about 6 years ago in version 3.0 or something like that. I wasn’t that great of a programmer then compared to now and had even less tolerance for poor API design. In short, I was pissed off that after a week I couldn’t even get the library to compile (no project files were included) and that I had wasted $150 or something like that because you had to pay before you could get any code. I wrote a negative review on the gaming website I was running (though the website had nothing to do with programming APIs) and remember to this day not to use Power Render.

Is that logical or fair? Probably not. It may be the world’s best 3D library right now for all I know. Will I ever look at using it again? No. It probably has working project files now and may even have up-to-date documentation but I’ll never know because I already wasted $150 learning that it didn’t (back then) and don’t want to go through that again.

The lesson to be learned is not so much to let people use your code before paying for it (though that is important if you don’t want forever pissed off customers), but that you only get one chance to launch your product. I got more of a proportionate gain in traffic for RakNet on launch day than on any time since then, except possibly when I started giving it away for free two years ago. But that was a bad thing because a few months later I’d find a crippling bug, which I’d fix shamefaced and wonder how anyone could have used RakNet with that bug. Then I’d do some order of magnitude performance improvement and be shamed at anyone could have seen how sub-optimal my library was. And so on. The RakNet of today doesn’t really share a single line of code with the RakNet of 4 years ago, is a million times faster, and has 10X the features. Yet someone who looked at RakNet 4 years ago wouldn’t have the impression of the hyper-fast full featured RakNet of today, but the slow, weak, clumsy version of then. In fact, the GameDev.net review still refers to the RakNet of 4 years ago and this is analogous to the impression many people probably have today of the library.

The same holds true in game development, but it’s even worse. Because with a programming library, if someone doesn’t buy your library today that’s OK because someone 4 years from now who has never heard of it might and you’ve been working on it the whole time. But with a game, once you get your two weeks of shelf space you’re gone. Nobody will buy your game 4 years later: They wouldn’t have heard of it and even if they did there are games with 4 years worth of graphics advancements to compete with yours.

In every project I’ve ever worked on, game development has gone on to the very end, with a month of bug testing, and that’s it. There was no dedicated time spent on game design, or fun, or balance. These things were worked on simultaneously while the levels were being built and the game programmed. The problem is that if you make a level that’s not fun, or an AI that’s too hard, nobody knows that and even if someone did it wouldn’t matter because the person responsible is the same person who created the problem and they probably don’t agree with you. What might be fun to a programmer who plays the game 10X a day for years might not be fun for someone who has never seen it before. So these games are released, and they have good graphics, and they may be novel, but nobody is playing them 6 months later.

To make a classic game, or programming library, or probably a lot of other things I think it’s extremely important to look at the issue of quality over completeness. Blizzard does this, and it takes them years to make a game, but they are making something like 10 million * 15 dollars a month right now with WoW where other MMOGs are considered a success to get 1/100th those subscription rates.

I think for my own MMOG I’m going to spend X months developing it, then force myself to spend another X months polishing it, with closed beta tester feedback the whole time. Because I only get one shot to launch, and if I can pull this off I will be pretty wealthy. But if I fail, I will have lost years of my life and a ton of money.

Categories
Game Development

Going back to web-based game

If you look at MMOG Chart you’ll see this little game called Runescape. It’s a web-based MMOG. The graphics are terrible and the gameplay simplistic, yet they are raking in the money and have more subscribers than Everquest. Why? Lets look at what is different between Runescape and the other MMOGs.

1. The graphics suck.
2. The gameplay is simplistic.
3. It’s cheap.
4. It runs in a webbrowser.

Since the first two are negative points, the conclusion must be that it’s the last two points that are selling the game. More than this though – if your graphics suck you don’t have to spend as much time or money on graphics, which is a big plus to me in my situation.

So I’m going to avoid the work of migrating the Reality Engine (although it is a great engine) and continue with my original plan of using Irrlicht in a web browser. Irrlicht just released version 1.0 too so I’m going to take a look at that soon.

Categories
Game Development

I will never work for EA

After reading about the EA spouse settlement I’m glad I never went to work for EA.

About a year and a half ago EA contacted me after I sent in a resume. I was really excited by this because everything on the phone went very well. I spoke to a programming department head and we really hit it off. Over 3 days, the EA recruiter contacted me 3 times by phone and we worked out a (in hindsight, low) salary of $75,000 a year. I was all set to move down there. On a Thursday he said they’d buy me plane tickets to fly down on Monday and speak to them in-person. I never hear back regarding confirmation of the flight times so I write three times on Friday and call both him and the person I interviewed with on the phone. No response.

So Monday comes and goes and I assume they lost interest and rudely just stopped replying to my emails. But about two months later the recruiter sends me an email out of the blue, apologizing with the excuse that he had to fly out, told his staff to handle the arrangements, which they didn’t do.

That sounds like a bunch of crap to me. First of all, if he flew out, does that mean he stopped checking his email? This is a connected world. It’s not like I sent one email either. I sent multiple emails, ending with something to the effect of “Hey it’s Monday and I didn’t hear from you. If you lost interest please let me know.” And why would it take 2 months for him to follow up? Furthermore, I just wrote to him and got an answer like an hour before I sent in my inquiry about the plane ticket. Did he fly out in that short period of time, making no mention of this or that I should expect to hear from his staff?

If you don’t want to hire me, fine. If there is a canidate you want to try first, go for it. This is business. I do the same thing, where I have multiple job offers and go in order of preference. Don’t lie or jerk me around though. If you say “You are going to fly here on Monday” I will start packing, and if I don’t fly I will have wasted time and effort.

So a different recruiter contacted me about 4 months ago. I brought up EA spouse, and she said something to the effect that they made a lot of changes and things were different now. I didn’t answer though, because even if that were the case I will never work for EA after getting jerked around.

Categories
Game Development

Rant: How the unwashed masses have ruined computing

When I first started using the PC (mid-80s) there was only DOS. DOS wasn’t hard to use. My Dad, who bought the computer, installed some kind of shell where you could hit F7 or something to enter a directory, F6 to go back, and F5 to run the highlighted program. However, the shell actually ran the regular cd.. and cd [dir] commands. So I learned 80% of all the commands I would ever use in DOS in the first day, and 99% in the first month. I never used the shell again after about a week.

Then Windows came out, and it sucked. It was slower to get to my programs, took minutes to load, as opposed to seconds in DOS, ate up memory, and basically didn’t contribute anything to my ability to use the computer. Yet, over several revisions, it was popular. Eventually, application companies stopped supporting DOS and I was forced to upgrade my computer just to run Windows.

Most of what I did at the time on the computer was play games. Back in the DOS and early Windows days, there were no installers. On floppy disks there were unpackers. Early CD-ROM games just had the whole game on the CD-ROM and you could run it from there directly if you wanted to.

Things were good, because I had control over my harddrive. I knew were every file on my computer was and what it did because I put it there. If I wanted to backup, copy, or move a game I just did it. There was no registry or shared files to contend with. There was no crap left over or “Add/Remove” programs list where 1/4 of the programs in the list actually don’t exist but can’t be removed from the list.

Yet, companies started using installers, and they started using Add/Remove programs, and soon my harddrive was cluttered with crap. My computer was now slower, with wasted harddrive space, and I had to reformat every 6 months or else things got out of control. Even now I still reformat about once a year.

Fast forward a few years. The next version of Windows, Vista, takes half a gigabyte of RAM just to run. I complain about my work computer regularly, which runs XP. Yet it is an Intel 3 gigaherts. That ought to be fast enough to open a text editor right? But for various reasons it’s often not. Essentially, unless you have a top-of-the-line computer you can’t even run the OS anymore without frustration and slowdowns. Why is this? Because people want cute 3D windows, animated icons, and other crap that has nothing to do with the point of the OS, which is to run your programs.

This is the same reason why console gaming is more popular than PC gaming. Consoles are less powerful, harder and more expensive to develop for, and the games are more expensive. Yet they account for 3/4 of the market for two reasons: quality control and installation which consists of inserting a cartridge rather than clicking through a few windows on your PC.

Half the population has an IQ under 100. Better applications, which don’t support “click and drool” as a fundamental design feature, fall behind those that may be worse in every regard except the installation. Windows vs. Linux is arguably in this camp.

It’s important to end a rant with a lesson learned, since complaining isn’t going to change the reality of the situation. The lesson is to make your software so easy to use that your Grandma can use it. If you can do that, you’ll sell to the 50% of the population with an IQ under 100 that your competitor can’t sell to.

Categories
Game Development

Dynamic help is the Clippy of Visual Studio

Does anyone actually use Dynamic Help?

Dynamic Help = Snail Shit

It seems like the stupidest idea Microsoft has ever come up with. Well maybe behind Clippy and Microsoft Bob but not far behind. Within ass grabbing distance.

The problem with dynamic help is that it takes about 10 seconds to load on my snail slow work computer, and F1 is right next to the Escape key, which I hit all the time. And those fields are utterly useless. Do I really care what Microsoft thinks about my coding techniques and programming practices? 10 seconds is too short to go do something else, and too long to avoid breaking my concentration.

At least there’s no dog that comes up asking me what I want to search for.

Categories
Game Development

Improving compile and link speeds of C++ projects

At work we have a very large codebase, in the millions of lines of code. Nobody understands all the code, and half the people who wrote it aren’t at the company anymore. So a lot of my time is spent experimentally – tracing through code to figure out how it works, or making small changes to fix unforeseen bugs. The problem is this requires a lot of recompiling small changes. Unfortunately, the code is designed in such a way that sometimes small changes result in the recompilation of hundreds of files.

I spend half my day not programming, nor thinking, but waiting for the compiler. This is by an order of magnitude the biggest hindrance towards my accomplishing anything meaningful. A single line of code change can take 15 minutes when you consider the time to build, the time to link, the time to regain my lost attention, and the time to do it all again for my second instance of Visual Studio (for network programming). Fortunately, I’ve learned a few things as the author of RakNet that can help with compile and link times. While they may be obvious to experienced programmers, even experienced programmers don’t consistently follow them so they are worth reviewing.

1. It’s bad to include header files in your cpp files. It’s exponentially bad to include header files in other header files

.cpp files increase the time to compile your project linearly. For example, if my cpp file includes “blah.h” then every time “blah.h” changes, then I have to recompile all cpp files that include that. That’s bad – but still far better than header files, which increase your total compile time exponentially. If files C.h and D.h include B.h, and B.h includes A.h, then anytime A.h changes we have to compile 4 header files – A.h, B.h, C.h, and D.h. But it’s not just 4 header files – we are now also rebuilding any cpp file that includes any of those header files.

2. Avoid, as much as possible, putting code in header files

Code is likely to change. Class definitions are much less likely to change. Furthermore, code in a cpp file is only included in that one place – that cpp. Code in a header file is included everywhere that header file is included. If you put code in a header file, that means that you are likely to change that header file and you are including the same code all over your program meaning it gets recompiled every time.

3. Split up your header into independent classes/structs/enums as much as possible.

It’s a hassle to add header files to a project. Oftentimes, when two kinds of interfaces, such as an enumeration and a structure, are both used with a class, it’s tempting to put both in the same header file.

Supermarket.h
enum Fruits {APPLE, ORANGE, GRAPE};
class Supermarket {Fruits GetType(Fruit *fruit);};

There are two problems with this. First, enumerations are likely to change. If we later add POMEGRANATE then every class that includes this needs to be recompiled. Secondly, every class that cares about Fruits now has to also include Supermarket, and vice-versa, resulting in unnecessary compiles.

4. If your class has complex types in the header, or is included by many other files, think about exposing an interface for that class.

Interfaces can be a hassle since you now have to maintain two copies of your class definition, rather than one. However, in some cases they can vastly cut down on compile times. Consider the following:

Database.h

#include "ComplexTemplatedList.h"
class Database
{
Rec* GetRecord();
ComplexTemplatedList recordsList;
};

DatabaseInterface.h

class Database
{
virtual Rec* GetRecord()=0;
};

In the second version, we got rid of all the implementation code yet every class that needs Database can still use it and now compile almost instantly.

Here’s another example:

class Logger
{
public:
void WriteLog(char *);
private:
char *logList;
int numLogs;
}

The logger will probably be included in a lot of places. If we were to add a field

int *logTimes;

then, even though the log times have nothing to do with the users of the log class, all those users will have to be recompiled. By using an interface, none of the member variables would be exposed, so adding or deleting member variables won’t cause recompiles of files that include this header.

5. Inside header files, include pointers to other classes rather than the classes themselves

CompileSlow.h

#include "CompositeClass.h"
class MyClass
{
CompositeClass a;
}

CompileFast.h

class CompositeClass;
class MyClass
{
CompositeClass *a;
}

Sorry if my last point is obvious, but it’s the easiest to do so is worth pointing out.

In conclusion, a few minutes of trouble today can save hours over the life of the project, not just for you but every other programmer that has to do builds.

Categories
Game Development

Effective AI programming

In game programming you need to keep learning to stay effective. When I finish a game, I reflect on what I’ve learned and consider my new skills to be more valuable than the pay I’ve earned (although that’s important too).

For my last two games, Getting Up and Star Wars Ep3, I worked on the AI. Although work on is sort of misleading, because all I really did was support users for the AI code that was already written. The existing AI code was pretty good – lots of code, lots of features, and most importantly anytime anyone else tried to add to it it was invariably worse than what was already there (and often duplicated an existing feature they just didn’t know about). So I didn’t much rewrite or extend it, and honestly there wasn’t that much to learn. In fact, a few months ago I would have said the only thing I learned is what a pain in the ass it is to maintain other people’s code who no longer work there.

On reflection though, I did learn a lesson. Because I’ve been dealing with AI actually since I started in the industry. We had the same AI programmer for every game from my first company, and the AI sucked equally bad for every game that company released. What this has demonstrated is the same thing that the AI code for GU and EP3 has demonstrated: that your AI is only as good as how high level you design it from the start.

In my first game, the design was at the level of pathfinding and movement. Subsequent attempts to add cover pretty much failed, because cover is a higher level concept that takes higher level design. I used to have a teacher that said “You can’t see the forest from the trees” and I never understood what he meant until I worked for a couple of years.

In GU and EP3, the design is at the level of combat and game mechanics, such as triggers, hide points, and gotos. Therefore, these features worked fairly well but there was no higher level planning such as group tactics or fear.

I think in order to have really good AI in a game, you need to design in high level tactics from the start, and fill in lower level concepts such as pathfinding later. Otherwise you will get bogged down in tweaking the existing code to try to compensate and never really succeed.

Categories
Game Development

Why design patterns are a good thing

So here I am for the third game needing a text manager class. Something to hold text strings for periods of time, display them in an ordered list, and handle text wrapping.

The first game that needed this used DirectX so I had lots of DirectX code in the text manager. It would compute the length of strings, edit the list of strings to split them up, etc.

This was useless for my second game because it used a different graphics engine. I copied some parts over, but a lot was changed. One of the biggest changes was that fonts were now in a separate class, where DirectX handled them as part of the graphics engine. Also DirectX took the strings to render directly where this new engine had a manager. So a lot of code was changed.

Now for my third game I look at what I did for the second game and again see that it is useless. Faced with the prospect of rewriting something that has the same functionality for the third time I decided enough was enough. Time to actually apply some engineering principles. Browing the web and remembering what I learned in college I decided to try out a factory class with a model / viewer pattern.

At first I was hesitant to do this because it didn’t seem to solve any problems. At best, I would split up the viewer into two classes that I could have done with a simple if statement. However, as I wrote more I began to see the wisdom behind the architecture.

First, I wrote the factory. This forced me to think about what parameters I would use in advance and whether they belonged in the model or the viewer.

Second, I wrote the model – which is just a list of text strings. This was completed much faster and easier than I had done in my prior implementations because I didn’t have to think at all about how the strings would be displayed. The model is totally independent of the graphics engine.

Third, I wrote the viewer. Some parts of the viewer, such as accessors for data, have nothing to do with the graphics engine. Some parts do. So in a flash of inspiration I had the viewer Irrlicht implementation derive from the viewer base class. I then modified the factory to return an instance of the Irrlicht implementation.

Presto! Now I can use this in future games. All I have to do to switch graphics engines is to derive a new viewer. I don’t even have to change the game code because it got an instance of the base class rather than the Irrlicht Implementation. I can just change the factory for the graphics engine I want. I could even support multiple graphics engines by passing different parameters to the factory.

Categories
Game Development

The devil is in the details

I just finished adding the ability to read double clicks. There’s a lot of little things you have to consider:

  1. You have to click the same button twice, not two different buttons rapidly in a row
  2. You have to account for mouse drift of a few pixels from the last click location
  3. Triple clicks should not count as two double clicks

The reason this is noteworthy is that it’s a good example of how trying to write TDDs that handle every detail of the code is impossible because normal people don’t think at that level of detail. I was watching this show about autistic people and how some of them remember all the small details they see if you let them glance at a room. A normal person doesn’t because they are bombarded with information and the brain filters out most of it.

This is why I take the approach “Write what you know, refactor what you don’t.” This is totally opposite the concept of high level design.

It’s also why, when you ask for a spec from a customer, the spec invariably misses out on details. Programmers are trained to do this sort of work and forget things. What can you expect from a customer who probably barely knows how to open Word? Extreme programming accounts for this by involving the customer in the design and implementation process which sounds like a good approach.