Game State Management using Ox

Jun 14, 2010 at 3:37 AM

So far in my experience with XNA, I've followed an architecture similar to the Game State Management example on the XNA education catalog. The simplicity of it is awesome, and the organization of screens into isolated areas is easy.

With the Ox Game Engine, how would something similar be achieved? I've been playing around with it a bit, but the learning curve seems a bit steep. Also, all the examples I've seen so far have just been of a single screen, usually just crammed into one code location.

Does anyone have tips on how they architect their state management within Ox?

Thanks.

Jun 18, 2010 at 1:41 PM
Heya Dharwin, I am currently working on a project using the Ox Game Engine, and to manage my game states, I based my code on the XNA Game State Management sample. Basically, I used the sample to manage the menus etc., instead of using Ox's built in GUI system. and the engine is only called upon just before the gameplay screen is initialized, and then updated as the game runs, essentially keeping the menu system separate from the game engine. In order to be able to use custom graphics, I followed the advice from this thread: http://oxgameengine.codeplex.com/Thread/View.aspx?ThreadId=210489 The function outlined in the above thread allows for the use of XNA's built in sprite drawing capabilities. I will try and get a working sample uploaded by 11:00 pm GMT tonight if I can! I hope I've helped a bit. Best Regards, and Good Luck!!! InSlayn
Jun 19, 2010 at 6:10 AM

Your post was indeed helpful. I'll get back to trying things out. A sample upload would be amazing, since I'm a bit confused on things like entry point, and how to manage where the engine comes into play.

Thanks a ton for taking the time to help! =)

Coordinator
Jun 19, 2010 at 9:38 PM
Edited Jun 19, 2010 at 10:23 PM

I personally much dislike the Game State Management sample.

