Categories
Game Development

RakEngine: Adding debug text in Ogre 3D

Ogre 3D doesn’t have native functionality to display debug text. So I spent a half day adding a layer to their overlay system to make it easier to use. You can now do the exact same thing with half the lines of code, no loss of functionality, and with greater safety, including automatic memory handling. This is essentially free in terms of speed.

I now got text showing up and fading out over time. But then I found out Ogre3D also doesn’t have the ability to do automatic line wraps… Or positioning of multiple lines of text.

It looks like the way to go if you want debug text in ogre 3D is to use CEGUI. It already handles line wrapping and I’m pretty sure it also handles multiple lines of text. If it doesn’t do what I need I can write my own text positioning system in a day or so.

Categories
Game Development

Game architecture design

I’m at the point where I need to design the high level architecture for my game. What classes will there be? What operations will they perform? How will they relate to other classes?

The problem is that my answer is usually “I don’t know” or “I don’t know very well.” I can roughly say that “It’s an MMOG game so it will have a client and a server.” That’s true, except it’s not very useful information. For example, it’s wrong to say I have “a server” because for scalablility I plan to use server clustering. And what is a client? There is a game client for sure, but there are or may be remote administration clients or logging clients as well.

So I can’t really design the whole game architecture on paper right out. The human mind just can’t explore every possible detail in advance. So how about extreme programming? In XP you have a shipping product pretty much every week. And you build on that project from week to week. This isn’t a bad approach and it’s certainly better for motivation. At the same time you can’t totally ignore high level goals. If I were to do that using a simple minded approach I would hardcode it to have just one server, which means eventually I will have to go back and change code I’ve already written, wasting time. Changing old work that already works tends to be harder and more buggy than writing work the right way to begin with too.

So what’s the solution? For me, it’s an extension of the design principle I already use, which is “Don’t make decisions that have exceptions.” In this case it’s more like “Don’t make decisions I’m not absolutely sure of.” That’s a good starting point because it gives me code to work from. Some things I’m sure of:

  1. I’ll need the ability to enter text into windows for chatting.
  2. There will be at least 3 systems – a game client, a game router, and a game server
  3. For ease of testing I want to be able to run a server locally in the background from a client.
  4. I don’t want to include most of the server code when I release clients

So this actually gives me something to work from right away. I can create 3 classes, I can design those classes for code exclusion, and I can write a chatting system in the game.

Based on those modules I can think more about the problem and design other modules.

The positive results of this system are first that I don’t get paralyzed trying to think of what to do. Second, I’m unlikely to waste or redo work. Third, and most importantly, it forces me to carefully think about my systems and not gloss over details.

This is what works for me. Feel free to post your own ideas.

Categories
Uncategorized

RakEngine .1 released

Combines Ogre3D, fmod, RakNet, OIS, and Crazy Eddie’s GUI system. OIS (the input system) and Crazy Eddie’s GUI system do not work together very well and OIS isn’t very well designed so I wrote an input manager which fixes that problem.

The majority of my work went into setting up the projects so they work together nicely. All the libraries go to one place, the output to another place, and so forth. There are includes and dependencies all over the place so I subdivided them among projects.

So now it’s tremendously easy to create a new game, with access to the functionality of all those systems, without having to write all kinds of setup crap.

One big plus is Ogre3D supports lots of content creation tools so the particles were made by me, as well as the GUI layout.

Here’s a screenshot which shows all the systems except RakNet in action. Everything you see was done in 231 lines of game code, which includes winmain()

*** EDIT ***
You can get it here: RakEngine .1

RakEngine .1

Categories
Uncategorized

Good systems design

One thing I’ve learned from doing RakNet and am trying to do in RakEngine is to follow good systems design, which can be summarized as
1. Preserve generality
2. Preserve relevant information

This can be summarized in one sentence: Don’t make decisions that have exceptions – either in regard to processing or information hiding. Almost every time there is a case where someone says “This code is all over the place” it is because this rule was violated.

An example of this is a class that calculates and stores AI paths. Lets say you make a decision to limit updates to every 500 milliseconds. During later testing you find that the AI doesn’t respond fast enough when getting hit, and in that particular scenario you need to update the path right away. So now you have an exception to your rule of 500 milliseconds, which means it was a mistake to make that rule to begin with. Except that now when the AI gets hit a lot, you don’t want to recalculate the path again, so you have to add a special flag to disable this. Except for a third case when a path blocker comes up. And so forth. Now your code which simply finds AI paths has special flags for things it shouldn’t know about (blockers and getting hit).

