• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Gasimzada

"Proper" state management for CBE

9 posts in this topic

I have asked a question similar to this before but I cannot move forward with my engine without fixing the State Machine. In my old design, the systems hold the needed components and updated them as needed and the states hold the systems they need. Like "Play" holds graphics,physics,input,ai,gui; the "MainMenu" holds gui,input. Also, the states are not hard written to the engine; one can create any type of a system they want with the needed components. The problem was that new systems are created for each state; for example there would be multiple input systems in the lifecycle of the application if more than one state has input system.

 

As my engine become more complex, I decided to change the design to something similar to Artemis Framework. So, here is the new design:

 

The systems are created ONCE only and their pointers are passed to the needed states. Each state holds a component map. The first parameter of the component is the pointer of the system. The second parameter is of type ComponentHolder. A component holder is basically an abstract class of different lists of components. For example a GraphicsComponentHolder holds 3 lists {list<GraphicsComponent*>, list<CameraComponent*>, list<LightComponent*>}

 

Example Snippet:

class GameState {
private:
   std::map<Controller*, ComponentHolder*> mControllers;
   std::map<View*, ComponentHolder*> mViews;

public:
   void update(Real time) {
     for(auto &controller : mController)
        controller.first->update(time, controller.second);
   }

   void render() {
     for(auto &view : mViews)
        view.first->render(view.second);
   }
};

class HordeCameraController : public Controller {
public:
   void updateNode(SceneNode * node) {
     //...
   }

   void update(Real dt, ComponentHolder * holder_) {
      auto holder = static_cast<HordeComponentHolder*>(holder_);
      for(auto graphics : holder->getGraphicsComponents())
         updateNode(graphics);

      for(auto camera : holder->getCameraComponents())
         updateNode(camera);

      for(auto light : holder->getLightComponents())
         updateNode(light);
   }
};

class HordeCameraView : public View {
public:
   void render(ComponentHolder * holder_) {
      auto holder = static_cast<HordeComponentHolder*>(holder_);
      for(auto camera : holder->getCameraComponents())
         h3dRender(camera->getNode());
   }
};

Is there another way I can build this? Or should I do it this way? Should I just update the component holder when state changes or do something different. I am very noob at state management, so I really need help on designing on.

 

Thanks,

Gasim

0

Share this post


Link to post
Share on other sites

Hello there!

 

I too have had my share of problems implementing a finite state machine.

I have found the very last answer in this thread (the post from Henrique Barcelos) to be a very good starting point.

It is easy to understand and the implementation is very generic.

 

Good luck!

 

*EDIT: I guess I didn't really answer your question..

 

First of all I agree with phil_t that you should try to keep your components more generic in general.

If you do follow the example that I posted a link too, I think a good idea would be to put the system parts of the ECS in the machine and component parts in the states.

 

Something like this psuedo code..

// In machine.cpp

void Machine::on_render()
{
  _state->on_render(*this);
}
 
// In some state.. lets say play-state.cpp
void PlayState::on_render(Machine& machine)
{
  machine._renderSystem.on_run(this->_world);
}

..where _renderSystem is a local RenderSystem in machine and _world is a local container of components (enteties)

Edited by AlanSmithee
1

Share this post


Link to post
Share on other sites


I don't understand for the need for subclasses of ComponentHolder (e.g. what additional behavior does GraphicsComponentHolder have over ComponentHolder?). Likewise, I don't understand the need for subclasses of View and Controller. Can't Controller just update all of the things inside the ComponentHolder?

 

The controller needs to know how its going to update the holder: bullet physics updates the holders in its own way, the graphics controller updates it in its own way; same with the Views. As for the subclassing of holders, I only do that for having less amounts of castings to the needed type. Instead of casting every component to the right type, I just cast the holder to the right type and access its elements. How would you do it? I don't really understand how its possible to have generic holder, view, and controller classes while still preserving flexibility of the state machine.

 


Backing away a bit: maybe you should even reconsider the notion of GameStates. What's the real difference between the "Play" state and the "Main Menu" state? Aren't the states simply implied by the currently active entities/components? Do you really need any custom functionality for the states?

 

For me there is not meaning behind States as there is no meaning behind Entities. They are both just containers with ID. The way I think about both of them is like a Storage Unit - by themselves, they are pointless; but once you put the things in it, they get valued :P The State Manager I want to implement is very different than most I have seen in the internet; the ones I have seen always inherit from a base State class to a PlayState or MainMenuState. For my state management, there is a generic State class; that is handled by any sort of state machine - whether its FSM, HFSM, or BT. Then, there is a special case "GameState" where its used for changing menus or whatever. This container itself consists of "components" = managers, controllers, views. The systems are identified by "name". The main difference between controllers/views and managers is that, each state has its own created manager, while each state stores only the reference to the particular controllers/views. The controllers "don't care" about the existence of a state, they run in separate threads and update/render whatever is given to them. I have had Managers, Controllers, and Views working altogether but I want to change that and separate the controllers/views. 

 


In my current project, I do sort of have the concept of "states", and each state has it's own completely separate entity manager (and completely separate systems). This does have the advantage that I can easily just completely shutdown and destroy all the entities related to the main menu screen, for instance (this would be more difficult if I shared entity manager and systems across states). So that's something you might want to think about too. I don't have any custom subclasses for my states, because they don't have any custom functionality... they're just the sum of their parts (i.e. their functionality/logic is completely defined by the entities that exist in them). And I do have some code that sits above the states that manages transitions from one to another.
 
I've been wondering if I could refactor this a bit though, and eliminate my separate entity managers altogether.

 

