Skip to content
This repository has been archived by the owner on Mar 12, 2021. It is now read-only.

Addition: WorldStateMachine? #41

Closed
JesseTG opened this issue Mar 25, 2014 · 9 comments
Closed

Addition: WorldStateMachine? #41

JesseTG opened this issue Mar 25, 2014 · 9 comments

Comments

@JesseTG
Copy link

JesseTG commented Mar 25, 2014

So I'm working on a game with Anax. I'm using finite state machines to model the change in game state (i.e. main menu vs. in-game vs. splash screen, etc.). I don't wanna publish the source code yet, because it's not properly tested or polished, but here's the gist of it;

  • The WorldStateMachine, of course, maintains a pointer to the World in question (just a raw pointer, though).
  • Rather than directly passing in a new state (e.g. wsm.changeState(TITLE_SCREEN)), I'm writing it with more traditional transitions in mind (e.g. wsm.transition(EXIT)). The states are nouns of some kind (title screen, in-game, etc.), and the transitions are verbs (exit, advance, pause, etc.). Whenever you transition, the WorldStateMachine takes the input and the current state, and looks at the transition table (a std::map) to decide where to go next. If no transition is defined, an exception is thrown.
  • The WorldState itself consists of just three function objects; one called on state exit, one called on state entry, and one called every frame.
  • Systems are not explicitly added to WorldStates; that's what onEnter() is for (though that could be up for debate)
  • WorldState favors composition over inheritance (you're not subclassing it, you're passing functions into it), though I don't see why I couldn't allow both with abstract base classes or something.
  • All states in a WorldStateMachine are referenced by some key
  • There are three template parameters for WorldStateMachine; one is the state type (which is ideally an enum), another is transition type (also an enum, preferably), the third is a parameter pack of arbitrary arguments (e.g. a std::vector<sf::Event>; I know you use SFML). For a WorldStateMachine to be compatible with a WorldState, it must share the last parameter type.
    • This part of the design I'm a bit iffy about. Subject to change.

I'm writing this for my game, but if I were to polish it up and write unit tests, would you want it in Anax?

@miguelmartin75
Copy link
Owner

What advantage does this have to "scenes" (using polymorphism, that is)? For example, my library called pine has polymorphic states implemented within it: https://github.com/miguelmartin75/pine#game-states (note: the library uses a lot of templates, but it could be implemented without).

I know you use SFML

I only use SFML for the examples and prototyping, because it's simple to use and easy to get something to work. I may/may not use it for my final product, depending on the context (e.g. if I want to have a custom renderer, or use a different library to render objects [such as 3D models, particles, etc.]).


The WorldStateMachine seems a bit 'fixed'. (e.g. wsm.changeState(TITLE_SCREEN) depends on TITLE_SCREEN; is this an enumeration? and why do I need to know the state type during run-time?).

Does the WorldStateMachine depend on anax? I don't think it's really necessary for it to be included with the library. Perhaps make a separate repository for it? You could put a link to it in the wiki if you like, discussing ways to handles states and suggesting your own method (and comparing it with others, such as the one I mentioned above).

@JesseTG
Copy link
Author

JesseTG commented Mar 25, 2014

Yes, TITLE_SCREEN is part of a hypothetical GameState enum. And what do you mean knowing the state type at run-time?

@miguelmartin75
Copy link
Owner

I don't necessarily understand why you need to know what specific state you're in. i.e. if you switch to TITLE_SCREEN, you probably store the enumeration that tells you that you're in the title screen. However, you can just use polymorphism to achieve the same result, however, you don't require to know what state you are currently in.

In other words, you're defining a state as an enumeration, but why not as a polymorphic object? Then you don't need to know what type of state you're in, it is much more flexible (but of course requires inheritance, which is in some-ways bad, but in this specific case it seems rather useful IMHO). Unless you could use this state machine for more than just title screens/menus/etc.?

@JesseTG
Copy link
Author

JesseTG commented Mar 26, 2014

I maintain it as both in case the same state object might be reused, but with different parameters of some kind. Also, so state objects aren't copied around too much. Like I said, I haven't worked out all of the design details yet.

In my game, I actually provide two flavors of WorldStates; one is the usual abstract base class with onEnter(), onExit(), and update() methods. The other, CompositionWorldState, takes in three std::functions as parameters, and those are the functions that are called.

@miguelmartin75
Copy link
Owner

I maintain it as both in case the same state object might be reused, but with different parameters of some kind. Also, so state objects aren't copied around too much. Like I said, I haven't worked out all of the design details yet.

I'm actually interested to know what this is exactly. I suggest putting up the code on github so I can see it (even if you haven't finished it, it doesn't matter).

@JesseTG
Copy link
Author

JesseTG commented Apr 17, 2014

Sure, I just need to decouple it from my own code. I'll make a pull request some time soon. There's a couple of other unrelated things I noticed would benefit from changing, too.

@miguelmartin75
Copy link
Owner

I'll make a pull request some time soon

I'm not sure if it would be best (for users that is) for a WorldStateMachine to be added to the entity system. Since one of the design goals is to be quite minimalistic (i.e. aim to do one thing only, and that is provide an entity system, which is the same reason I don't have my own event system and etc. built in). Perhaps a separate repository would be better suited IMO, unless your "unrelated" changed directly change the entity system itself (if so, then perhaps have a separate pull request for these changes and a independent repo for the WorldStateMachine).

@JesseTG
Copy link
Author

JesseTG commented Apr 17, 2014

I haven't changed Anax itself, I just have some ideas. WorldStateMachine does depend closely on Anax, though.

@miguelmartin75
Copy link
Owner

I don't think this is really necessary for the library. However, feel free to link to your project here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants