Skip to content

Server Variables

SmartFoxServer provides different types of Server Variables that can be used to maintain synchronized state across Users, Rooms and Buddies inside a Buddy List.

Server Variables, in general help the client (or server) logic to store custom values that are automatically updated within a specific scope. There are three main types of Server Variables:

  • User Variables: custom data attached to a User object. All updates are received by the clients in the same Room(s) where the owner is joined. Example: a User called Piggy will be able to access and get updated about all Variables of user Kermit when they are both joined in the same Room. A common use case is to store custom User profile or game state (score, rank, avatar type, etc...)

  • Room Variables: custom data attached to a Room object. Their scope is the Room itself, therefor clients can access Room Variables as soon as they join a specific Room. A common use case is to keep the state and properties of a game (required skill level, highest score, game state, etc...)

  • Buddy Variables: they represent custom data attached to a Buddy object in a Buddy List. The scope is the Buddy List itself. Example: anyone who adds a User called Gonzo in their list will see and receive updates for those Buddy Variables. A common use case is to keep every friend updated about one's status in real-time.

Overview

The following diagram illustrates a simplified hierarchy of the different types of Server Variables. At the top we have the Variable interface defining the basic properties such as name and value. Below we find different sub-classes that extend the basic features and add new properties such as private, persistent, hidden etc.

RoomList

Let's take a look at each property:

  • name: can be any string. Keep in mind that short names will use less bytes and therefore less bandwidth. Often times 2-5 characters are enough to define a Variable

  • value: all Server Variables support several basic types: Null, Bool, Byte, Short, Int, Long, Float, Double, String, SFSObject, SFSArray, Vector2, Vector3

  • isHidden: by default all variables are not hidden. You can switch this flag on for User/Room Variables to keep these values accessible only from the server side. This flag is also availble only when creating Variables from the server side (default == false)

  • isPrivate: has different effects when activated on a User Variable or Room Variable. Private User Variables are accessible only to their respective owners. Private Room Variables are visible to all clients in the Room but can only be modified by the owner.

  • isPersistent: by default a Room Variable is removed from the Room when the owner leaves it. If this flag is turned on, the Room Variable will persist until the owner leaves or disconnects (default == false)

  • isGlobal: a global Room Variable is visible from outside the Room as well. The scope is the whole Room Group, so clients that have not joined this Room but are subscribed to the relative group can access and receive updates. (default == false) Please note: running lots of global Variables can use significant bandwidth in a high traffic server

  • isStorable: specifies wether or not a Variable should be stored by a persistence service such as the Room Persistence API, which allows to store Room definitions and variables to a local file or database (default == true)

Static Room Variables

While User Variables and Buddy Variables can only be created dynamically via code, Room Variables can also be created statically at configuration time. You can learn more about this by consulting the documentation about the AdminTool's Zone Configurator.

Examples of usage

The following are a few examples of how to create Room/User Variables from the client API. Buddy Variables are treated separately in the largest context of the Buddy List API.

User Variables

The following example shows how a User can store some profile data using Variables that automatically update all other clients in the same Room(s):

// Create a list of User Variables
var uVars = new List<UserVariable> {
    new SFSUserVariable("avt", "MissPiggy.png"),
    new SFSUserVariable("job", "Acting and singing"),
    new SFSUserVariable("loc", "Muppet's Show")
}

// Send the request to set Room Variables
sfs.Send(new SetUserVariablesRequest(listOfVars));

To receive the update, clients must be listening to the USER_VARIABLES_UPDATE event and handle it like this:

...
// Add variable-related event listener during the SmartFox instance setup
sfs.AddEventListener(SFSEvent.USER_VARIABLES_UPDATE, OnUserVarsUpdate);
...

private void OnUserVarsUpdate(BaseEvent evt)
{
    // Get the user that changed his variables
    User user = (User) evt.Params[EventParam.User];

    // Do something with the values
    sfs.Logger.Info("Location: " + user.GetVariable("loc")?.StringValue);
    sfs.Logger.Info("Occupation: " + user.GetVariable("job")?.StringValue);
}

Room Variables

Below is a quick example of how to set a private Room Variable from client side:

// Create a list of Room Variables
var rVars = new List<RoomVariable> { 
    new SFSRoomVariable("topic", "Multiplayer Game Development") 
}

// Send the request to set Room Variables
sfs.Send(new SetRoomVariablesRequest(listOfVars));

To receive the update, clients must be listening to the SFSEvent.ROOM_VARIABLES_UPDATE event and handle it like this:

...
// Add variable-related event listener during the SmartFox instance setup
sfs.AddEventListener(SFSEvent.ROOM_VARIABLES_UPDATE, OnRoomVarsUpdate);
...

private void OnRoomVarsUpdate(BaseEvent evt)
{
    // Get the names of variables that were updated for the Room
    var changedVars = (List<String>) evt.Params[EventParam.ChangedVars];

    // Obtain the variable and do something with it
    if (changedVars.Contains("topic"))
    {
        var topicRV = sfs.LastJoinedRoom.GetVariable("topic"));

        sfs.Logger.Info("The Room topic is now set to: " + topicRV!.StringValue)
    }
}

Variables on the server-side

Setting Variables on the server side uses a similar interface and logic. Even if we haven't explored Extension development in this tutorial we can show a couple of examples to give you an idea of how similarly this works. Examples are in Java but can be transported to Kotlin, Scala, Groovy etc., very easily.

User Variables

private void setUserProfile(User user, int databaseId)
{
    // Define a public User Variable
    UserVariable avatarPic = new SFSUserVariable("pic", "GonzoTheGreat.jpg");

    // Define a private User Variable
    UserVariable dbId = new SFSUserVariable("dbId", databaseId);
    dbId.setPrivate(true);

    // Set User Variables via the server side API
    getApi().setUserVariables(user, List.of(avatarPic, dbId));
}

Room Variables

The interesting thing about creating Variables on the server side is that the owner is the server itself, while on the client side it always is the User that sends the request.

This means that server-created Room Variables never expire, in contrast to those generated via the client API. This can be used to maintain fully persistent values in any Room that requires it.

private void setupRoomVariables(Room room)
{
    // Define a private, global Room Variable; no one will be able to overwrite this value
    // Being a global Variable, its value will be visible from outside the Room
    RoomVariable chatTopic = new SFSRoomVariable("topic", "Multiplayer Game Development");
    chatTopic.setPrivate(true);
    chatTopic.setGlobal(true);

    // Define an hidden Room Variable, only accessible from server side
    RoomVariable isModerated = new SFSRoomVariable("isMod", true);
    isModerated.setHidden(true);

    // Set Room Variables via the server side API
    // Passing null as the User parameter sets the ownership to the Server itself
    getApi().setRoomVariables(null, room, List.of(chatTopic, isModerated));
}