The truth is that your game is in whatever state it is in. The engine is in whatever state it is in. Having explicit state variables is a violation of DRY (don't repeat yourself) as the application probably already has enough existing information to tell you the abstract state it's in. All you have to do is interpret that information. I personally just write a State property or GetState function somewhere that inspects your game's context and deduces what state the game is currently in.

Jun 20, 2010 at 12:35 AM

I'm not sure I follow you, bryanedds.

The Game State Management sample does not use explicit state variables. At least not in the way I'm picturing your description of them. Unless you consider a stack of Screen objects to be that.

If you mean the type of state management where you have a GAME_STATE enum and a current_state property, then yes, I dislike that as well, but that's not how the state management sample worked.

Coordinator
Jun 20, 2010 at 8:59 AM

Ah, thanks for the correction. I looked at the game state sample a looooong time ago and must have misremembered it.

Still, a stack of screens doesn't make sense either. I've never worked on a game where screens ended up working well on a stack. You always end up transitioning in a way that is orthogonal to the stacks layout in the edge cases. It seems like the right approach initially, but it's not in the end.

With Ox, I would use the GameScript subclass that comes with a new project to handle requests to intelligently transition from one screen / scene to another. If there's extra logic when going from one screen to another, the transition should be smart enough to detect it and dispatch to that logic. Being patterned after the 'Mediator' design, this is one of the things the GameScript subclass is meant to do.

Jun 20, 2010 at 8:59 PM

The ScreenManager could be rewritten to handle the screens in a manner other than a stack. The main things I like about the sample are the isolation of screen logic into the individual screens, as well as the ease of one screen to transition to another, either directly or through a middle-man loading screen.

I'm going to play with screen management in Ox more tonight, using the advice both of you have given. I'm not quite sure how the GameScript class will serve as a screen manager, but I'll try it out. Any suggestions on that?

Thanks again.

Coordinator
Jun 20, 2010 at 11:18 PM

Create a Screen component derived from OxComponent in which to isolate general screen logic.

Expose the Screen component via a ScreenToken class derived from ComponentToken to the GeneralEditor via Ox.xml.

For individual screen logic, write up a script for each individual screen, create a Screen component in the GeneralEditor for each screen, then set the ScriptClass property appropriately for each Screen component.

As before, use the GameScript subclass to intelligently mediate the transitions among Screen objects, as well as load up the GeneralDocument containing the screen components at the start of the game.

I did all this in a game I was working on before and it turned out well. I didn't want to reveal my technique because I didn't realize how general the approach was at the time. I regret that.

cheers!

Jun 21, 2010 at 12:46 PM
Edited Jun 21, 2010 at 8:17 PM

Hi guys, Sorry for the delay, I got carried away with a separate project :D

But as promised I have now uploaded a sample integrating the XNA Game State Management Sample with Ox.

It may not be the best way of doing things, so please try it out and let me know. If you have any questions, feel free to ask, I'll try my best to help,

but just warning you, I'm no guru! ;D

I've uploaded the sample in both .zip and .rar formats.

You can download the sample from http://cid-92ecd911abc41e66.skydrive.live.com/redir.aspx?resid=92ECD911ABC41E66!116&Bpub=SDX.Docs&Bsrc=GetSharingLink.

In the code, look for regions marked SCREEN MANAGER and OX GAME ENGINE.

Those are the locations where code was changed. I hope this helps!

bryanedds, great work with the engine! I am looking forward to your next release! I've worked with a few engines now, Torque, Unreal, OGRE, Irrlicht to name a few, but although the learning curve is quite steep with Ox, I've never had so much fun using an engine as I have with yours! It has enabled me to quickly prototype my game project, and move directly to working on the demo with virtually no hassle! Not to mention the relative ease of extending the engine! Definately the best open-source C# engine I've come across!

Keep up the good work mate!

Best Regards!

==== edited for formatting ====

Coordinator
Jun 21, 2010 at 4:43 PM
Edited Jun 21, 2010 at 4:52 PM

Thank you posting it up, inslayn!

However, I must discourage other people from doing things that way and instead encourage them to do things how I recommended above.

Taking the *non-recommended* approach is not your fault. The real issue is that Ox is overly hard to learn because it lacks much necessary documentation. I've been trying to find time to work on the big swath of documentation needed, but I always get forced on something else because real life hates me :(

cheers nonetheless!

Jun 21, 2010 at 8:03 PM

hi bryanedds,

I will have a go at your reccomended method, see if I cant get it working.

If I can, I will post up another sample, and maybe a small tutorial.

Also, I *may* have a bit of free time opening up in my schedule soon, so maybe I

can help you out with the documentation.  What exactly is needed?

cheers for your feedback!

Coordinator
Jun 22, 2010 at 3:50 AM

I think the best thing would be for you to figure out how to implement the above recommendation, then document the implementation steps so others can follow along. I'll help out with proofing and answering any questions you have along the way. If it turns out the solution is fully generalizable, I might be able to make some engine enhancements to make implementing the above recommendation easier.

Be great if we could get this done!

cheers!

Jul 1, 2010 at 11:45 PM

I did some game state work with trees a while back. The idea is derived from this paper, although the paper goes into a whole engine design structure which is rather weak. Best to just take the game state bits.

It's essentially the graph of a state machine limited to an n-ary tree, with a restriction on movement: you can make a transition down the tree one level at a time, but you can make a transition upward as many times as you want. The idea is that you treat states as general concepts, and each level of children a refinement of the previous state.

For example:

State example

 

The black lines are transitions down the tree. If there is a black line going from one state to another, you can transition along that path only once at a time. So from the Main Menu state, I can transition to an in-game level. Then from there, I can open the inventory screen. Then I can view some details of an item in my inventory. The restriction imposes the concept of refinement: it makes no sense to transition from the main menu to an inventory screen, as the inventory screen cannot exist without the prerequisites provided by the Level state.

The green lines are transitions upward. From any given state, you can follow the green lines as far as you like. Consider a contrived yet simple example: in order to reach level 2, I must open my inventory screen and combine two items to get a third item. In this scenario, it makes sense to jump from the Item Details state to the next level. However, it does not make sense to jump straight into the inventory screen of the next level.

Another example might be, if I'm in the Inventory state, I drop an item and it causes dialog with a party member who is complaining about me dropping an item. This transition makes sense, but it does not make sense to transition directly into a cutscene that would normally be the result of the player talking to said party member.

Lastly, another important facet is the concept of temporary and permanent transitions. A permanent state transition is something like loading a new level. It causes an unwinding of all the current states, allowing them to free resources before the new state is entered. A temporary transition is a local transition to something else in the state tree. This is great for things like inventory screens or the main menu. If you are playing through a level, opening the inventory screen obviously does not destroy the game world. You can also open the main menu to pause the game, change preferences, etc.

I implemented this in a project I never completed. I abandoned it for a stack, probably because I thought a stack would work just as well. Looking back, I think I just implemented it incorrectly. First of all, I don't think the movement of one state down at a time is a good restriction. It makes sense to open the inventory screen and immediately jump to an item. The tree does provide a good structure for transitions. If I say, "I want to view the item details for FOO," the state manager can automatically invoke the inventory state because it knows the item detail state can't exist without it. Presumably, states are often passed messages during a transition. I'm unsure of the implementation details but you could work something out to let you jump from one state to any other state, traversing the tree in the correct manner.

If I were to reimplement this now (and I might!) I would implement it as a stack of stacks. The tree would be conceptual, not a data structure used for managing state. Well, not exactly. State classes could reference their parents with attributes or something. The state manager could then use this to infer how to walk the "tree" in order to get to the desired state.

Phew, long post... any of that make sense?

Coordinator
Jul 2, 2010 at 12:27 AM
Edited Jul 2, 2010 at 12:27 AM

olenikm,

It's hard to describe all that is troubling about that paper.

I'll simply suggest taking a different approach. Hack up a piece of transition functionality with the simplest code that you can. Then refactor that code to be as clean as possible. Then hack in more transition functionality as simply as you can. Then refactor the system again. Hack. Refactor. Hack. Refactor... and so on.

After doing several iterations of this (and perhaps extra refactoring at the end to get it into its overall simplest form), the proper design will have emerged. I can't say what it will look like (no one can, that being the point of this process), but I am almost certain it won't look like what's in that white paper.

cheers!

Jul 2, 2010 at 12:30 AM

I agree, and that's exactly what I did! Explained above is not what's in the paper, but something that came about of my own refactoring. The only thing I took from the rest of the paper is the hierarchy of states, the rest about building the engine around that design is rubbish (maybe its good for a Flash game).

Jul 27, 2010 at 5:34 AM


bryanedds wrote:

Create a Screen component derived from OxComponent in which to isolate general screen logic.

Expose the Screen component via a ScreenToken class derived from ComponentToken to the GeneralEditor via Ox.xml.

For individual screen logic, write up a script for each individual screen, create a Screen component in the GeneralEditor for each screen, then set the ScriptClass property appropriately for each Screen component.

As before, use the GameScript subclass to intelligently mediate the transitions among Screen objects, as well as load up the GeneralDocument containing the screen components at the start of the game.

I did all this in a game I was working on before and it turned out well. I didn't want to reveal my technique because I didn't realize how general the approach was at the time. I regret that.

cheers!

I'm not exactly sure how to implement the "Expose the Screen component via a ScreenToken class derived from ComponentToken to the GeneralEditor via Ox.xml".

I created the screentoken class but how do I update the Ox.xml file?

Jul 27, 2010 at 9:56 PM
Create a new code block in the Ox.xml file similar to the one below: <ConstructionToken> <FileName>Ox.Engine.dll</FileName> <========= Change this to the name of the dll your new class resides in <TypeName>Ox.Engine.Component.TransformableComponentToken</TypeName> <================= Change this to the full class declaration of the token class you created </ConstructionToken> example: <ConstructionToken> <FileName>Ox.MyGameEngine.dll</FileName> <TypeName>Ox.MyGameEngine.MyComponent.ScreenComponentToken</TypeName> </ConstructionToken> please correct me if I'm wrong, i hope this helps you! Regards.
Jul 27, 2010 at 10:02 PM
sorry, formatting doesn't seem to be working in my browser, i will try to edit the post again.
Jul 28, 2010 at 2:32 AM
  example: <ConstructionToken> <FileName>Ox.MyGameEngine.dll</FileName> <TypeName>Ox.MyGameEngine.MyComponent.ScreenComponentToken</TypeName> </ConstructionToken> please correct me if I'm wrong, i hope this helps you! Regards.

 

Sorry to sound like a n00b about this. Let's use an example called ShipGame. ShipGame is the name of the solution/project/namespace. where/what is the DLL file that I Would put intot he filename attribute? also, I don't need to prefix my project name with Ox.* right?

Again, these may be dumb questions but I want to make sure I have this right.

Jul 29, 2010 at 4:54 AM
Edited Aug 1, 2010 at 6:47 PM
jschell12 wrote:
  example: <ConstructionToken> <FileName>Ox.MyGameEngine.dll</FileName> <TypeName>Ox.MyGameEngine.MyComponent.ScreenComponentToken</TypeName> </ConstructionToken> please correct me if I'm wrong, i hope this helps you! Regards.

 

Sorry to sound like a n00b about this. Let's use an example called ShipGame. ShipGame is the name of the solution/project/namespace. where/what is the DLL file that I Would put intot he filename attribute? also, I don't need to prefix my project name with Ox.* right?

Again, these may be dumb questions but I want to make sure I have this right.

Don't worry about it. A wise man has many questions wheras a fool has few.

First off, am I right in assuming your dealing with the source? I assume you've implemented your ScreenToken class as subclass of OxComponent.

If so, then you would set up the ox.xml code block as follows:

<ConstructionToken>

      <FileName>Ox.Engine.dll</FileName>  //this is the default engine, if you haven't created your own subclass of OxEngine.

      <TypeName>ShipGame.ScreenToken</TypeName>   //this parameter is the fully qualified name of your screen token class, that is, the full namespace and class name.

</ConstructionToken>

You don't have to prefix your project name with Ox.*, it was set up like that in my previous post because that was the namespace.

so if your class is set up like this:

namespace ShipGame.Screen.Component
{
    /// <summary>
    /// A serializable token for a screen.
    /// </summary>
    public class ScreenToken : ComponentToken
    {
        /// <summary>
        /// Create a ScreenToken.
        /// </summary>
        public ScreenToken()
        {
            screenName = new ProxyProperty<string>(this, "ScreenName", "");
        }


        /// <inheritdoc />
        [XmlIgnore, Browsable(false)]
        public new Screen Instance
        {
            get { return OxHelper.Cast<Screen>(base.Instance); }
            set { base.Instance = value; }
        }


        [DefaultValue("")]
        public string ScreenName
        {
            get { return screenName.Value; }
            set { screenName.Value = value; }
        }

        protected override OxComponent CreateInstanceHook(OxEngine engine, string domainName, bool ownedByDomain)
        {
            return new Screen(engine, domainName, ownedByDomain);
        }

        private readonly ProxyProperty<string> screenName;
    }
}

the TypeName property would be set to: ShipGame.Screen.Component.ScreenToken

If you haven't created your own subclass of OxEngine, similar to the DefaultEngine project with DefaultEngine.cs,

then the FileName property can be left as: Ox.Engine.dll

If you have created your own subclass of OxEngine, then the FileName property should be set to the name of the

DLL created when your custom engine subclass is built, for example: CustomEngine.dll, DefaultEngine.dll, ShipGame.dll or whatever.

I hope this helps!  If I've made any mistakes, please point them out!

Best Regards mate.

Jul 30, 2010 at 12:48 AM
Hey I appreciate the reply inslayn. Once my laptop stops doing chkdsk I'll test this out.
Jul 30, 2010 at 1:26 AM
Hey inslayn, The ProxyProperty constructor takes a ProxyPopertyToken and not an OxComponentToken as implied by this. Also the base class does not contain a method called Instance. Are you working with an older version of Ox or perhaps newer source code?
Jul 31, 2010 at 3:34 PM

You know what... I don't think there is an OxComponentToken, just ComponentToken. am I right Bryan? I looked through your source and couldn't find it.

Jul 31, 2010 at 4:03 PM

Also, am I to add the ConstructToken inside the "GeneralConstructionTokens" element? If any of these question are found in the documentation you can just give me a reference instead. I'm looking through it now.

Aug 1, 2010 at 6:46 PM

Sorry for the late reply, my main laptops graphics card is fried :(

had to go get a new one.

anyway, you are right its just ComponentToken...my bad

Aug 1, 2010 at 6:48 PM

thats fine. To tone down the amount of questions I'm reading through the source. Hope you bought a better new card!