Thursday, June 16, 2011

Foray into Photon - Part 6 Strategy/State Pattern

So far I've really only been covering the code and how to build up to where the demo is. I'm going to take a step back to my original post and discuss a few things on why they were done.

As I stated toward the end of my post on SmartFoxServer, there are a few patterns or philosophies I try to adhere to. One of them is to keep only what a class needs to do in the class that does it. The folks at Exit Games follow this same philosophy. They have an Operator class which only contains the data that operations need. The same holds for Events. The only place you will find a send is in the PhotonPeer and the only place you get events is in the PhotonPeerListener.

Would you be able to agree with me if I told you that we want to do the same with how we handle messages? I hope so. In the demo on the client portion you will find a series of classes in the GameStateStrategies. They all base themselves off of the IGameLogicStrategy. This class follows the Design Patterns called State and Strategy. If you are serious into programming and want to make headway into being a better programmer I would recommend you pick up Design Patterns: Elements of Reusable Object-Oriented Software. This book shows you 23 design patterns you will frequently find in programming and one of these is the Strategy pattern.

The book defines the state pattern like this: "Allow an object to alter its behavior when its internal state changes. The object will appear to change its class." Lets take a look at it in terms of how Exit Games used it. The object that appears to change its class is the Game.cs class. You have several behaviors that all do the same thing: Disconnected, WaitingForConnect, Connected, and WorldEntered. It appears to change its class because based on which state its in, is how the game reacts when it gets an operation response or an event, checks its status in the call back, or sends an operation. In disconnected or waiting for connect it doesn't send operations, and it reports errors when it receives events and operationresponses. But connected is able to listen for a few things like when the world is entered and the worldEntered state is there for when they are totally in the game.

So lets think about our what we did in our SmartFoxServer program. We would have several states. Disconnected for when they haven't clicked login. WaitingForConnect would be used when they have hit the login button but we aren't talking to the server. CharacterSelect would be used when they are at the character select screen. CharacterCreate would be used when they are on the character creation screen. Lastly, WorldEntered would be used when they have selected a character and are fully in the game. Each of these states would handle only specific messages and would report all others as errors. So when you are on world entered you would report an error if you got the operation stating that you are creating a character. Also you couldn't send an operation to perform a craft while waiting for the connection.

Next time we will create a set of classes: IGameState that will contain the same as the IGameLogicStrategy. Then we will set up the barebones for these states and modify our game to use these states.

No comments: