Partial Class State Machine

You’ve probably been told before not to re-invent the wheel, but when it comes to my own code I couldn’t disagree more. I love re-inventing the wheel because it helps you understand why things are designed the way they are, and occasionally allows you to make something better. I’m currently “thinking out loud” about a whole new approach to the way I implement state machines that can provide functionality I had been wanting but not thought was possible – until now.

The Problem

You can see State Machine’s used in a lot of my code. In particular I make use of them in the Tactics RPG and Tic Tac Toe projects. The StateMachine and the State scripts are all MonoBehaviour subclasses which allows me to use things like GetComponent and AddComponent to make getting and changing state nice and easy. In addition, I could use MonoBehaviour abilities like Coroutines, or the ability to grab other components attached to the same GameObject. I felt like I had a whole host of beneficial and powerful features with my original architecture. Still, I always felt like something was missing, or just not right. Perhaps it just wasn’t as good as it could be.

My primary complaint was that the whole architecture was based on “has a” rather than “is a”, and what I mean by this is that my object, say a “Game Controller”, has a “State Machine”, and it has several “State” components. So for example, when it comes time to perform “setup” on the “Game Controller” then I could create a special state for this task. However, the “Setup State” is its own object instantiated from its own class. It needs to know about its owner, but can only see what the owner exposes in the interface. In order to expose something to the state, it would also become exposed to everything else. Wouldn’t it be nice if the setup state could somehow have special privileges or permissions to see private fields or access private methods on the owner which other classes could not see?

Even when a state only needs access to things which are already public, I still have to refer to them in the sense of the owner. For example, if a state refers to the Game Controller’s hero, it might need to use something like “owner.hero” instead of just “hero”. This would either end up making all of the code a little longer, or would require patterns such as convience wrappers. I often used the later approach and would make a common base class that my other states would inherit from. This class would automatically cache the owner, and use properties to wrap the owner’s fields and properties as if it were its own.

Both of my primary complaints would be solved if I could think of the state as an “is a” instead of a “has a”. This would mean that the “state” ought to be able to act as if it was actually the “owner”. This would give me direct access to all fields, properties, and methods, etc, regardless of if they were public or private. This was a big challenge though because I had to keep several things in mind:

  • I still want to keep the “state as an object” pattern, so I can determine when state changes and act on it. If the owner is the state, there is no object change when a state changes.
  • There are no C++ style “friends” in C#. The only way to access something private is to be the class itself or to be defined inside the class, such as an embedded class. This option wouldn’t be compatible with a Monobehaviour.
  • I still need a common interface so that the state machine can act at a lower abstract level. I just want “Enter” and “Exit” methods.
  • I can use extensions on a class, but can only use methods, and can’t add new fields which might be needed to properly maintain the state. I also can’t keep re-defining the same method names needed by the state machine interface for multiple different states.

The Solution

I decided that I could “inject” the functionality I wanted. By making a state a simple container for “action” methods, I could still have separate objects for each state. I could maintain a common abstract enterface with “Enter” and “Exit” calls. I could even, in a way, allow a state to act as the owner itself and have full access to everything, even all private details (really it is the delegate that had access). I took it a step further, and made the owner a partial class, with separate definitions for each state in its own file. Because of this, I can also maintain clean and simple code where all of the logic unique to a state was organized nicely on its own.

Want to see what this looks all like with actual code? Glad you asked!

State

using UnityEngine;
using System;
using System.Collections;

public class State
{
	#region Fields
	public Action Enter;
	public Action Exit;
	#endregion

	#region Factory Methods
	public static State Empty ()
	{
		return new State(DoNothing, DoNothing);
	}

	public static State EnterOnly (Action enter)
	{
		return new State(enter, DoNothing);
	}

	public static State ExitOnly (Action exit)
	{
		return new State(DoNothing, exit);
	}
	#endregion

	#region Constructor
	public State (Action enter, Action exit)
	{
		Enter = enter;
		Exit = exit;
	}
	#endregion

	#region Private
	static void DoNothing ()
	{
		
	}
	#endregion
}

Here’s the State class. See how it isn’t an abstract base class? With this new architecture, I don’t expect to actually create subclasses of State, but will probably always use them as simple “dumb” containers. The only expected purpose of the object is to hold the references to the two “Action” delegates, “Enter” and “Exit”.

