design

You are currently browsing articles tagged design.

Unique character names in MMOs have long been a pet peeve of mine.  I am sure most of you have experienced the frustration when your favorite character name ends up taken by some else, and if you are like me it might take as many as 20 tries to get an available name.  Well, here is a question for all you MMO programmers, why the hell are you still using character names as a unique identifier?  There are so many better options to identify players in the world, every name does not need to be unique.  In fact I frequently find that running across players entitled ‘FancyPants12′ or ‘Moooo4me’ does more damage to game play than a simple change would.  When I am in the process of being adsorbed into an MMO through very nicely executed immersion techniques, stumbling onto these players breaks flow, ScreenShot_071107_195300disrupts my concentration and I find it harder to follow the story line (or even care about it).

Creative Commons License photo credit: Idhren

I bring this up because this last weekend I started playing Aion.  A very nice game that I have high hopes for, but its probably the first MMO that I am actually interested in a bit of the lore; I even went so far as to read some of the important quest text.  Its shocking yes, but they really did do a good job making the player feel like they are not just a drop of water in an ocean; which is worthy of recognition in itself.  Unfortunately, Aion suffers from the unique name dilemma so while I am trying to rescue the damsel from a horde of black winged bandits I am constantly running into ‘XXSlayerXX’ or ‘RoGeGardian’ and that is just terrible from an immersion perspective.

But what can be done about it?  After all, a lot depends on character names.  PMs, brokers, mail, friend lists, etc etc.  Obviously a new system has to enhance game play, not restrict it.  I propose a system where each character is assigned a unique number, not a name, which can be used for all these means of communication with just a little extra effort on the programmers side.

Read the rest of this entry »

Tags: , , ,

Graduation

A quick update today, I have graduated college and am officially in the work force.  Great time to do so I know, luckily I am under no emergency to get a new job, but I am looking.  Therefore, if you are visiting here and you like what you see, please visit my About page to download my resume, cv, and portfolio.  I am willing to relocate ( eager, in fact ), and prefer jobs that are interesting and will challenge me to learn and improve my existing skills.

Read the rest of this entry »

Tags: , , , , ,

Contrary to the many many posts about ’10 reasons why ubuntu is the next #1 consumer desktop’ or ‘Switching from windows to ubuntu’ this post is about my experience with ubuntu and why as of this moment I am reinstalling windows vista.

Read the rest of this entry »

Tags: , , , , , ,

Here is a problem for all the theoretical computer scientists out there.  Say you want to write a program, this program needs to parse a certain file structure and extract useful data.  A single file is setup as a bunch of independent records built on a handful of fields in said record.  There are almost 1000 different kinds of fields, and close to 200 different kinds of records.  The requirements for output is standard duplicate checking and removal, and programmable output, meaning you can change how the output looks or is handled without changing the program.

If you can think of a good solution feel free to post your ideas, today I will be writing about my solution and things that worked and did not work, and things that still do not work.

Read the rest of this entry »

Tags: , ,

So in my last article I touched on the subject of what I termed static factories. I did a little searching online and found the original article that first gave me the idea.  Apparently this type of design is called pluggable factories.  A term I had forgotten until just now.

Here is the basic idea, you have x number of objects your program can create.  These objects are all children of a base interface.  You have cleverly created an abstract factory to create the various instances of your objects, but there is a problem, you are asked to add several new objects and/or remove several objects.  So you jump back into your code and make a new object or remove an object.  You compile your code and try to use the new object, OOPS, you forgot to add it to the abstract factory!   Or, after removing the object you run some old data and OOPS, your program crashes as it tried to return an instance to a class that does not exist.

To be fair, if your program was written correctly it would not compile in the latter case, but that is besides the point.  Sometimes abstract factories can be a pain in the ass.  So, here is where pluggable factories step up to the plate.
Read the rest of this entry »

Tags: , , , ,

Log Files

While working on the BAF file project I learned a very interesting life lesson. See like most new computer science graduates I have worked on few actual projects, and quite frankly the few I have finished could not be considered corporation ready. While writing a few console applications, file parsers, corba interfaces, etc I learned a valuable lesson in documentation and log files. Log files can save your life if done correctly, and if you are really up to speed they can save many long hours of debuging too. In my case I fell in love with trace log messages. Trace logs are the log files that trace a programs execution so you can get a general idea of where your software is failing or producing an error. Now, most trace logs I have had the pleasure to work with are not quite where I wanted to be when I approached trace logs in my program. Most of the time they are a little more helpful then debug messages when trying to pinpoint an application’s problem. So when I faced the decision to add trace messages I decided to go all out.

