[Tutorial] Part 1: Game and Systems - UbiBelETF/dagger GitHub Wiki

Game and Systems

Game setup

To start a new project, you're looking to extend the Game class. The class is defined in core/game.h:

    struct Game
    {
        virtual void CoreSystemsSetup(Engine& engine_);

        virtual String GetIniFile() = 0;
        virtual void GameplaySystemsSetup(Engine& engine_) = 0;
        virtual void WorldSetup(Engine& engine_) = 0;
    };

The CoreSystemsSetup method has a default implementation that adds all the relevant engine systems. The GetIniFile() method defines what your project's ini configuration file is; the default directory for these is in data. Copy one of the present ini files to start.

The GameplaySystemsSetup and WorldSetup functions actually define your game's behaviour. Usually, you'll be using the void Engine::AddSystem(System) function in GameplaySystemsSetup, as this is where all the systems are declared and started. The WorldSetup function takes care of creating your game's entities and decorating them with components.

Once you're done, run your game from int main(int argc_, char** argv_):

int main(int argc_, char** argv_)
{
	dagger::Engine engine;
	return engine.Run<YourGameClassName>();
}

If you've implemented the virtual functions as empty, you should see a blue window open when you run the project!

About Systems

You can think of a system as a function that will run each frame and do something with the entities of your game. Try to keep your systems simple and single-minded: a system should always be fulfilling only one purpose. When considering what this purpose is, it helps to think about systems as filters for component types: you might want to filter all Sprites and all Player components, and do something to them, for instance.

The System class (in core/system.h) has four parts:

struct System
{
	virtual String SystemName() = 0;
	virtual inline void SpinUp() {};
	virtual inline void Run() {};
	virtual inline void WindDown() {};
};

The SystemName defines the string name of your system, so the implementation is pretty simple: basically just return "My System Name";. This function is used for diagnostics, mostly, but is nice to have around.

The remaining three functions define the lifetime of a system: SpinUp() is called once at the start of the game, WindDown() once at the end, and Run() is called once per frame and is where all of our logic usually happens.