I created a few convenience Factory Methods just in case you wanted a state that didn’t implement one or both of the actions. The constructor expects both actions – neither action should ever be “null”. I also created a static method called DoNothing, that (surprise) doesn’t do anything. This will be the default method for any state that doesn’t need to be fully implemented.

State Machine

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

[Serializable]
public class StateMachine
{
	string current = string.Empty;
	Dictionary<string, State> states = new Dictionary<string, State>();

	public State CurrentState
	{
		get
		{
			return states.ContainsKey(current) ? states[current] : null;
		}
	}

	public void Register (string key, State state)
	{
		if (!string.IsNullOrEmpty(key) && state != null)
			states[key] = state;
	}

	public void Unregister (string key)
	{
		if (string.Equals(key, current))
			ChangeState(string.Empty);
		
		if (states.ContainsKey(key))
			states.Remove(key);
	}

	public void Clear ()
	{
		ChangeState(string.Empty);
		states.Clear();
	}

	public void ChangeState (string key)
	{
		if (string.Equals(key, current) || key == null)
			return;

		if (states.ContainsKey(current))
			states[current].Exit();

		current = key;

		if (states.ContainsKey(current))
			states[current].Enter();
	}
}

I also decided not to make the state machine a subclass of MonoBehaviour. I don’t actually “need” to, because functionality you would need can be injected directly into the state. Note that I also tagged this class as Serializable even though I have no serialized or public fields. If you look at the upper right corner of the Inspector pane, just to the right of the lock icon, is a hamburger looking menu button. You can use this to switch between “Normal” and “Debug” modes, but while in Debug, you will actually be able to see the private fields of your objects. Any Monobehaviour which has a state machine (even a private one) would then appear in the inspector, and you would be able to read the name of the current state field as well.

Since I am not using MonoBehaviour based states, I need something to be able to maintain all of the state references so I can easily switch back and forth between them. I decided to use a Dictionary for this which maps from a string “key” to an instance of a State “value”. The dictionary is also private so you will be required to use the “Register” and “Unregister” methods which provides me a chance for a little error handling. If you need to clean up, you can use a simple “Clear” method to remove all states from the machine. Note that when I unregister or clear, it will first “Exit” the current state if applicable.

The ChangeState method will be used the most. It expects a “key” to know which state to transition to. This also means you must have already registered the state by that key. The method checks to make sure that you aren’t attempting to change to the current state, and will exit early in that condition. It also checks to make sure you don’t pass a “null” value for the key, becuase that isn’t compatible with the dictionary. When transitioning from one state to another, I always give the original state the opportunity to “Exit” before allowing the new state the opportunity to “Enter”.

Demo Consumer

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public partial class BattleController : MonoBehaviour 
{
	#region Fields
	StateMachine _stateMachine = new StateMachine();
	int _aNumber;
	bool _aBool;
	#endregion

	#region MonoBehaviour
	void Awake ()
	{
		RegisterStates();
		_stateMachine.ChangeState(ActiveState);
	}

	void OnDestroy ()
	{
		_stateMachine.Clear();
	}
	#endregion

	#region Private
	void RegisterStates ()
	{
		_stateMachine.Register(ActiveState, new State(ActiveStateEnter, ActiveStateExit));
		_stateMachine.Register(PassiveState, new State(PassiveStateEnter, PassiveStateExit));
	}
	#endregion
}

Here is the first part of a class which consumes our State Machine code. It is a MonoBehaviour but is defined as a partial class – this still works, you just have to make sure that when you connect a script to an object that the name of the file matches the name of the class.

This demo doesn’t actually do anything, it simply demonstrates how to create a few states which can see and directly act on the members of the owner. All of the fields are left implicitly private to help re-iterate the flexibility of this approach.

In the “Awake” method, I register all of the potential states that my implementation could need, and then change state to one of them. In the “Destroy” method, I clear all the states, which isn’t strictly necessary, but I like to clean up after myself.

The RegisterStates method references strings and methods which aren’t defined anywhere you can see yet. Don’t forget that the class is defined as “partial” – you will see them in another file.

using UnityEngine;
using System.Collections;

public partial class BattleController : MonoBehaviour 
{
	public const string ActiveState = "Active";