My first logging framework was log4cplus, which is a very nice and complete logging framework for C++. I used it for one linux application I wrote and it works perfectly despite being several years old. Unfortunetly I was uncomfortable with how much work it took to write a message each new function ( two lines instead of one ) and it would not compile in windows so for my next application, bafprp, I set out to write my own.

When I completed the class I was left with one macro to print a log message depending on the level you wanted, ie, LOG_TRACE( string ), LOG_DEBUG( string ), etc. I then made sure I was adding trace messages to each and every function as I made them, instead of later on in the design. For example, an empty function would look like


void BafRecord::getType()
{
LOG_TRACE( "BafRecord::getType" );
LOG_TRACE( "/BafRecord::getType" );
return;
}

Each function would have a start and stop trace message.

Now this might raise an eyebrow or two but I assure you it definitely helps when your program crashes and you do not have a nice debugger on hand. Like say, if a non-technical user is using it.

This is how my linux application was programmed and I went the extra step in bafprp to work these in while I was working. Enough about this though, a short while ago, after adding one of the major structure types to the program my application slowed down from parsing a 12 meg file in 2 seconds to 2 minutes and I was greatly concerned over the well being of my design.

I tried many things, first I greatly reduced the number of memory copies my program executed, then I changed my file input so that it would read the entire file at the start and reference a data bank instead of reading the file each cycle. However none of these things put a dent in the processing time. So then I went online to try and find a nice and easy code profiler. Code profilers will basically watch your program execution and tell you which function your program is spending the most amount of time in. I ended up finding LTProf which allowed me to profile my program without recompiling or changing my program at all. I am actually very surprised at how well it works with compiled binaries. After running a release version of my program it was still able to accuratly determine function names and operate like it had a window into the source code.

I found that my time stamp function, NowTime, which returns the current time as a string, was taking a noticably large amount of my program’s time. Thinking back to what code uses this function I discovered the flaw.

When I wrote the log program I wrote the log level exception into the log class. This way if the program tried to log a trace message it would get sent to the output class, which would then pass it on to the logs if the level was at or below the log level type. However this was not enough. as it turns out simply creating the log message twice in each function had a substantial effect on the processing speed of my program.

Needless to say as soon as I moved the log level check to the macro the process speed dropped from 2 minutes to 30 seconds. Now some might say that trace logs this detailed are excessive, however I believe they can help greatly when dealing with a malfunctioning program. So as a final statement, be careful when you design systems, and beaware of how to use your tools. And if your program runs 3 times longer then a similar program, there is probably something horribly wrong.

Tags: , , , , ,

Ok ok, I am writing again! If you read my previous posts on dynamic npc actions then this is an update on my progress. If you have not, this is about how to create good file formats for your applications.

As some might have expected this project is taking more time then expected, partially because I am currently downing bosses in WoW, and partially because its very hard. So lets just cover what has been going on since my last post.

I spent a lot of time thinking of the best structure for my idea in terms of objects and file formats. I do not know if I covered this before because I am to lazy to view my past posts so heres a recap of the basic composition of what I have been calling a ‘Puppet.’ A puppet is a game object with x number of movable joints. These joints are built in a tree structure and move based on messages passed to his parent. These messages are generated from a actor class who learns actions and movements as I previously discussed. When I was designing the puppet class I hit a big fat road block. I wanted the ability for a puppet to be independent of his underlying joint structure. That way I could have a puppet control everything from a human to grass. So you might think, ‘No problem, do some tricky interface work and have derived classes for each type of puppet.’ WRONG!

See I myself have read many articles about component game object design, and I do believe I wrote an article on this in the past. However do not get the wrong idea, what I did is not EXACTLY component objects, but kind of close. Because when I thought about components I also thought how to best describe them in a file format. And after thinking about that I decided that I wanted a global file format to describe not only each type of puppet but the entire world. And that the entire game will be built out of components in a tree structure built at load time from this file format. I am getting a bit ahead of myself here so lets get some examples here.

<world>
<name type=string>Main</name>
<description type=string>
Big world for which to run tests in
</description>
<floor type=plane>
<p1 type=vector>-1000 -1000 -1000</p1>
<p2 type=vector>1000 1000 1000</p2>
<material>dirt01.mat</material>
</floor>
<joint>
<position type=vector>0 0 0</position>
<orientation type=vector>0 0 0</orientation>
<puppet>arm.puppet</puppet>
</joint>
</world>

