[SmartFox] Room variables
[ April 14, 2005 ] by Marco Lapi, a.k.a Lapo
Article 12: take a closer look to Server Side variables in SmartFoxServer, how they work and why they are useful

[ Introduction ]

In this tutorial we will take a closer look to Server Side variables in SmartFoxServer, how they work and why they are useful. In particular the article is focused on RoomVariables. We have already encountered them in the board game tutorials and they have been usefull to keep custom user data in the room without having to write server side code.

[ Requirements ]

Before proceeding with this tutorial it is necessary that you're already familiar with the basic SmartFoxServer concepts explained in the previous articles.

[ Objectives ]

The example application shows the various features of the Room Variables objects and allow to see them in action.
The interface will show the variables available in each room and you will be able to create new ones, modify and delete them, change their attributes and so on.

[ The setRoomVariables() method ]

As we have already seen in the other articles SmartFoxServer allows data to be stored on the server side using RoomVariables and UserVariables.
The first ones store data at room level and the second ones store data at User level. Each has is own advanatges: for example if you want to keep track of the position of an avatar for each client in the room you can save this property in each User, by using UserVariables.
On the other hand if you want to keep track of the status of a board game, say a battle-ship game, it would be better to keep those values at Room level.
In both cases data saved on the server-side is shared across all other users, so that they are constantly kept in synch as data is updated.

Before we analyze the application I'd like to show you how RoomVariables are created with a client request.

The SmartFoxServer Client API command used is setRoomVariables(varList) where varList is an Array of objects each one representing a
variable with the following properties:

name the name of the server side variable
val the value of the variable
priv a boolean flag, if true the variable is private and it can't be changed by another user except the one who created it
persistent a boolean flag, if true the variables persist until the user who created it disconnects.

As you can see everything sounds pretty simple, just give your variables a name and value and you're ready to use them!

The two boolean flags available need a more in-depth look at how these variables work.
In the most simple case we can set a RoomVariable like this:

var varList:Array = []
var roomVar:Object = {name:"test", value:"Hello world!"}



We first create an empty array that will hold the variables we'd like to create, in this case just one variable.
Then we declare an Object with name and value properties which represents our simple variable and finally we send the request to the server.

By default the variable is going to be created and sent to the other clients in the room. It will be destroyed when its owner will go out of the room where the variable was generated.

Once the variable exist in the room other users may update it as well, and if they do the ownership of the variable is changed to the last user who has modified it. If you want to avoid this behaviour you should set the "priv" flag to true, this way no one will overwrite your server side values.

Setting the "persistent" flag to true will allow your variables to persist throughout the entire user session.

[ Variable types ]

Room Variables support all the "primitive" Actionscript types: Strings, Numbers, Booleans and null.
The null value is used to delete a variable, so if you want to remove one of them you should use a code like this:

var varList:Array = []
var roomVar:Object = {name:"test", value:null}



In this case you will delete the variable called "test". The variable will not be deleted if it's private and you are not its owner.

[ Other ways of creating variables ]

Using the setRoomVariables method is not the only way in which you can create RoomVariables.
There are two other ways to create them:

1) In the config.xml file
2) At the time a new room is created

1) Defining room vars in the config.xml file is useful when you need to create persistent variables at server start.Here's a code example you could use in the config.xml file:

<Room name="Disco Fever" maxUsers="12" isPrivate="false" isTemp="false">
		<Var name="bg" type="n" private="true">5</Var>

This example is taken from our "SmartChat" application. In our chat every room loads a different background image so we decided to define
each background as a RoomVariable. By defining it in the config.xml file the variable is created as soon as the server starts so we don't have to worry about creating them later. Also we wanted to avoid these values to be changed so we set the private flag.

NOTE: all variables created in the config.xml file will be always persistent, since the owner of those variable is the server itself.

You should have also noticed the type="n" attribute. What is it about? Each Room Variable preserves its type to avoid mismatches, so if you send a String you will always get back a String and so on: this is done transparently by the SmartFox Client API and you don't have to take care of it.