	void ActiveStateEnter ()
	{
		_aNumber++;
		_stateMachine.ChangeState(PassiveState);
	}

	void ActiveStateExit ()
	{
		if (_aNumber >= 10)
			_aNumber = 0;
	}
}

This code exists in another file named “BattleControllerActive.cs” even though the name of the class is still “BattleController”. Don’t forget that you must include the “partial” keyword in the definition of this class or the compiler will complain at you. Note that you can’t add this file to GameObjects in the Unity Editor, but any fields you define here can still be visible in the inspector as part of the BattleController component.

Within the same class (even a partial class) I can’t redefine a method with a same name as another method. This means I can’t have two “Enter” methods, but I can use a sort of naming convention like I did here. I am treating this partial class as if it were a state called “ActiveState” so I use that as a prefix on the “Enter” and “Exit” methods I actually wanted.

Inside of these methods I “work” with the private properties defined in the original partial class file, even though I am not really doing anything useful. It is just placeholder code to show that I can do stuff. Cool huh?

using UnityEngine;
using System.Collections;

public partial class BattleController : MonoBehaviour 
{
	public const string PassiveState = "Passive";

	void PassiveStateEnter ()
	{
		_aBool = true;
	}

	void PassiveStateExit ()
	{
		_aBool = false;
	}
}

Like before, this code exists in yet another file named “BattleControllerPassive.cs” even though the name of the class is still “BattleController”. I use the same sort of naming convention as I did in the “ActiveState” version, and I modify one of the other private fields just for fun.

Summary

In this lesson I “thought out loud” about some new architecture I intend to add to my future projects as a replacement for my old State Machine code. With the new architecture, states no longer need a reference to their owner, because they act using code injected from the owner itself. This allows direct access to anything and everything, without needing to also expose access to any other classes.

Note that I haven’t battle tested my ideas yet, so I don’t actually know how much I do or don’t like it. At the moment I feel like I will love it, but until I try working with it in a “real” project (or three) it can be hard to tell the full scope of the pros and cons of the new approach. As always, I’d love to hear your thoughts, so drop a comment below!