This is my toy world I am working in. The file format is xml and I use tinyXML to load and parse these files. For those familiar with ogre, I made a resource of type XMLFile to load these. Now here comes the clincher, this XMLFile resource will load every type of game object I desire, regardless of type or purpose. Not only that, but I only added 2 methods to the class.

So let me explain a bit about these methods, they are named ‘build’ and they are called usually immediately after loading the file. Basically what they do is look at an element in the xml, find a builder for it, have the builder build it, and attach the new object to the world tree. In this example, the world has no parent and all elements inside the world tags are children of the world. I use the type descriptors so that I would not have to write many classes that do the exact same thing. Elements that load another file, like the puppet tags, will load that file in their own world and all objects created from that are children of the puppet. After the build the main program is not aware of any object other then the world. Messages are passed to the world when need be, however most thought processing is done in the world object, not by the game engine.

Lets get an example puppet up here:

<puppet>
<name type=string>arm</name>
<description type=string>
Generic arm
</description>
<joint>
<name type=string>shoulder</name>
<gib>upperarm.gib</gib>
<joint>
<name type=string>elbow</name>
<gib>forearm.gib</gib>
<joint>
<name type=string>wrist</name>
<gib>hand.gib</gib>
<joint>
<name type=string>pinky</name>
<gib>pinky.gib</gib>
</joint>
<joint>
<name type=string>ring</name>
<gib>ring.gib</gib>
</joint>
<joint>
<name type=string>middle</name>
<gib>middle.gib</gib>
</joint>
<joint>
<name type=string>index</name>
<gib>index.gib</gib>
</joint>
<joint>
<name type=string>thumb</name>
<gib>thumb.gib</gib>
</joint>
</joint>
</joint>
</joint>
</puppet>

As you can see this file format is very flexible, the same structure that built the world can build a puppet and also a gib:

<gib>
<name type=string>forearm</name>
<notes type=string>
Fore arm gib
</notes>
<mesh>forearm.mesh</mesh>
<input>
<name type=string>shoulder</name>
<position type=vector>0 0 0</position>
</input>
<output>
<name type=string>elbow</name>
<position type=vector>7 0 0</position>
</output>
</gib>

I want to clarify one thing before I go on. Elements called position or orientation, these attributes are not given any attention by the builders. Instead those objects simply exist on the tree for someone else to read them and make the correct adjustments. For example, the puppet’s name element simply sits as an element on the tree until a debugger opens and the entire tree structure is displayed. At that time the debugger will go through each element and find name tags that it will use to give more information on the node. And the description works the same way.

They are both created by the string builder, as denoted by the ‘type=string’ attribute I give them. The value is assigned and the name of the new object is set, but the type is always a string.

So what exactly is required to declare a new type of object? Just a builder and an actual object. Take this example of the string object.

class ScktString : public ISocketable
{
friend class StringBuilder;
public:
void setValue( std::string val ) { _string = val; }
std::string getString() { return _string; }
private:
ScktString( std::string propName ) : ISocketable( propName ) {}

std::string _string;
};

class StringBuilder : public IBuilder
{
public:
StringBuilder() : IBuilder() {}
Socket* build( std::string element, Socket* parent );
const std::string& getType() const;
static std::string BUILDER_TYPE_NAME;
private:
static const StringBuilder registerThis;
};

As you can see its relatively easy to create a new object. Lets start at the builder, when the xmlfile is building it will search for a builder based on its type name, which is assigned by you. A builder list is created at the start of the program, as each builder has a static ‘registerThis’ variable that adds it to the builder list. Those familar with static factories should be familiar with this. The builder’s build method gets called with the name of the element and its parent’s socket. A socket is an object that accepts links from children. The builder then builds the object passing its name. The sockable base class is for objects that can be socketed or linked with a parent.

So the string object is created and the string builder passes back the parent object. This is done in case the new object has a socket himself. In that case he would pass back his socket and the builder would build his children and attach them to him. In string’s case however, there is no socket and a little while later the builder assigns the string object a value by calling the setValue method in the parent object with the objects name and value as parameters.

After all the work we are left with one tree that contains all objects in the game. Kind of like a scene manager, but for ALL objects, not just renderable ones. And oh, don’t forget that the entire tree was created by one instance of XMLFile. As programmers we should always strive to achieve the cleanest and most powerful format we can muster. This format is not only really easy to implement, but also holds unlimited power. You want to load a texture? Create a texture socketable object, and implement file specific loading inside it. You want to script AI? Either create an AI socketable object that reads children objects that decribe a strategy, or create a python socketable object that will load your ai scripts and parse them. In this way our file format can act a proxy for another format or as the direct format. The most important thing however is that none of our in game objects need to give file formats a single thought.

