• 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
Icebone1000

How to avoid game state hell (huge switchs)?

18 posts in this topic

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..
0

Share this post


Link to post
Share on other sites
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.
-2

Share this post


Link to post
Share on other sites
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.
0

Share this post


Link to post
Share on other sites
[quote name='sss_abaker' timestamp='1340135769' post='4950701']
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.
[/quote]
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.
0

Share this post


Link to post
Share on other sites
[quote name='Narf the Mouse' timestamp='1340152279' post='4950779']
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.
[/quote]
Donald Knuth said that, [url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.103.6084&rep=rep1&type=pdf"]in this paper[/url] (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.
0

Share this post


Link to post
Share on other sites
[quote name='frob' timestamp='1340133229' post='4950679']
...

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


In your Update() loop you can reduce it to:
[CODE]
Update()
{
if( mCurrentUpdateBehavior != null )
{
mCurrentUpdateBehavior.OnUpdate();
}
}
[/CODE]

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.
[/quote]

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..)
0

Share this post


Link to post
Share on other sites
You may find [url="http://lspiroengine.com/?p=351"]this[/url] 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 [i]substates[/i]. 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
0

Share this post


Link to post
Share on other sites
[quote name='frob' timestamp='1340133229' post='4950679']
Generally the code smell of complex case statements is resolved through inheretence and the [url="https://www.google.com/search?q=Strategy+pattern"]strategy pattern[/url].

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:

[CODE]
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
}
}
[/CODE]

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


In your Update() loop you can reduce it to:
[CODE]
Update()
{
if( mCurrentUpdateBehavior != null )
{
mCurrentUpdateBehavior.OnUpdate();
}
}
[/CODE]

[/quote]

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

Share this post


Link to post
Share on other sites
[quote name='Calin' timestamp='1340222509' post='4951101']

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

[/quote]

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.
0

Share this post


Link to post
Share on other sites
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.
0

Share this post


Link to post
Share on other sites
[quote name='NEXUSKill' timestamp='1340295438' post='4951403']
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.
[/quote]
That still leaves you locked to a state machine.
-1

Share this post


Link to post
Share on other sites
[quote name='Narf the Mouse' timestamp='1340296138' post='4951408']
That still leaves you locked to a state machine.
[/quote]
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
0

Share this post


Link to post
Share on other sites
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.
1

Share this post


Link to post
Share on other sites
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 [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img]

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

Share this post


Link to post
Share on other sites
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
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