It’s much harder to design systems that maintain generality as opposed to systems that are specific. You usually have less features. One way to tackle this is to define primitives, where a primitive is the minimum unit of functionality and information that anyone could ever care about. Then build up systems composed of those primitives. A good example of a primitive is the sin() function. A sin function is an expansion series. There is a certain amount of internal data going on there such as the nth term and how far the series is expanded. But you don’t care about that. So it’s not exposed and the sin function works well, without people having to rewrite it. Suppose instead the sin function calculated both the sin and the cosine at the same time, at a cheaper cost than calculating both separately but more expensive than individually. That would be a good thing, except in cases where you don’t care about the cosine. So you no longer have a primitive, which is why that is not done.

Sometimes designers think something is a primitive and it is not. For example, bytes. In network code I deal with bits all the time. The bit is actually the minimum computing unit. Because of the abstraction of bytes I had to write a bitstream class with a huge set of complicated functions to read and write bits. So defining bytes as the minimum memory unit was a bad abstraction. A better abstraction would have been to make a bit a native type, and to use that in composition, where you have a bit8 as another type, and so on.

The native C/C++ types are also bad abstractions. They try to hide the underlying type by representing the most efficient form for the compiler. So an int is the type you should usually use for numbers, a char is used for characters, and so on. But in practice a great deal of the time you don’t care about that – you care about how many bytes are used. So you end up with almost every library doing something like
typedef unsigned char UCHAR;
And when you use another library, you can’t just use UCHAR. You have to look at what type that actually was, and match it up with your own type. So people have proposed to do something like
typedef unsigned char u8;
typedef signed int s32;
And so forth. This is good, because it is more of a primitive than int or char. You are undoing the bad design work which shouldn’t have been done to begin with.

So a good rule of thumb when designing systems is “Is there any case where anyone would want to process something differently than I just wrote?” And “Is there any case where anyone would want to view this data I am setting as protected or private?” If yes, you need to think carefully about that because you will have to write exceptions, which multiplies the complexity of your system. It might be better to go to a lower level of granularity and compose the system instead.

Categories
Game Development

Input, Sound, RakNet, Ogre 3D running

I have 4 systems running now. I need to integrate RakVoice with fmod next.

I would have had all this done yesterday except that I spent a huge amount of time trying to get Ogre to work from source, instead of using their framework. Eventually I gave up on that idea.

I thought it would be a simple matter to get the GUI on the screen but it seems like that’s one of the hardest things to do of all. I think I’m going to have to write a wrapper for Crazy Eddie’s GUI system because there’s a ton of code involved to do things that should have been automated. For example, mouseover and mouseoff highlights, setting callbacks for various operations, and such. You have to load the textures yourself even. With as much as you have to do yourself I’m not sure what functionality Crazy Eddie’s system even provides.

The system I had in Irrlicht was much better. It was one line of code to add a GUI element and it did everything else for you. Rather than having to create a class and then setting and writing callbacks for each button I just handled an event in a switch / case.

Categories
Game Development

Huge static libraries in Visual Studio 2005

I build Ogre + dependencies into a static lib in Visual Studio 2005. The resulting .lib was 1,445,853,944 bytes. In fact I had to use a special flag /expectedoutputsize:50000000 or else the compiler incorrectly reported “LNK1106: invalid file or disk full: cannot seek to 0x76364” It also took minutes to link.

The same thing, built as a DLL was 7,921,664 bytes and the lib was 2,983,094 bytes. It took less than a second to link.

Categories
Game Development

Should have used fmod to begin with

fmod is the RakNet of the audio world.

From looking at the website to getting it running in my game was 15 minutes.

It compiled and ran as I expected the first time.

It was documented.

The sample actually worked and was easy to follow.

I didn’t even have to write a wrapper!

$5000 is pretty steep for a commercial license but the shareware license at $100 is well worth it. I’ll be registering.

Categories
Game Development

OpenAL makes me want to kill someone!

OpenAL has to be the worst packaged library I’ve ever used.