Tags: , , , ,

The true cornerstone of a project such as this will be dynamic and human like actions. I have spent the last two weeks thinking of a system that would allow the development and evolution of dynamic actions, searching the internet, writing down ideas, and finally come up with a design I feel confident enough to post about. I am writing this down for my benefit as well as anyone who is curious, so the train of thought it going to be random and probably hard to understand. For that I apologize, I will have more solid implementation details ready when I have a working system written.

I started by defining what I would be given, and what I would need to produce, and I decided to start with nothing but basic preprogrammed controllers attached to the actor’s to control everything about it. Rotation, position, scale, etc. For an npc, he would have controllers on all his bone joints, for an example. These controllers will have a predefined range of accepted values and know how to move around those ranges. What I wanted to end up with was a high level action, something that will ultimately be composed of hundreds of controller movements over time. And I needed a nice system to wrap up all this data into a structure the npc can store and build off of.

To start off, picture a flat plain of controllers. Each controller knows what it can do, but there are no existing actions yet so this npc is stupid as a brick. During training, actions will start simple, something along the lines of, ‘bend index finger’ works. The npc would look at its action graph and see only the flat plain of controllers, so then its asks each controller if it can accomplish the task of moving the finger’s x position by 1. The controller(s) that respond will have already been defined as able to do this so the npc builds a new action that connects directly with the controllers found previously. Now if the game asks to bend a finger, this action will say ‘I can do that’ and use the correct controller to chance the finger’s position. Its worth noting how the action knows it can do this, so I will explain that a bit. Each action has a function that reads the actor’s current state and determines if it has actions or controllers in its collection to handle that state in any way. If it does, it says yes.

So as the npc adds more and more actions it builds it’s web of linked actions, the process looks a lot like building a neural network. Actions have many actions linked to it, and many actions linked to. I cannot go to much farther without showing you the action class definition so here you go:

class Action
{
Action();
Action( Action* next );

bool validStart( Actor* );
bool validEnd( Actor* );

void AddNext( Action* );
void RemoveNext( Action* );

private:

std::set<Action*> actionList;  // Each entry in this action array represents a start state.
// What about actions that have many independant start actions?
};

When designing this class I thought it was going to be some monster from hell, but after I thought about it, added some recursion, and trimmed it down I think it ended up rather nice. Its simple and works well. Each action will hold links to one or more actions. Each action link represents a valid start state, so when validStart is called the class should call each of it’s start states validState functions and return the OR of their return. This design is very recursive, a next link could be another action or a controller at the very basic level. Therefore chains of actions will form in neural network fashion with proper training. When the npc wants to change his state (execute an action) he simple needs to figure out what state he wants to be in, call validEnd( endState ) on each of his higher level actions that match his start state and if one matches, execute the action.

Only problem here is the tremendous overhead of using the brain. Take an example actor with just three levels of actions, when the game asks to do an action on the third level that action asks for valid start on all level 2 actions linked to it, and in turn those level 2 actions call valid state for all level 1 actions linked to it, which in turn call validstart for all controllers that are linked with it. We could be looking at thosands of function calls with a simple 4 or 5 level npc. And the growth is
exponential.
For now we will just have to deal with it since I believe this to be the best way to describe dynamic actions however in the future tremendous effort will be required to optimize this code.

I will be working on integrating this design into my demo project so if my explanation is way off I will have sample code sometime soon.

Tags: , , , ,

So heres the deal, every game needs some sort of script compiler. Regardless of how its designed, there will always be a time when the ability to edit the game without recompiling is key. But thats not the only reason, scripts allow us extra layers of abstraction so we can do complex things such as ‘pickup( itemid )’ with ease. But I am getting distracted.

I have been working on this component AI idea and have come to the point where I need to start defining actor actions through scripts. How I have it setup now is the npcActor’s state will slowly degrade over time (think the sims) and when it reaches a threshold they go and search for an object that can alleviate their problems. Its a pretty simple design for a simple test. As mentioned in previous posts, I want these npc’s to learn from interacting with the environment. This combined with the mbti structure and other things should produce reasonably agile AI (see previous posts for specifics).

