This is going to be a multi-parter, simply to allow for some organizing and avoid the giant scrolling page.
State as language syntax
One thing I’ve always liked about UnrealScript was its inclusion of states as a first class citizen in the language. It’s something that just made sense for the problem that UnrealScript tries to solve. After doing some Unreal modding, I thought about building a game scripting language of my own and contacted Tim Sweeney for his advice. I don’t know if he just didn’t get as much mail as he does now, or if he is just one of the incredibly helpful guys in the industry, but he got back to me in a day and gave me some good advice on language design and generally told me to bone up on the Java Virtual Machine design docs — which is where he got a lot of his ideas for UnrealScript.
While fun, that project didn’t get very far, but I still keep coming back to first-class stateful programming from time to time. Now that XNA is out seems like the perfect time to revisit this, because writing your game logic in .NET would almost certainly benefit from the approach of UnrealScript.
There are three paths of approach to this problem that I think are all viable:
- Implement an UnrealScript compiler for .NET
- This would be a cool project and could be something to try to get Epic to pick up and have them embedd .NET/mono into Unreal. It would provides their clients with more programatic flexibility (i.e. more languages), a richer framework and might even add a good bit of performance (not sure how optimized the UnrealScript VM is by now). It’s basically what SecondLife is up to.. Of course LSL was always a scripting language, and UnrealScript has been a bytecode compiled language from the start, so the comparison might be flawed.
- Create a C# derivative that implements new state keywords
- This is my fav, just because I prefer to have the C# as my foundation. While UnrealScript is probably one of the nicest game scripting languages for gaming, its syntax is still a bit strange to me at times — like
statekeywords and the lack of static methods. But it would be a major undertaking, so it’s likely to be the ultimate, not initial, approach.
- See what can be done in C# to create a stateful object framework
- This is the path I’ve chosen for now, because it let me prototype the whole thing in a day, which is always nice. If that turns out to be useful, the prior approach can always be adopted from this work.
Design of a stateful C# framework
So what are my design goals for this stateful C# framework?
- Different logic paths per state on state aware methods
- Really the definition of state aware objects. If the state of my
Idlea different code path for
Hit()should be called than if the
Botwas in state
- State specific methods should be inherited
- Extend regular inheritance to per state logic path inheritance. I.e. a subclass should be able to override the existing default and state specific methods, as well as create state specific methods, where the base class was just using the default.
- Default and state specific methods
- A method that is declared as state aware should always have a default implementation, so that identical behaviors don’t all create duplicate code or simple stubs that just point to common implementations.
- Type-safe states
- I always prefer strongly-type definitions, so enum’s seem like the ideal way to express states. The biggest drawback is lack of inheritance in enums. If we used one enum for all states of all objects the state names would quickly become meaningless. So the design must allow for per class enumeration of states and the framework should not have a preconceived idea of the possible states.
- Serializable state-aware objects
- If our objects store state, we should be able to fully serialize them, including their state, so we can take a snapshot of our action at any point in time.
See State-aware programming in C#, part II for the syntax that implements this design.