Skip to main content
All CollectionsGame Design
How to Implement a Global Jackpot
How to Implement a Global Jackpot

This article describes how to implement a global jackpot using brainCloud’s RTT and Chat services.

C
Written by Cody Melvin
Updated over 2 months ago

A common feature in casino-style games is a global jackpot that users contribute to as they play and can be collected when a user reaches a set criteria. The more difficult the criteria, the larger the jackpot will grow until it is eventually collected.

In the Acey Deucey brainCloud demo, a portion of a user’s bet is added to the jackpot whenever they lose. When a user wins a predefined number of games in a row, they collect the jackpot and it resets to its default starting value (defined by a Global Property). This jackpot value updates in real-time, so multiple users playing across different sessions at the same time will always have an accurate reflection of the current jackpot.

With brainCloud, setting up a jackpot system is quick and easy. The process defined in this article can be condensed as follows:

From the brainCloud portal:

  1. Create a Global Statistic to hold the value of the jackpot

  2. Enable RTT and Chat from the brainCloud portal

  3. Create a Global Chat Channel to send and receive updates

From the app:

  1. Read the Global Statistic containing the jackpot value

  2. Connect to RTT and the Chat Channel

  3. Increment the Global Statistic where desired

  4. Send a chat message with the updated jackpot value

  5. Receive the updated jackpot value through an RTT Chat Callback

The code snippets within this article are from the Acey Deucey demo- a web app that uses the JavaScript brainCloud client library. The API Docs can be referenced to view the equivalent syntax for apps written in a different language.

Creating the Jackpot

The first step in implementing a jackpot that all users can view, contribute to, and collect, is creating a Global Statistic. From the brainCloud portal, go to Design > Cloud Data > Global Statistics and select the + icon in the top right corner.

Give the new statistic a Name, Category, and Description, then click Save.

An initial value can be set here, but for Acey Deucey, the jackpot’s starting value is defined by a Global Property that is read from the app when the game is first initialized, or when the jackpot is collected. This process is described later in the article, but is not necessary to implement a global jackpot.

To view the current value of a Global Statistic (or reset it), go to Global > Global Data > Global Statistics.

RTT / Chat Configuration

Jackpot updates will be received through a global chat channel. RTT and Chat will need to be enabled first.

To enable RTT, go to Design > Core App Info > Advanced Settings, and select Real-time Tech (RTT) Enabled.

To enable Chat, got to Design > Messaging > Chat, and select Chat Service Enabled.

Create a Chat Channel by going to Design > Messaging > Chat Channels, and clicking + New Channel.

Give the channel a Code (used for the channelID), Name, and Description, then click Save.

Everything is setup from the portal. Now it’s time to add some code.

Reading the Jackpot’s Value

The code in this section is taken from the Acey Deucey demo, a web application written in JavaScript. The API Docs can be referenced to view the equivalent syntax for apps written in a different language.


Global Statistics are retrieved by calling ReadAllGlobalStats. The returned JSON will contain all of an app’s global statistics.

// Read Global Statistics to get current Jackpot amount
_bc.globalStatistics.readAllGlobalStats((readAllGlobalStatsResponse) => {
var currentJackpot = readAllGlobalStatsResponse.data.statistics.Jackpot;

// Correct jackpot value if it is lower than the starting/reset value
if (currentJackpot === 0) {
var defaultResetValue = 0;
_bc.globalApp.readProperties((result) => {
defaultResetValue = result.data.JackpotDefaultValue.value;
$scope.updateJackpot(defaultResetValue);
var statistics = {
TotalHouseWinnings: -1 * defaultResetValue,
};

_bc.globalStatistics.incrementGlobalStats(statistics, (result) => {
var status = result.status;
console.log(status + " : " + JSON.stringify(result, null, 2));
});
});
}
else {
$scope.updateDisplayedJackpot(currentJackpot);
}
});

As mentioned above, Acey Deucey uses a Global Property to set the jackpot’s starting/reset value. That property is read via ReadProperties. If the jackpot global statistic’s current value is lower than this property (i.e. it has been reset or has never been used) it will need to be corrected. These steps can be skipped if no such property is being used:

// Read Global Statistics to get current Jackpot amount
_bc.globalStatistics.readAllGlobalStats((readAllGlobalStatsResponse) => {
var currentJackpot = readAllGlobalStatsResponse.data.statistics.Jackpot;
});

Connecting to a Global RTT Chat Channel

The next step in implementing the jackpot is connecting to RTT so that the app’s currentJackpot value can be updated as other users play. This is accomplished using brainCloud’s Chat service.
First, register a chat callback to receive RTT messages (jackpot updates in this case). Then, enable RTT.

$scope.enableRTT = function () {

// Register a callback for RTT Chat Channel updates
_bc.rttService.registerRTTChatCallback(rttCallback);

// Real-time Tech (RTT) must be checked on the dashboard
// (under Design | Core App Info | Advanced Settings)
_bc.rttService.enableRTT(
(enableRTTSuccess) => {
console.log("enableRTT Response: " +
JSON.stringify(enableRTTSuccess));

$scope.onRTTEnabled();
},
(error) => {
console.log("enableRTT Error: " + JSON.stringify(error));
},
);
};

Once an RTT connection has been established (onRTTEnabled), connect to the channel created earlier to listen for RTT messages (jackpot updates).