I thought of making this post to stress a key factor in my decision making process as it pertains to this project. And that is abstraction. The abstract is key to this project. In an ideal world, nothing here should be hard coded, unfortunately that is a little hard to do, especially right from the get go. So what I decided to do was to brute force my way to a reasonable demo app and work backwards from there. Removing static code as needed to perfect the design. For instance, I have pretty much decided on a syntax for my scripting language, but I have left much of the interpretation to genetic algorithms in the compiler. Here is a sample script


using actions
using health

_actions::sit $this
$sitting = true
callback -actions::stand _stoodup
{ $health::comfort +1 / 5 } while $sitting

_stoodup:
$sitting = false
::
I am not going to explain the syntax because to any programmer the intentions should be clear. The problem I have been facing is how to keep the intentions abstract enough to allow multiple interpretations. I want Bob’s sitting to look different from Kim’s. I have currently setup a system where the compiler creates these jobs for each script and at the appropriate times sends messages to actors to handle actions. It is then completely up to the actor as to how to handle the action. For instance, when the compiler runs over ‘_actions::sit $this’ it will send a message to the host actor to sit on the target object. In this case the message will not be as simple as

msg.id = ACTION_SIT;
msg.target = 0x01234567h;
msg.brainless = 1;

Instead the message will contain a number of input to be inserted into a designate neural network, which would have been trained earlier to sit when given those inputs (exactly how they sit is up to the GA).

So then how to handle direct variable access like the ‘$health::comfort +1/5′ line above. Well some messages will have to be specially constructed to be brainless. I figure I will have a range of message id’s designated for variable access, neural network input, etc. So a msgID of 1 would be to set a variable, and 2 would send the incoming data into the NN.

This is not the final system, just what I am currently using for testing. However this is the current framework for future applications. The goal of this first program is to weed out any bugs and get a clear understanding of how I want this thing to run.

You can notice how this solution offers a direct line to the actor’s state of mind without hard coding everything, which is exactly what we want.

Tags: , , ,

In a continuation of my last article, I would like to record the process I have been taking to creating and designing the component AI I described in my last post. Component AI is my term for this idea right now, I really have no idea if it has been done before so for right now its what I call it. Now, for those of you who might be familiar with component based object systems (Game Programming Gems 5), this concept will not be to hard to understand.

Basically, we want the npcs to operate off of components they learn about through their training. I know I did not mention training in my last post, but it is necessary for the npcs to not look like mindless zombies through half the game. Each npc will have to be fed through a virtual school where they will learn, through various tests and challenges, how to operate in their world. But I am getting distracted here, back to the design.

Component based objects can be summed up as imaginary containers that are filled with components that operate the object. For example, one component might be a renderer, another holds a model, and one more holds animations. These three together form a solid object that will be displayed in game. They are attached to each other solely through the object manager, but nonetheless are able to effectively communicate with each other through interfaces and a messaging system. I wish I had GPG5 around me so I could yank their example, but I think you get the general idea.

Anyway, objects communicate with themselves through messages, and each of the components that make up an object can subscribe themselves to different messages. A render component would subscribe itself to a ‘draw’ message, that way when the game sends a ‘draw’ broadcast, all objects that have the render component will draw themselves.

That is how component object systems work, when we introduce the ability to pick up new components during run time through actions, we have component AI. The npcs will be equiped with the simple components, model, render, animate, physics, ai, etc, and they will be able to pick up new components from the world to plug into their brain for future use. These types of components can subscribe themselves to messages, and even communicate with each other to achieve the best results. Some form of genetic training will have to be used to teach these components how to effectively communicate. When the npc comes across something new that it doe not know how to handle, picking up a chair for example, it will need to know things about weight, body position, what limbs to use, how to grip it, pretty much everything, and the only way he will know is if the components in his head know how to communicate effectively.

Yes I did mention body position and dynamic animation. I already mentioned the fact that objects themselves will hold data on how to handle them, generally. Then after the npc does that action he will gain a new component for handling that object. This system does not conform very well to static animations like most games keep. So animation will be dynamic and learned by the npc over time. This allows npcs to gain their own style of movement and actions.

Yes yes, I know I am going a bit over board again, running 8 or so npcs each tugging about 10,000 or so AI components will probably be a big load. That is why I need to write a demo application one of these days to see how much this will cost. For right now I am planning to go all out, screw the cpu, but most likely for slower computers we can introduce a system to merge and combine components to save processing time. However the more components you combine the more hard coded the npc becomes.

Tags: , , ,

« Older entries

Charles Solar is Digg proof thanks to caching by WP Super Cache