12/14/2014

Simple Resource Manager With Templates

Hi, been a while.
Contrary to what I wrote in the previous post I'll be talking about a Resource Manager I wrote in a recent game jam. I built it to be simple and fast to implement. This is by no means a great or even good Resource Manager, but it is a good way to quickly get up and running with resource management. But first some background information.

What is a Resource Manager and why do I need one.
The principal problem which a resource manager solves is that of resource duplication. For example you may have several models in your game which use the same texture. If you choose to create one version of this texture for each model you are wasting a lot of memory, the smart way of doing this is to reuse the same texture for all models. But how?

The basic idea is that you keep track over which files you've already loaded. To do this you need to store the information and search through it and if you can find it you just return a pointer/reference to that resource. To do this quickly while maximizing re-usability we'll be using std::map and templates.

The Standard Template Library - Map<Key, T>
The standard template library provides a ton of different predefined types, now the Map class stores a pair of a key type and a resource type. The key is what the map uses to sort the pairs, and this lets it return the pair faster. I'm not sure but I assume it a simple binary search that returns the pair with a time complexity of log(N).

In our resource manager the key type will be a std::string which is the name of the file in question. The name in the map is going to exclude the directory since the root will be the same for all resources of the same type. Comparing of two strings will take longer than necessary if it's comparing the root which will always be the same. The resource type will be a pointer to the resource.

The Code
Here follows the code for the Resource Manager, remember this isn't the fastest or best way of making a resource manager but it is the quickest way I've found so far.

One point of interest is the use of templates, this is done to create a protocol that the resources must follow without creating a v-table.

ResourceManager.h
#ifndef RESOURCEMANAGER_H
#define RESOURCEMANAGER_H

template<typename T>
class CResourceManager
{
public:
    T* Load(std::string name)
    {
        ResourceMap::iterator it = m_Resources.find(name);
        if (it != m_Resources.end())
        {
            return it->second;
        }
        else // Resource not found
        {
            T* t = T::Load(name);
            if(t)
                m_Resources[name] = t;

            return t;
        }

        return nullptr;
    }

    void Unload(std::string name)
    { /* Unloading here, left as an exercise for the student */ }
};

#endif // RESOURCEMANAGER_H


Resource.h
#ifndef RESOURCE_H
#define RESOURCE_H

template<typename T>
class CResource
{
public:
    std::string GetDirectory();
    std::string GetExtension();
    T* Load(std::string name);

}

Texture.h
#ifndef TEXTURE_H
#define TEXTURE_H

#include "Resource.h"
#include "ResourceManager.h"

class CTexture : public CResource<CTexture>
{
    // Texture stuff here
};

extern CResourceManager<CTexture> g_TextureManager;

Texture.cpp
#include "Texture.h"

CResourceManager<CTexture> g_TextureManager;

std::string CResource<CTexture>::GetDirectory()
{ return "./Resources/Textures/"; }

std::string CResource<CTexture>::GetExtension()
{ return ".png"; }

T* CResource<CTexture>::Load(std::string name)
{
    std::string FullPath = GetDirectory() + name + GetExtension();
    // Load texture using the full path.

}

11/15/2014

Game AI - Finite State Machine

I have long had an interest in Game AI. My favorite AI is probably the AI for the creature in Black and White (the first one). I really liked that you were able to teach your creature and it had it's own personality. Training it was frustrating but when you eventually finished it was incredibly rewarding.

Finite State Machine
The finite state machine is nothing like the creature AI in Black and White. A FSM is an architecture or a mindset that allows you to break down an agents behavior into different states. An agent is an NPC or a monster. Each of these states are usually mutually exclusive, which means an agent is only in one state at a time. For example if you have the states Attacking, Fleeing and Searching then the agent would only be doing one of those things at a time. Thinking about creating any one of these states should make you realize that it seems a lot more manageable than trying to just throw together a script that does all that at once. This is why this is so commonly used, it's a simple way of breaking down code into manageable chunks.

Example of a simple state machine

So when do we change from one state to another? Each state has conditions that when fulfilled prompts a change to a different state. In the example you could change from Attacking to Fleeing if the agents hp drops below 10% then start to flee, and if you lose track of where the player is you switch to Searching. The simplest way of doing a transition is to pass in the state manager into as a parameter in the update function and then just do the tests and make the transition.