$scope.onRTTEnabled = function () {
console.log("RTT Connected!");

// Connect to default channels
var maxReturn = 0;
var channelId = appId + ":gl:jackpot"

_bc.chat.channelConnect(channelId, maxReturn, (channelConnectResponse) => {
var status = channelConnectResponse.status;

if (status === 200) {
console.log("Connected to Jackpot Updates channel");
}
else {
console.log("Failed to connect to chat channel);
}
});
};

Handling Jackpot Updates

Changes to the jackpot global statistic will be sent and received through the global chat channel created and connected to above in the form of RTT messages.

Sending a Jackpot Update

The conditions in which the jackpot should be updated can vary, but the two major actions are when it is incremented and when it is collected. Both of these actions are accomplished with IncrementGlobalStats.

In Acey Deucey, the amount seen below will either be a number to increase the jackpot global statistic by, or- if they are collecting the jackpot- a string: "RESET" (the latter will set the global statistic to 0). After calling incrementGlobalStats, the new value of the global statistic will be read. This value is then sent to other users via postChatMessage.

In the case of a "RESET" (i.e. the new value is 0), the global property containing the starting/reset value is read to correct the jackpot:

/**
* Increment the Jackpot if a user loses money, or "RESET" it if the user collects it.
* @param {number} amount
*/
$scope.updateJackpot = function (amount) {
var statistics = {
Jackpot: amount,
};

_bc.globalStatistics.incrementGlobalStats(statistics, (result) => {
var newJackpotAmount = result.data.statistics.Jackpot;

// Jackpot should never be zero. When a player collects the jackpot, reset it to a default value (defined in Design > Cloud Data > Global Properties)
if (newJackpotAmount === 0) {
var defaultResetValue = 0;

_bc.globalApp.readProperties((result) => {
defaultResetValue = result.data.JackpotDefaultValue.value;

$scope.updateJackpot(defaultResetValue);
});
}

// Send updated Jackpot amount through Chat Channel
var content = {
jackpotAmount: newJackpotAmount,
};
var recordInHistory = true;

_bc.chat.postChatMessage($scope.channelId, content, recordInHistory, (result) => {
var status = result.status;
console.log(status + "Post Chat Message Success : " + JSON.stringify(result, null, 2));
});
});
};

If no such property is being used, the correction step can be skipped:

/**
* Increment the Jackpot if a user loses money, or "RESET" it if the user
* collects it.
* @param {number} amount
*/
$scope.updateJackpot = function (amount) {
var statistics = {
Jackpot: amount,
};

_bc.globalStatistics.incrementGlobalStats(statistics, (result) => {
var newJackpotAmount = result.data.statistics.Jackpot;

// Send updated Jackpot amount through Chat Channel
var content = {
jackpotAmount: newJackpotAmount,
};
var recordInHistory = true;

_bc.chat.postChatMessage($scope.channelId, content, recordInHistory, (result) => {
var status = result.status;
console.log(status + "Post Chat Message Success : " + JSON.stringify(result, null, 2));
});
});
};

Once the chat message has been sent, all users will receive the update. This will be handled within the chat callback that was registered when enabling RTT.

Receiving a Jackpot Update

The updated jackpot value will be within the rttMessage:

/**
* RTT Chat callback handler.
* @param {*} rttMessage RTT Chat update message
*/
var rttCallback = function (rttMessage) {

// Update Jackpot with value received from Chat message
if (rttMessage.data.content.jackpotAmount >= 0) {
var newJackpotAmount = rttMessage.data.content.jackpotAmount;

$scope.updateDisplayedJackpot(newJackpotAmount);
}
};

Using a Global Property to Reset the Jackpot

Acey Deucey uses a Global Property to set the jackpot’s starting/reset value. While this may not be necessary for all jackpot systems, it can be a useful option should developer’s want to change the default value from the portal.

To create a Global Property, go to Design > Cloud Data > Global Properties and click the + icon.

Fill out the required fields from the Meta tab…

…then add a value in the Data tab.

Once the property is created, it can be read via ReadProperties:

// Read Global Statistics to get current Jackpot amount
_bc.globalStatistics.readAllGlobalStats((readAllGlobalStatsResponse) => {
var currentJackpot = readAllGlobalStatsResponse.data.statistics.Jackpot;

if (currentJackpot === 0) {
var defaultResetValue = 0;

// Retrieve the Global Property
_bc.globalApp.readProperties((result) => {
defaultResetValue = result.data.JackpotDefaultValue.value;

$scope.updateJackpot(defaultResetValue);
});
}
else {
$scope.updateDisplayedJackpot(currentJackpot);
}
});

In the case above, the Global Property is retrieved when first reading the jackpot global statistic in order to make sure that the jackpot’s value is never zero / below the Global Property’s value. This same logic should be applied anywhere the jackpot global statistic is being incremented/reset to ensure consistency as users play.

Live Demo & Source Code

At this point, users should now be able to increment and collect the jackpot, all while sending and receiving updates made to it. How the jackpot is displayed and when it’s incremented is up to the developer; the steps described in this article are only intended to show what brainCloud features can be used to get a jackpot system up and running. For a working example- try out the Acey Deucey demo. The full source code (as well as other JS examples) can be viewed here: AceyDeucey.

Did this answer your question?