How to avoid game state hell (huge switchs)?

Started by
17 comments, last by Dario Oliveri 11 years, 10 months ago
You may find this useful.
Again, virtual functions drive the scenes, but you can ignore the warnings regarding the performance penalty—this results in 2 virtual calls per frame, which would not even slow down a PlayStation 3. This is a state machine.

A mix between this and what was mentioned by frob is ideal.
This is a macro-level arrangement (a CState for the entire main menu, another one for the entire options menu, etc.) and then within each state you will use frob’s method to create substates. This is where you handling fading in the main menu, flashing the buttons after they are pressed, fading out, etc.

You are over-engineering a lot of things. A “fade-screen listener” seems to have no purpose, and certainly should not be registering a bunch of objects. If a state needs some fade, it can make a CFader instance and render that on top of itself over the whole screen while fading in or out. These should be instances owned within each state, not connected to anything else. This allows them to be layered—your pause menu fades out the game screen a little, and then a sub-menu adds even more fade over the pause menu and the game screen.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Advertisement

Generally the code smell of complex case statements is resolved through inheretence and the strategy pattern.

Depending on the code smell there may be other patterns (such as the Visitor pattern) that may apply depending on your details.

In your example you might implement:


class UIUpdateBehavior
{
virtual void OnUpdate()
{
BaseUpdateBehavior();
}

void BaseUpdateBehavior
{
// Normal behavior here.
}
}


class IdleBehavior : UIUpdateBehavior
{
// Does nothing special
}


class FadeInBehavior : UIUpdateBehavior
{
virtual void OnUpdate()
{
// do stuff differently
}
}


With similar classes for your states (waitFade, initialDlg, doThat, animateNPC2, waitNPC2FinishAnimation, etc.)


In your Update() loop you can reduce it to:

Update()
{
if( mCurrentUpdateBehavior != null )
{
mCurrentUpdateBehavior.OnUpdate();
}
}




could you expand the code a little more, how do you jump from one state to another i.e . if( !fadescreen.isfading ) internalstate = initialDlg;

My project`s facebook page is “DreamLand Page”



could you expand the code a little more, how do you jump from one state to another i.e
. if( !fadescreen.isfading ) internalstate = initialDlg;



You can have a mNextState member that would be set to the current state upon completion of the update. Or at the beginning of the next update. Either way, this will prevent the CurrentState from being changed during the actual update of the entity/game object/whatever you're calling it.
A simple yet flexible solution for this is a Finite State Machine, you are likely to use it for many other purposes as well such as AI agent behavior simulations, so its always good to have a generic implementation at hand.

It can get as complex and powerful as you want it to, but the basic implementation is very straightforward and can get you up and running in no time.
Game making is godlike

LinkedIn profile: http://ar.linkedin.com/pub/andres-ricardo-chamarra/2a/28a/272



A simple yet flexible solution for this is a Finite State Machine, you are likely to use it for many other purposes as well such as AI agent behavior simulations, so its always good to have a generic implementation at hand.

It can get as complex and powerful as you want it to, but the basic implementation is very straightforward and can get you up and running in no time.

That still leaves you locked to a state machine.

That still leaves you locked to a state machine.

The OP described a state machine.

State machines are perhaps the most often use control system for complex systems, or any system that needs a simple flow.

I've probably written a thousand state machines over my career so far.

In my current mass-production of game objects I'm creating about three state trees every week and the code that goes inside them.


I completely agree about having generic state machine code available in any serious game. It is necessary functionality.
I suppose I came in half cocked. I don't optimize as I code myself and I use polymorphism pretty liberally. I simply code with those thoughts in mind. But I was of the mind that polymorphism's cost was still a determining factor when deciding whether or not to use it and I never did any experiments to confirm. Thanks for setting me straight guys.
Yeah, the need for experimentation is pretty often unstated, but very important. People are notoriously bad at seeing what actually is costing them time so they try to optimize everything. It's variable on the code, of course, but I have a software engineering book here whose author mentions several times that 5% of his code caused about 90-95% of the slowdown. Optimizing everything as it's written in that case means 95% of the work is wasted.

You might call that habit suboptimal tongue.png

(Not that you shouldn't ignore obvious inefficiencies as you write, of course, but weigh "this'll be easy to change later" and "this is easy to read" over "it'll run faster if I do this," especially before you actually profile it)
you just have to use a state pattern
Every state just setup next state when needed. This require onl 1 virtual function call /frame (update current state) and 1 extra virtual function call when switchin states(set state). Every states need to know only about the AbstractState in the interface and need to know only about few states can be setted from it in the implementation. No huge classes etc. That's one of the most basic design patterns very usefull in games you need to know. Many books uses that pattern

Peace and love, now I understand really what it means! Guardian Angels exist! Thanks!

This topic is closed to new replies.

Advertisement