The distributions are different between the SVN, the downloadable installer, and the source download.
There is a downloadable installer for a library to begin with, which makes no sense.
The license terms for the downloadable installer are draconian.
The library is split among 4 projects, each with different settings, which output to 2 .libs with no explanation as to why or what the differences are. The actual library takes 2-3 .libs depending on which one you download, which in turn takes 1-2 dlls, again depending on which one you download.
None of the three dowloads work without modifications.
Each of the three downloads only contain a subset of the code, meaning you have to download all 3 anyway and then figure out how to put them together.
The tutorials don’t run because they require a DLL that isn’t included in any of the distributions.
You can’t build static libraries or directly include the source without modifying the code.
Version 1.1 is utterly incompatible with older versions and in fact seems to have less features.
The documentation is so out of date that it is flat out useless for that functions that it does cover, which is only a minor fraction of the actual functions.
The code does not include useful user documentation in the headers so you have to just guess what the functions do.


/* Create Source objects */
AL_API void AL_APIENTRY alGenSources( ALsizei n, ALuint* sources );

Um thanks…

Out of all the libraries I’m including in my game engine, by far I’ve spent the most time trying to get OpenAL working. I’m about to just say screw it and use fmod instead, even though fmod isn’t free.

Categories
Uncategorized

Ogre3D update

I’m trying out Ogre3D now. So far I’m impressed!

I found a nice particle editor although it took some digging around in the forums. So that’s one big headache gone!
It has a GUI editor which could be easier to use but seems to do everything I want. Another headache gone.
It has exporters for every 3D modelling package. That’s great, because it frees me up from having to write one. If I do have to write one, I have the sources so I can do the modifications I need to.
It obviously supports shaders and enough graphics techniques for my game.

I made a project called RakEngine, which has Ogre3D, RakNet, and OpenAL. I’m going to screw around with it until I get some clickable buttons on the screen, showing some particles, and playing some sound. Then I will do a new state system. That’s pretty much it for the engine! I don’t need physics but if I do later turn out to need it there is a newton plugin for Ogre 🙂

In order to test the engine I can try writing something really simple, like multiplayer hangman. Although I don’t like taking the time away from my game, that covers all the basics so I can iron out the kinks.

I can then start over and do my real game 🙂

Categories
Game Development

Reality Engine vs. Ogre 3D

I was really excited about finishing the MMOG networking code recently and moving over to the Reality Engine. However, after looking at and discussing it for a few days it seems like there are some serious flaws in the design of RE.

First of all, they wrote most of the game in script. This is fine, except that the script they chose was C#. Which is also fine, except that C# requires that your end-users install the .net 2.0 framework. This is unacceptable because, at least with downloadable games, users might choose not to do that. I don’t blame them. Who wants to install some bloated crap from Microsoft and slow down your system just to play a game? It’s almost unheard of for a game to require you to install some 3rd party application just to play the game.

So now I have an engine with no game code.

Doubly bad, they also used C# for their GUI designer.

So I have an engine with no GUI code.

They also tied in Ageia physics to their physics library. Which itself requires an installation of a 3rd party driver. Which is also unacceptable for the same reason. So now I have an engine with no Physics either.

I’m not going to use their networking because although they used RakNet, they did a bad job of implementing it. So I have an engine with no networking.

RE has a good renderer. Except their toolset is very limited. For example, no particle editor and support only for MAX. Oops!

At least I get support in an engine right? Nope, because they aren’t answering the forum anymore.

So I’m left with a sound engine… an input engine… not much else really. I already have a sound engine though (OpenAL). I already have an input engine too.

So what am I left with?

I guess I have the option to either continue to use Irrlicht or to swap and start over with Ogre3D (Duke Nukem Forever!). I don’t want to keep starting over but the problem with Irrlicht is they are years behind Ogre3D. I really like how well written and easy to read and use the code is. But there’s no editor and a hell of a lot of other stuff missing. I spent quite a lot of time writing my particle editor. Then I was faced with writing code to render text on the screen. And so forth. With so much time spent on low level things, it would probably be faster just to use Ogre3D. I’m on the edge at this point and saying “Fuck it” and starting over with Ogre3D. It’s a sunk cost fallacy to stay with Irrlicht just because I already spent a lot of time on it. The question is, what is the fastest way to get my game done at this point? And it’s probably starting over with Ogre 3D. Since my network code is abstracted out I lose nothing there so I’m still maybe 40% done.