In this particular case you will have to tell the server what type are the variables you are setting, by using this convention:

n = Number
s = String
b = Boolean

2) An alternative to the previous method is to declare the room variables when creating a new room

The createRoom method of the SmartFoxClient object accept a rooObj argument where you can define all properties of the room you want to create, variables included.

Here's a code example:

room:Object = new Object()

room.name = "The Cave"
room.isGame = true
room.maxUsers = 15

vars:Array = new Array()
vars.push( {name:"ogres", val:5, private:true} )
vars.push( {name:"skeletons", val:4} )

room.variables = vars


First an empty object is created, then we add the various room properties and then we define a new Array with a list of Room Variables.

[ Other ways of creating variables ]

By moving the playhead in the main timeline to the "app" label you can inspect the stage. In the "variable list" panel we have a datagrid that
will show names and values of each variable defined in the current room.

The "create variable" area allows you to create a new room variable by assigning name, value, type and the two boolean flags we've talked about earlier. On the right side of the application you'll find the usual room list and user list components.

You will notice that most of the code in the example is similar to the the other applications, so we'll analyze the most important section.

room:Object = new Object()

room.name = "The Cave"
room.isGame = true
room.maxUsers = 15

vars:Array = new Array()
vars.push( {name:"ogres", val:5, private:true} )
vars.push( {name:"skeletons", val:4} )

room.variables = vars


This method is called each time you press the "create" button. We've used a little "trick" to cast the values taken from the textfield to the appropriate Actionscript type: we created a variable called "fn" of type Function which will dynamically point to one of the built-in AS functions String, Number, Boolean depending on the datatype.

[ Optimizations Tips ]

When you send and receive variables from the server their names and values should always be kept as short as possible to save precious bandwidth.

Try keeping the variables names as short as possible, one or two characters would be the best choice, for example if you have in your SWF a variable called "enemy_posX" and you need to save it as a Room Variable try to shorten its name to "ex" or similar.


var roomVar:Array = []
roomVar.push( {name:"ex", val:enemy_posX} )

Another important aspect is floating point numbers as they can get pretty big while you may not necessarily need many decimal places. For example (100 / 3) gives 33.3333333333333 which is 17 characters long: in this case you may try to round them to the 2nd or 3rd decimal place to shorten the amount of data you're sending.

One trick that can help save quite a lot of space is using strings to compress more data into one single variable. Imagine you have to send four numbers to the server which in turn will update the other clients.

You could use the traditional approach :

var roomVar:Array = []
roomVar.push( {name:"x", val:100} )
roomVar.push( {name:"y", val:200} )
roomVar.push( {name:"w", val:50} )
roomVar.push( {name:"h", val:50} )


... or you could put the four values in one string with a separator like this:

var roomVar:Array = []
roomVar.push( {name:"s", val:"100,200,50,50"} )


when you receive them on the client you would use this code:

smartFox.onRoomVariablesUpdate = function(roomObj:Object)
        var variables:Object = roomObj.getVariables()
        var values:Array = variables["s"].split(",")
        for (var i:Number = 0; i < value.length; i++)

In other words you pack the four values into one single string choosing the "," (comma) as the delimitator and when you receive them on the
other clients you use the String split() method to obtain your values back.

[ Conclusions ]

By the end of this article you should be a Server-side variable master!
Try experimenting some more with this simple application by launching one or more instances of it at the same time.


Name: Marco Lapi, a.k.a Lapo
Location: Fossano, Italy
Age: 34
Flash experience: started out with Flash 4 back in 1999
Job: web designer/developer
Website: http://www.gotoandplay.it/
| Homepage | News | Games | Articles | Multiplayer Central | Reviews | Spotlight | Forums | Info | Links | Contact us | Advertise | Credits |

| www.smartfoxserver.com | www.gotoandplay.biz | www.openspace-engine.com |

gotoAndPlay() v 3.0.0 -- (c)2003-2008 gotoAndPlay() Team -- P.IVA 03121770048