Cluster Server-side development

Developing server-side Extensions for the Overcast Cluster is, for the most part, very similar to regular SFS2X development. You will be using very familiar API and be able to port existing game code from previous projects in this environment, with minimal changes.

In particular the locality of data that we have mentioned in the architecture section allows to reason and manage the game state in a familiar way, without the complexity of distributed systems.

In other words, the vast majority of the Lobby state is local to the Lobby and can be managed normally, i.e. as if developing for a standalone system. Similarly most of the game state in each Game Node is also local and doesn't require new knowledge compared to standard SmartFoxServer 2X development.

Where elements of the Lobby/Game state needs to be globally available we'll use the database. Classic examples are user profiles, game statistics, high score tables, etc.

Lobby side

We'll start by taking a look at Extensions development for the Lobby Node, which is the main entry point for all players. Here we need at least to handle login credentials and maybe also allow clients to create a new account (unless this is done somewhere else, for instance on the main website).

As mentioned in the architecture section, the Lobby is the place where users interact mostly with the server and not much with other players, with the exception of the Buddy List system. It is the place where players can configure and modify their profile, inventory, buddy lists etc. And run match-making requests.

Recommended:
  • Using a single Zone-level Extension.
  • Using a secondary Zone for guest users or to setup a new account.
  • Use Buddy Lists for user interaction.
  • Use the central database for shared state.
Discouraged:
  • Creating Rooms for user interaction; use Game Nodes instead.
  • Using Room-level Extensions.
  • Sending broadcast-type messages, such as Public Message and similar from server side.

Player interactions in the Lobby should be kept to a minimum and only using the Buddy List API. All the other more complex interactions (public/private chats, turn-based/real-time gaming, etc) should be delegated to Game Nodes.

New API

From the Lobby side we'll be able to access the new Clustering API which offer several new features to run match-making queries, create and join new games etc.

Here we will find methods such as:

  • createRoom()
  • quickJoinOrCreateRoom()
  • sendInvitation()

All of which are replacement of the standard SFS2X API methods that are cluster-aware, integrating Load Balancing, Server Orchestration, etc.

The API can be imported in your Java project by adding the sfs2x-cluster.jar library found in any SmartFoxServer 2X distribution.

NOTE: the Clustering API are only useful from the Lobby Node, and should be mainly used in Lobby-side Extensions.
What's different?

If you are still wondering what's different when writing Extensions for the Lobby, the answer is just a few things. All of the concepts you've learned by developing SFS2X Extensions apply here as well, with the addition of the new Clustering API and the guidelines we have just discussed.

Game side

Server-side development for Game Nodes mostly entails creating Room-level Extensions that are dynamically loaded by Game Rooms at launch. This is good news for developers who can transport their SFS2X knowledge and existing code with minimal rework, if any at all.

An important aspect of Game Nodes is that they don't deal with Login or Join Room operations anymore:

  • Users login at the Lobby Node where credentials are checked. When players are sent to a Game Node, they are auto-logged in without need for another verification.
  • Also join operations are directed by the Lobby.

As mentioned in the architecture section, Game Nodes are the place where users play games and interact with each other, send public and private messages, invitations, etc.

Recommended:
  • Using Room-level Extensions for Game Rooms.
  • Deploying multiple Room-level Extensions for each supported game.
  • Using Game Rooms for chat-only areas too.
  • Using the central database for shared state.
Discouraged:
  • Creating Rooms manually from a Game Node Extension. Use the Cluster API from the Lobby side instead.
  • Using Zone-level Extensions to handle Game logic.
  • Handling the USER_LOGIN event at Zone Level. Logins on Game Nodes are automatically managed by the cluster.
  • Manually joining users in Rooms from Extension code.
Single Zone approach

One rule to keep in mind is that Game Nodes run a single Zone, called Cluster, that is readily available when the Node is launched. You can still organize your multi-game project by using different Room Groups for different games, only keep in mind that you won't be able to use multiple Zones on Game Nodes.

Zone Extensions

Sometimes it can be useful to run a global Zone Extension on Game Nodes: for instance when you need to handle server-side events that are dispatched at Zone-level only. An example would be the SERVER_READY or USER_JOIN_ZONE events.

When developing a Zone Extension for Game Nodes the base class to use is no longer SFSExtension but rather a new class called SFSClusterGameExtension (which extends the former).

This is provided in the previously mentioned sfs2x-cluster.jar library that can be added as dependency to your Java project.

Below is a simple example of usage:

			public class MyNodeExtension extends SFSClusterGameExtension
			{
				@Override
				public void init()
				{
					// Don't forget this
					super.init();

					// Add request and event handlers...
					
					// More game initialization code...
				}

				@Override
				public void destroy()
				{
					super.destroy();

					// More clean-up logic...
				}
			}

The way in which this class works is almost identical to the old SFSExtension: same init() and destroy() methods, same way to add and remove event/request handlers, etc.
However, there is an extra step to remember: the super.init() at the beginning of the init() method. When extending the SFSExtension base class you don't need to do this explicitly. Here instead it's necessary to make sure the base class is also properly initialized. Failing to do so will become immediately apparent as clients won't be able to login on the Game Node.