• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Sign up now

# How to avoid game state hell (huge switchs)?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

18 replies to this topic

### #1Icebone1000  Members

Posted 19 June 2012 - 12:38 PM

The last 2 projects I worked on ended up like this:
(pseudo c#)
[source lang="csharp"]public class InGame_Situation1{ public enum state_S1 { fadein, waitFade, initialDlg, doThat, animateNPC2, waitNPC2FinishAnimation... }; public state_S1 internalState = fadein; void Update(){ switch( internalState ){ case fadein:{ fadescreen.fade(); internalstate = waitFade; }break; case waitFade:{ if( !fadescreen.isfading ) internalstate = initialDlg; }break; ... } }};[/source]
Its incredible easy (adding new stuff is easily donne by adding enums and case blocks), but incredible ridiculous, every time something changes, ctrl+f entire solution to the rescue..
So, what should I do? what comes to mind is state machines, event driven systems and message driven systems...But I have never implemented one, the experience I have with stuff like this are the win32 message system, and the SDL event driven system, never saw and I have no clue on what would a system that handle game states would look like.

When I think on how it would be, I start get confuse with stuff that need to be communicated across lots of objects (like stuff that happens in parallel)..

Lets say I want to fade out the screen, in that moment (the screen is fading), all my GUI should become inactive(but still displayed), the problem is, theres a lot of GUI/HUD objects that handle gui for different parts of the game( i.e. pause menu, dialogues with npc, inventary...), so what Id do? each of those would have a fadescreen listener registered? Or the listner itself would have links to all gui objects that need to be deactivated? Or Im way out of reality?

Any source, tips, snippets, links, whatever would be great..

Id try my own to see what happens, but If things goes bad I dont believe I have the time to redo everything..since those systems are the core..

### #2frob  Moderators

Posted 19 June 2012 - 01:13 PM

POPULAR

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();
}
}


You can then create new behaviors easily by deriving from the base class, or from deriving from an existing class. You can keep the behavior code contained to the individual behaviors. If for some reason external people need to work with your code, the added benefit is that they can create new behavior without modifying your original base code.

Edited by frob, 19 June 2012 - 01:17 PM.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

### #3sss_abaker  Members

Posted 19 June 2012 - 01:56 PM

Except that the strategy pattern comes with a significant cost and that's the cost of virtual look up every time you call a Strategy's method. Optimized code is not necessarily the best looking and most manageable code.

So ask yourself and clarify for us, do you want performance or convenience? With that in mind notice that the examples are written in JAVA. Most Java apps don't care too much about performance on the level required by a game.

### #4smr  Members

Posted 19 June 2012 - 02:59 PM

POPULAR

Except that the strategy pattern comes with a significant cost and that's the cost of virtual look up every time you call a Strategy's method. Optimized code is not necessarily the best looking and most manageable code.

I think it would be at best premature to worry about optimizing away the virtual call to update using a switch and at worst an incredible waste of development time both up-front and in maintenance.

Edited by smr, 19 June 2012 - 03:00 PM.

### #5frob  Moderators

Posted 19 June 2012 - 03:12 PM

POPULAR

Except that the strategy pattern comes with a significant cost and that's the cost of virtual look up every time you call a Strategy's method.

Depends on which paper you read, but looks like the cost currently tends toward about 7 nanoseconds for a virtual function. It takes longer to fetch memory to the cache.

If the few nanoseconds in that above update loop are critical then there is a very serious problem with his app.

I've used the pattern on major AAA games ranging from high-performance games requiring multi-core processors all the way down to 66MHz handhelds. The overhead of virtual function use is negligible, especially in comparison to the development time and the developer's sanity.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

### #6BornToCode  Members

Posted 19 June 2012 - 04:49 PM

What i did in my engine is a similar system using Function Pointers instead. So each state registered an function pointer and whenever you switch state, you call the proper function pointer for the state you are in.

### #7Narf the Mouse  Members

Posted 19 June 2012 - 06:31 PM

Except that the strategy pattern comes with a significant cost and that's the cost of virtual look up every time you call a Strategy's method. Optimized code is not necessarily the best looking and most manageable code.

So ask yourself and clarify for us, do you want performance or convenience? With that in mind notice that the examples are written in JAVA. Most Java apps don't care too much about performance on the level required by a game.

Premature optimization is a root of evil.

Don't know where I first read that sort of thing, but it's so very, very true.

Worry about optimization:

1) When it's relevant.
2) When you know how your code will work.
3) When you know where the slowdowns are (Code profiling).

This isn't an excuse to write lazy code, but writing your code around "optimization" for anything other than a small coding exercise is a great way to drive yourself nuts.

### #8frob  Moderators

Posted 19 June 2012 - 06:40 PM

What i did in my engine is a similar system using Function Pointers instead. So each state registered an function pointer and whenever you switch state, you call the proper function pointer for the state you are in.

Whether you use inheritance's vtables -- which are nothing more than function pointers -- or you manually do it yourself with a function pointer table, the end result is the same. The real difference is letting the language do the work for you.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

### #9Cornstalks  Members

Posted 20 June 2012 - 12:19 AM

Premature optimization is a root of evil.

Don't know where I first read that sort of thing, but it's so very, very true.

Donald Knuth said that, in this paper (page 8 (or page 268 of the full thing), right hand column, end of the paragraph). He's the one who is quoted as saying that, and it is indeed true.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

### #10Icebone1000  Members

Posted 20 June 2012 - 08:05 AM

...

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();
}
}


You can then create new behaviors easily by deriving from the base class, or from deriving from an existing class. You can keep the behavior code contained to the individual behaviors. If for some reason external people need to work with your code, the added benefit is that they can create new behavior without modifying your original base code.

Thanks a lot for the response!
Some questions regarding the method you described, Im not so sure about how Id use it..

How Id change to the next behavior? If one behavior is responsible for changing/update to the next behavior, then I lose reusability of behaviors (after the first fade complete, change to the first dialog, but the next fades will change to new behaviours..so : next question)

Each behaviour would be unique? i.e. InitialFadeBehavior, FadeBeforeAnim1Behavior, FadeToScene2Behavior, FadeBeforeAnim2Behavior...? (each would derive of a base FedeBehavior like you mentioned, I believe)

My current enums really have a LOT of values, some have 20 +, some case blocks have really 2 lines of code, is it fine to create classes and objects for stuff like this? Im used to see classes as more complex stuff, maybe I should review my concepts..Im afraid of the number of simple small classes that will sum up.

(Dont know if its relevant, the current games Im working on are really a bunch of diferent situations, its not a constant game play where the things that change are level design and amount of enemies, its like a bunch of scenes with some diferent interactive GUI each, depending on user choices, different paths are taken, etc..)

### #11L. Spiro  Members

Posted 20 June 2012 - 08:53 AM

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

### #12Calin  Members

Posted 20 June 2012 - 02:01 PM

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;

### #13smr  Members

Posted 20 June 2012 - 04:06 PM

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.

### #14NEXUSKill  Members

Posted 21 June 2012 - 10:17 AM

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

### #15Narf the Mouse  Members

Posted 21 June 2012 - 10:28 AM

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.

### #16frob  Moderators

Posted 21 June 2012 - 10:42 AM

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.

Edited by frob, 21 June 2012 - 10:43 AM.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

### #17sss_abaker  Members

Posted 21 June 2012 - 03:33 PM

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.

### #18Cagnazzo  Members

Posted 21 June 2012 - 07:34 PM

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

(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)

### #19DemonRad  Members

Posted 22 June 2012 - 01:22 AM

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!

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.