Implementation
Please note that the following source code is not the best way of implementing a FSM, the code is designed to be as compact and as intuitive as possible.

StateManager.h
The state manager is the class that collects all the different states and keeps track which one is active. All states components of this class.

#ifndef STATEMANAGER_H
#define STATEMANAGER_H

enum{
STATE_SEARCHING,
STATE_ATTACKING,
STATE_FLEEING,
STATE_COUNT
};

class State;

class StateManager
{
private:
State* states[STATE_COUNT];
int current_state;
public:
StateManager();
~StateManager();

void ChangeState(int state_id);

void Update();
};

#endif // STATEMANAGER_H

StateManager.cpp

#include "StateManager.h"
#include "State.h"
#include "StateBehaviours.h"

StateManager::StateManager()
{
states[STATE_ATTACKING] = new StateAttacking();
states[STATE_SEARCHING] = new StateSearching();
states[STATE_FLEEING] = new StateFleeing();
}

StateManager::~StateManager() {}

void StateManager::ChangeState(int state_id)
{ if(state_id < STATE_COUNT) current_state = state_id; }

void StateManager::Update()
{ states[current_state]->Update(this); }

State.h
This is the abstract base class for all states, it defines the protocol by which the state manager communicates to each state. Add things here if you want the state manager to be able to do more with each state.

#ifndef STATE_H
#define STATE_H

class StateManager;

class State
{
public:
virtual ~State() {};
virtual void Update(StateManager* state_manager) = 0;
};

#endif // STATE_H

StateBehaviors.h
Instead of creating 3 different headers for the 3 different classes just for the sake of compacting the code down a bit I put them all in one file. We make sure that all states here implement the update function defined in "State".

#ifndef STATEBEHAVIORS_H
#define STATEBEHAVIORS_H

#include "State.h"

class StateAttacking : public State
{
public:
void Update(StateManager* state_manager);
};

class StateSearching : public State
{
public:
void Update(StateManager* state_manager);
};

class StateFleeing : public State
{
public:
void Update(StateManager* state_manager);
};

#endif // STATEBEHAVIORS_H

StateBehaviors.cpp
This is where you add all your behavior, we have minimal compile dependencies so any change here will only affect this .cpp file. How you get access to the player class you'll have to figure out on your own, there are many ways of doing it and it's up to you to figure out which ones work best for your specific problem.

#include "StateBehaviours.h"
#include "StateManager.h"

// ATTACKING --------------------------------------------

void StateAttacking::Update(StateManager* state_manager) {
if(hp < 10)
state_manager->ChangeState(STATE_FLEEING);
}


// SEARCHING --------------------------------------------

void StateSearching::Update(StateManager* state_manager) {}


// FLEEING ----------------------------------------------

void StateFleeing::Update(StateManager* state_manager) {}

University, Game Development and Game AI

After a long hiatus I'm back. Up until recently I've been taking a Msc in AI from which I have dropped out. The program focused on research and machine learning algorithms seldom used in game development and after 7 weeks I felt it was a bad fit. I did however walk away with new knowledge and renewed enthusiasm for developing video games.

I have begun studying game AI more vigorously and I have a long list of algorithms that I want to try out, not least of which is GOAP (Goal Oriented Action Planning) and Nav-Meshes.

In parallel to my AI experiments I'm applying for jobs, thus far I've only done a test for a game company but I hope I'll be called in for an interview.

Coming up next: Game AI - Finite State Machine

2/02/2014

Designs for world domination


Sorry for the absence, here's a short explanation of my MMO idea.

Have you, like me, thought that it has been enough with all these MMOs that just let you grind the same quests as everyone else. Why can't the players be part of the world. Want to create your own kingdom? Trading empire? Want to raid trading caravans? Work as a mercenary? All this is possible within an MMO and this is how I want to do it.
Form a guild and rally an army, take over a zone and dub yourself king, forge alliances with other kingdoms. Or hire buy wares in one zone and transport them to another, if you have the coin you can even hire NPCs to do the transporting for you, but beware of bandits. Hire mercenaries by predesignating a target number and a promised sum of gold at the end of the trek.

The possibilities are almost endless once you start using this system, write a comment if you have any ideas you'd like to add.

Until next time.