I just realized that I want to build something similar to what you have :) The moment I have a working version of what I want to achieve, I am thinking of getting rid of the entity class all together because it has no specific function than be a "middle man" between the components, which I think components should do directly. For me it makes sense to have a State because of transitions in the State Machine. But for Entity, I would rather change it to a sorted double linked list of components (or maybe a set. i'll figure it out when its time); where one can find the other components by comparing IDs. One question, about Entity Managers? what are they? Are they basically a World or are they the creator of the entities? Or are they both?

 


I too have had my share of problems implementing a finite state machine.
I have found the very last answer in this thread (the post from Henrique Barcelos) to be a very good starting point.
It is easy to understand and the implementation is very generic.

 

My main problem is not the implementation of the state machine but the design of a flexible and generic GameState (MainMenu or Play) that can be created into anything.

 


If you do follow the example that I posted a link too, I think a good idea would be to put the system parts of the ECS in the machine and component parts in the states.
 
Something like this psuedo code..

 

I really like the idea of the world. Can you please give me an idea of what a world is? What can it do? What does it store? How is it compared to my ComponentHolder? Is it just a container of component holders?

 

I think this topic isn't about state management but more about "Designing a world object"

0

Share this post


Link to post
Share on other sites


The controller needs to know how its going to update the holder: bullet physics updates the holders in its own way, the graphics controller updates it in its own way; same with the Views. As for the subclassing of holders, I only do that for having less amounts of castings to the needed type. Instead of casting every component to the right type, I just cast the holder to the right type and access its elements. How would you do it? I don't really understand how its possible to have generic holder, view, and controller classes while still preserving flexibility of the state machine.

 

I guess I'm still trying to wrap my head around your architecture. You may be using different terms for the same concepts (there isn't really a common way to implement entity-component frameworks).

 

In my framework, you just create a particular System and add it to a list in the EntityManager. Each system is updated in exactly the same way (why wouldn't it?), there are no "views" or "controllers". If I want to make a new system, the only code changes it requires is in my initialization code when I add it to this master system list.

 

The EntityManager stores all the components (one array per component type). It exposes a "component map" for each component type that lets you get a particular component given an entity id. The systems (which have their own list of entity ids that is kept up-to-date by the EntityManager) use these to fetch the components by entity id.

 

However, if a system only depends on one component type, it can just enumerate through the "component map" directly (it doesn't care which entity it belongs to). Otherwise (in the common-use case where a system depends on multiple component types) it uses its list of entity ids to request the necessary components for each entity id.

 

You mentioned the Artemis framework. My original design was based very closely on this, so it should be familiar.

 

I describe some of it here:

http://mtnphil.wordpress.com/2013/03/27/entity-component-system-architecture-c/

1

Share this post


Link to post
Share on other sites


In my framework, you just create a particular System and add it to a list in the EntityManager. Each system is updated in exactly the same way (why wouldn't it?), there are no "views" or "controllers". If I want to make a new system, the only code changes it requires is in my initialization code when I add it to this master system list.

 

Do you register observers to the systems to do some system specific codes. Thats why I have a different update function per system. Like BulletSystem update:

//Bullet.cpp
void BulletController::update(World * world) {
   btDynamicsWorld * dynWorld = world->getHolder<BulletHolder>()->getBulletWorld();
   dynWorld->stepSimulation(1/60.0, 0);
}

//HordeController.cpp
void HordeGraphicsController::update(World * world) {
   for(auto component : world->getHolder<HordeNodeHolder>()->getNodes())
      updateComponent(component);
}

//HordeCameraView.cpp
void HordeCameraView::render(World * world) {
   for(auto component : world->getHolder<HordeCameraHolder()->getCameras());
      h3dRender(component->getHordeNode());
}

For me doing view vs controller is just a conventional thing. I just split the system into Controller and Views, where controllers do update while views do render.

0

Share this post


Link to post
Share on other sites

Ah, ok, it was just a term misunderstanding. No, I have custom System implementations, just like you have custom Controller and Views.

1

Share this post


Link to post
Share on other sites

I've been wondering if I could refactor this a bit though, and eliminate my separate entity managers altogether.

 

We decided to apply the concept of a Scene to entities.  

 

Each entity references their owning Scene which is managed through the engine's SceneManager.  In the background, every scene instance uses the same entity manager and component subsystems.  We initially had them separated as you do, but decided to that each system could just as easily create buckets per scene and maintain various lists of components, allowing us to update all scenes in one loop or update certain scenes more frequently than others with a simplified main loop.

 

Plus when we want to eliminate that login or character selection screen of entities or perhaps a transition map's set of entities, we can do so using a timeout-based task that will call the Scene's destroy method if the scene remains untouched by the engine for a defined period of time.  This was a big plus where players entered a dungeon, later died and were teleported to the graveyard and then had to run back to the instance and rez.  The load time on the instance was drastically reduced.

0

Share this post


Link to post
Share on other sites

Thats how I do it now, I have a "World" class that holds component holders holders and the systems act upon those component holders. The World doesn't care about the existence of any manager or system. I am still thinking about making design more cleaner as I am deciding whether a system should know about the state dealing with resources or does the system only act upon the world where the world is coming from, either from a state or from somewhere else.

0

Share this post


Link to post
Share on other sites

I don't believe that systems should care how the World came into existence, whether by something which the current application state creates or whether it is something that was created due to an event triggering specific actions in a subsystem.  

 

In our engine's design, the World emits events when specific actions take place with an entity and the systems are simply subscribers to various events of interest.  When the events fire, enough context data is provided so that the systems can obtain the world reference, query entity state, or even manipulate other systems through various exposed interfaces from the engine's core framework.  

 

These systems are self contained behavior that alter state based on a finite set of inputs.  Their dependencies are generally kept quite lean primarily to advocate decoupling and the ability to plug and play variations of system behavior without disrupting the core game mechanics too harshly.

Edited by crancran
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0