22 thoughts on “Partial Class State Machine

  1. Interesting read! Are you planning on trying this out in the card game tutorial you have been thinking about?

  2. I was finally able to find some time to go and rip out the old state system and put in the new one in the game I am making- it took all of 30 minutes, if that. Now to make a brand new state. So far I am liking it. 🙂

    1. A state is an object with references to methods as its data. You can pass a reference to any method in its constructor – this could be anything including an instance method on a different object which could even be private, or it could be a static method on a class.

      I provided convenience factory methods that create states and auto pass a reference to a static method of its own called “DoNothing” for use in the event that you don’t care what happens at a particular moment of a state transition. For example, maybe you need something to happen on entering a state, but don’t need to revert anything when exiting the same state.

      You can see the “Do Nothing” method inside of the State class – it has an empty body so it literally doesn’t do anything. It is also a static method, which means no instances of an object need to exist in order to reference it.

      1. I was just confused about passing the DoNothing method as an Action in the constructors but I looked up the documentation for Action on msdn and it makes sense now. Very cool, I would have used delegates but this cleans things up much better.

  3. Hm, I don’t quite get how this creates actual statefulness. The Enter and Exit define stuff that happens when you enter and exit the state, but what about in between? How do we enable or constrain what you can do WHILE a state is active?

    For instance, if I want to enable the player to control some actor in one state, and deactivate controls altogether in another, how would you do that? You mention that you cannot have methods with the same names in the partial classes, so how do you create different functionality for Update() (where the controls are usually handled) in different states?

    Sorry if I’m misunderstanding altogether, I still only barely understand state machines as a concept.

    Also, as far as I can tell, this approach seems to require some additional boilerplate code to be written, compared to the one used in Tactics RPG: You need to register all possible states manually, rather than having them simply ‘exist’. All states need a string name, but isn’t actually required by contract or such in any interface. Not the end of the world or anything, but string matching, even when they’re consts, does pet peeve me out. On the other hand, you do get rid of the need to have both a superstate and a controller, so that’s one less class.

    1. Great questions, here goes…

      In my own personal experience, when using state machines with Unity I primarily only use “enter” and “exit” methods (“update” can be used directly from any MonoBehaviour or coroutine as needed), and I use those as opportunities to modify traits of other entities and not the state itself. For example, I might have a state for a boss that determines what moves it will use, or a state for a menu that determines what buttons to display. When those states have their “enter” method invoked, then they will update the target entity accordingly. If you need the state itself to store information you can still do this by creating a subclass of “State” and add whatever fields you wish. But here again, I almost always would have only added fields to store the values I would want to apply on something else anyway. By injecting the enter method, all of the fields to change can be the fields on the entity itself – no need to duplicate them in a separate state object. Whatever values you assign in the implemented method are “captured” without even needing extra fields.

      Imagine you have a Game controller, which holds a state machine for Play, Pause, etc. When I change states to the play state, I might use the “enter” method to find a “player input” component and enable it. Likewise, when we “exit” the state we might disable the “player input” component so that it wont function in any other game state such as pause or game-over, etc. The player input component would have handled its own update loop while the component was enabled, so there was no need for the state machine to manage it.

      Regarding the additional code – yes, you do need to register the states, but this allows the states not to need to be a monobehaviour subclass. This feature by itself is appealing for a variety of reasons, like less overhead, portability, the ability to share and reuse states, etc.

      Regarding the string for each state, you can think of this as a unique id. It is required, because the string is the key which you pass to the state machine to change states. It allows you to provide your own identifiers for any state, which could allow you to have multiple states in a state machine that share the same class. Also keep in mind that we are not “matching” strings in the sense of slow string comparison checks. The dictionary creates a hash of the string and looks up values using that value. This is significantly more performant than GetComponent as well. Furthermore, if you do create const values for your keys then you also have compile time checking, code completion hints, etc – all the features you would hope for.

      If I missed anything or you need additional clarification, just ask.

      1. Ah, thanks, that clarifies a lot. I might have picked a bad example though, being quite simple & binary. Turning the component off/on works in that example, but I wonder about a more complex case.

        Namely, I’m trying to imagine the example in the game programming patterns book with the partial class state machine:
        http://gameprogrammingpatterns.com/state.html#the-state-pattern
        His implementation of the state machine seems to basically be the same as the one you use Tactics RPG (I guess it’s the standard way?): State as seperate classes with a superclass and an owner. Here, controls are different in complex ways for each state, which is handled inside the state themselves. In Unity, one would have this code in a seperate Update() for each state. Is this still possible to do with the partial class state machine? Or would you say that it’s just as practical to do this by modifying fields and the like during “enter”?

        1. Yep, both the state machine in that article and the one used in my Tactics RPG are a pretty standard implementation of a State Machine. However, those patterns were designed for C++ and now we have some nice new features with C# so I re-imagined the approach using modern techniques. It is definitely possible to do separate updates per state using this pattern. It might look something like the following:

          1. Add an additional “Action” field to the “State” class called “Update”.
          2. Optionally add additional convenience factory methods which allow you to pass an update method
          3. Add an “Update” method to the “StateMachine” class. This method should then call “Update” on its current state (assuming it has one, and assuming the state has an update method)
          4. Whatever it is that requires the StateMachine with an Update method, needs to invoke it. For example, if you have an Enemy script which is a MonoBehavior, then you can use the Update method from there to call StateMachine.Update()

          Now you can implement it – suppose you had a JumpState, then you might add a JumpStateUpdate method which you pass to the constructor.

  4. Cool, thanks, that makes sense. And I would figure you could use the same procedure for any other in-built Unity function (though I suppose the cases where you’d need to do something for instance in Awake() that you could not do in Enter() or the “base” class Awake() are few and far between).

    I honestly still have thoughts, quibbles and questions but as this point, I really just need to try it out for myself and experiment with it.

    Thanks for the answers and thanks for a great blog! It’s benefiting not just my Unity programming, but my skills and mindset as a programmer in general. Keep it up!

  5. I was directed here by a previous coworker of yours. I fail to grasp all the benefits of this system, still it has been a huge help to me, thank you for sharing your work!

    1. Welcome. May I ask who the the coworker is?
      I’m glad the code has helped you. I’m not sure how many different implementations of state machines you have worked with, but I tend to recreate them a lot and see pros and cons in every approach. My favorite features of this variation is that the state IS the instance of whatever it is supposed to be a state OF. What this means is that I can allow a state to have access to all of the internal private code of the target object without needing to expose anything in a way that could be abused by other objects – its sort of like a C++ Friend.

  6. I ran into this exact design problem on my game project. I want to create nested state machines for a battle field controller but wanted to avoid either
    1. Making all my battle field state public for the states to access
    2. Wrapping up all my battle field state into a context to pass to states

    So partial classes seemed appealing on the surface and that’s how I landed here.

    One thing I don’t like about this approach is that there isn’t an interface or abstract base state with Enter/Exit methods. The requirement to register the state methods is a bit of an unfortunate trade off.

    I’m not sure whether I like this approach, a context to keep things private to states, or just f*** it and make all the controller state public. I am a solo dev after all…

    Anyway, you saved me some time on figuring out how the partials can be used for this so thanks for the post

    1. Haha, definitely sounds like we struggle with the same issues. Glad to help, best wishes regardless of the solution you go with.

  7. Do you think this implementation would be compatible with a State Chart (i.e. each state can have sub-states, making every State a StateMachine unto itself)? I’m also curious if you have any solution to transition tables, the oft-neglected part of StateMachine tutorials and resources.

    1. Good questions, to be honest, I had not heard of state charts or transition tables before now, and I am not sure if I will be using the same definitions as you. If you have links related to either topic that you feel might help, feel free to share.

      If all you mean by State Chart is that a state can have sub-states, then yes, I see no reason why you could not accomplish that using this pattern.

      What I saw for transition tables mentioned having different inputs and outputs based on state transition. The pattern here does not take input or output, especially as part of a transition. Rather, it can “do” anything in the enter or exit of a transition.

      1. https://statecharts.dev. Do you think having to grab State.Substate.Enter/Exit, or State.Substate.Substate.Substate etc., would be too tedious to be useful? A StateChart I’ve heard is great for design complex UIs.

        As for transition tables, I think a great example is Unity’s animation StateMachine. A State node can have a transition line pointing towards another State node. That transition will have conditions like “if JumpHeight > 5” or “Flying != True.” If those parameters change, it checks if the condition is met, and will automatically change the State.

        It’s a way of organizing *when* to enter a specific state based on parameters, rather than sprinkling “EnterState(Sleeping)” and “EnterState(Eating)” throughout your code. Maybe like a list of predicates? Again its difficult to describe because its not talked about.

        1. Thanks for sharing. I read the article and it looks interesting. I am not sure to what level you want to try taking it, such as even making your state chart in JSON or something that then is built into a code equivalent. For me though, the way I use state machines may be different than what you are used to, and I am not sure how I would integrate that kind of thing. For example, I could see an example where a State checks its own substate, but I would seriously question any code that needed to check as deeply as State.Substate.Substate.Substate. I would be looking for examples that were a little more focused on polymorphism and could be a little more disconnected.

          For example, suppose I want my state machine to react to user input. At most, I might have a system that observes my input controller and then passes that input event on to the statemachine’s current state. Alternatively, I might even have the state be responsible for registering for its own notifications of input. That’s it. If the statemachine’s current state doesn’t actually care about the input, then it is up to that state to ignore it. If the current state does care about the input, then it should handle it. If the current state has a sub statemachine, then the state could pass the input event to the sub statemachine’s current state (and the pattern can continue as needed).

          To take the example further, I could have a parent state that says it is a particular player’s turn. The state could then have a sub state machine that changes state based on interactions, such as the user clicks a card to play, then a target to play it on. Once an actionable turn has been recognized, the substate machine could enter a complete state, and the parent state could pass on the result as needed.

          Regarding the state transitions, Unity’s animation StateMachine is pretty powerful, and you could possibly use it for more than just animation if you wanted a transition table like you are mentioning. For my own patterns, I find it fairly easy to keep transition logic in the state itself, or within other systems where it makes sense. I can see the argument that if it isn’t in a consistent location that it could be harder to maintain, but so far, I have felt like my implementations are intuitive. The effort necessary to centralize the transition code to a single location could actually make it harder to implement, though if you find some examples you really like, I would be curious to see them.

          If it helps, you can see real example usage of state machines in my projects such as the Tactics RPG.

Leave a Reply

Your email address will not be published. Required fields are marked *