torsdag 1 september 2011

Yet Another Hobby Project

In lack of better things to write about, I thought I'd share some hobby work I've been doing lately.

The game in question is a straight off clone of the old X-Com games (with a different scenario slapped on instead of the whole alien invasion). The idea is that the basic gameplay in the game will be more or less the same as in the old X-Com games, but with a more streamlined and minimalistic UI etc.

Globe View (Autowin: Orange and Teal)
Tactical View (Still sticking to Orange and Teal, Enemies will stand for the orange once I have time to model them)
The environments are built up by having different pre-created building blocks (all placeholders still). Right now the levels are built by hand, but I got a cool idea of generating them using a some nifty tricks together with the A* algorithm (I might make a post about this at some later stage).

The skeleton of the tactical game has been implemented. As in the old games its all turn based and you can walk around and shoot with all your units (all costing Time Units of course). There's also a daft AI that can roam around and shoot back (not much of a challenge yet).

Anyways... enough blogging for a while and back to coding.

tisdag 9 augusti 2011

A Nifty Resource Manager

Here's some meat before we get to the pudding. Every hobby game engine (worth a damn) will needs a resource manager of some sort. This being "next-gen" and all, we got a few requirements on our resource manager as well:

  • It should manage ALL types of assets
  • It should support automatic hot loading of ALL assets
  • It should manage resource dependencies

So without further ado, meet the resource interface (a bit trimmed down) from which all our specific resources will inherit:

class IResource
{
    public:
        IResource( string filename );
        virtual void release() = 0;
        virtual void reload() = 0;
        bool needsReloading();

    protected:
        string    m_filename;
        FILETIME  m_lastModifiedTime;
};

This resource system is based on the assumption that each and every resource is stored using a separate file (something which isn't always the case, but for sake of discussion). The needsReloading() function simply checks the modified file time of the resource and returns true if the file has been modified.

The release() function simply releases all memory etc. tied up by the resource, and the reload() function loads the resource in from the file again. Now we just need a manager class (usually a singleton) to keep track of all the resources:

class ResourceManager
{
    public:
    
        template<class T>
        T* getResource( string strFilename )
        {
            if( m_resources.count( strFilename ) > 0 )
                return dynamic_cast<T*>( m_resources[ strFilename ] );

            // create and add new resource
            T* pResource = new T( strFilename );
            m_resources[ strFilename ] = pResource;
            return pResource;
        }

        void update();
        void releaseAll();

    protected:
        map<string, IResource*>    m_resources;
};

The ResourceManager class keeps a map of string (filenames) and resources (specific resources of various types). Every time a resource is requested it checks the map and see if it has already been created (if not it creates it with some template magic and adds it to the map). Note that in a proper engine you'd probably use a hash table and instead of strings you'd use hashed string IDs instead. But for your average hobby project with not too many thousands of assets this should work just fine.

To get a resource you simply call:


IResource* pSomeResource = ResourceManager::getInstance()->
                           getResource<MyResourceType>( "Resources\\MyResource.bin" );

In the update function of the ResourceManager we check whether any assets have been updated and if so, we call the reload function:

void ResourceManager::update()
{
    // loop over all the assets
    for( map<string, IResource*>::iterator it=m_resources.begin(); 
         it != m_resources.end(); ++it )
    {
        // check if assets needs to be reloaded
        if( (*it).second->needsReloading() )
        {
            // reload resource
            (*it).second->reload();
        }
    }
}

Note that this should of course be spread out over time, it's quite unnecessary to check this every single frame. That's more or less all there's to it. Managing dependencies between different assets is also something that should be handled by the resource manager. For example a mesh might add dependencies to stuff like materials (which might govern the vertex format of the mesh). Should the material then be updated, the resource manager will also call the reload() function of all the meshes that are dependent on that material and so forth.

Another thing to note is that the whole automatic hot loading, dependency registration etc. are things that shouldn't be in the final build of course. So the easiest thing to do is to wrap all that logic in a '#ifndef FINAL' preprocessor block.

A bit more fleshed out version is available here: ResourceSystem.zip
(Build & Start the exe, then change the values in the resource text files and watch the magic happen)

torsdag 28 juli 2011

Development Cycle

Back in the time when I was young... I would start a game project, dive into it head first without thinking, planning or even designing. After a few weeks I would have gotten lots done, a game almost, but the code would look like most people's attic or basement do. This is about the time when the code would become cumbersome to maintain. It would also be around this time when I would be distracted by something shiny and rush off to start the next epic project. A quick glance at my old project folder shows I got over 70 of these unfinished projects. Each and every one of these project would reuse exactly 0 lines of code between them (with the exception of the odd copy/pasted/modified line).

Then I reached puberty... This was around the time I got my first job in the industry. I got to see how the real developers did it. It seemed my betters were building game projects in layers were the low level layers could be reused between game projects. Not being a complete idiot I quickly picked up this idea and started building my own framework of reusable code... (On the other hand scratch that... Since I hadn't figured this out after 70 or so unfinished hobby projects, perhaps I was a complete idiot). Anyways, the only thing that changed was that I was spending my hobby time writing game engines instead of game projects. Instead of 70 unfinished games I now soon have around 10 unfinished game engines.

When I grow old... I think I will complete the cycle and go back to just simply writing games from scratch. I think I will know enough to select projects of a manageable size. I think I will have no other ambition with the project other than to have fun making it... and I think I will never grow old.

Hello world!

So I've been hearing about this new cool thing called blogging... apparently it's the latest thing so I thought I would give it a go.

My plan is to put stuff I do, learn and figure out while programming games here. But like with all my little pet projects we'll see how long I manage to stay focused on one thing.