Table of contents
Game servers based on SLOT-IDE game engine
The game engine available on this website comes as a javascript library that can be integrated and used in pretty much any environment and/or application that is capable of executing javascript code.Through modern javascript engines like Google V8 the game engine can be used in native game clients (such as the ones running on standalone Class III machines), mobile slot applications and of course it can be also integrated in gaming platforms as a server side component. This section refers to the latter case and demonstrates how easily it is possible to create game servers based on the game engine.
Because of its flexibility and thanks to the semplicity of its APIs, in order to implement a game server one simply has to wrap the game engine APIs and develop a service layer that handles the requests of the game clients.
This can be done in different technologies with the result being a game server that is capable of providing the logic and generating the outcomes for any slot game defined in SLOT-IDE.
The game server implementations available in this page come for free and are provided for demonstration purposes to those who have purchased the unencrypted version of the game engine. The underlying client/server communication protocol is based on JSON over HTTP and reflects the APIs of the game engine.
PHP Game server
This section describes a simple PHP game server implementation. The execution of javascript code from PHP is made possible by the V8JS PHP extension.Click on the link below to download the game server package:
SLOT-IDE_GameServer_PHP_v0.1.zip
The following code shows the simplicity of the game server script.
The GameEngine class wraps the APIs of the game engine. The actions that need to be invoked on the game engine are obtained from the HTTP request. All events fired by the game engine are sent back to the client in the HTTP response.
require_once("includes/engine.php");
$actions = json_decode(isset($_GET['actions']) ? $_GET['actions'] : file_get_contents('php://input'));
$sid = @$_GET['sid'];
$gameScript = @$_GET['game'];
$engine = new GameEngine($sid, $gameScript);
try {
$engine->invokeActions($actions);
} catch (Exception $e)
{
$err = array('error'=>$e->GetMessage());
echo json_encode($err);
exit;
}
echo json_encode($engine->getEvents());Table of Contents
7.Client sessions
9.Resuming interrupted game rounds
1.
Introduction
This
document describes a simple PHP game server based on SLOT-IDE game engine.
The game
server script relies on the V8JS (http://github.com/preillyme/v8js) PHP extension in order to process the game
engine script (slotgame.js) and wraps the APIs of the game engine in order to
allow invoking actions on the engine and receiving events directly from PHP.
Game
clients talk to the game server through a simple JSON over HTTP protocol that
reflects the game engine APIs.
For each
HTTP request sent to the server the game client specifies a unique session ID
that is used by the game server hold the state of the game round for that the
client.
In the body
of the HTTP POST request the client puts a JSON encoded array of actions (bet,
play etc.). The actions specified in the HTTP request are executed by the PHP
game server script on the javascript game engine. A
single HTTP request can contain several actions which will be executed
consecutively.
After
executing the actions the game engine fires a number of events, the events are
collected by game server script and are sent back to the game client in the
body of the HTTP response as a JSON encoded array.
In order to
understand this document the following page should be used as a reference as it
describes the actions that can be executed on the game engine and the resulting
events that the game engine fires when the actions are executed:
http://www.slot-ide.com/gameengine.html
2.
Requirements
In order to
run the PHP server the following requirements must be satisfied:
- PHP 5.3.3+
- V8 library and headers installed in proper paths (http://code.google.com/p/v8/). Most Linux distributions now provide Google V8 as a binary package.
- V8JS PHP PECL extension (http://pecl.php.net/package/v8js). This can be installed via "pecl install v8js" command.
- PHPMemcache extension (http://php.net/manual/en/book.memcache.php) or APC PECL extension (http://php.net/manual/en/book.apc.php). Alternatively any other caching method can be used (see gameengine.php).
- Unencrypted version of SLOT-IDE game engine script (slotgame.js) to be placed in the scripts directory. See http://www.slot-ide.com/pricing_contact.html
3.
Game server configuration
The game
server configuration can be set by editing the file "includes/config.php".
Here is a
list of the available settings:
- Cache class: name of the class that implements the cache used by the server to hold the clients states in memory (currently Memcache and APC are supported and can be used by setting the values Memcache_Cache or APC_Cache, other caching methods can easily be added)
- Inactivity timeout: determines how long the state of a client is kept in memory after the last request for that client is received
- Test: when true it allows forcing outcomes by injecting values for the random numbers
- Hide reels: when true it prevents the server from sending the reel strips in the config and spinStart events (clients can use virtual reel strips and can rely on the playedSpin event to know what symbols to display in the visible matrix after a spin)
4.
URL
for the HTTP requests
The URL for
the HTTP requests is the following:
http://serverip/path/gameserver.php?sid=sessionid&game=atkins_slot.js
where:
- serverip = IP address of the server
- path = the path where the game server is deployed in the document root of the web server
- sid = a ID that uniquely identifies the session of the playing user
- game = the SLOT-IDE game script that defines the game. This must be one of the scripts available on the server in the "script/games/" directory (e.g. atkins_slot.js)
5.
Format
of the HTTP requests
Clients
send HTTP GET or POST requests to the server. When POST requests are used the
body of the request contains a JSON encoded array of actions. With GET requests
the actions are specified with a querystring
parameter.
An action
is a JSON object with two fields: action
for the name of the action and context.
The value of context is an object that is used
to specify the arguments for the action and can be null when the action takes no argument.
For a
complete list of actions and the corresponding arguments refer to this page:
http://www.slot-ide.com/gameengine.html#actions
Here below
is an example of a HTTP POST request sent with the CURL command that executes
two actions: config
(to retrieve the initial configuration of the game) and bet (to set the number of paylines and
the credits bet-per-line):
curl -X POST -d'[{"action":"config"},{"action": "bet",
"context": [10,1]}]' "http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js"
The same
actions can be sent in an equivalent HTTP GET request with the following URL
structure:
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action":"config"},{"action":
"bet", "context": [10,1]}]
For simplicity, in the examples that follow in the rest of the document the client
requests will be shown in the HTTP GET form.
6.
Format
of the HTTP response
Every
action that is executed by the game server script on the game engine fires one
or more events. The events are collected fired by the engine are collected and
sent back to the client as a JSON array in the body of the HTTP response.
Each event is represented by an object with two fields: event for the name of the event and context. The value of context is an object (when present) that contains event specific information that the server wants to send to the client.
For a
complete list of events and the corresponding context refer to this page:
http://www.slot-ide.com/gameengine.html#events
As an
example, here below is an example request sent by the client in order to set
the bet (bet 5 credits per line on ten paylines):
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action": "bet", "context":
[10,5]}]
And the
response of the server shows the context for the bet event containing the total bet, the chosen bet-per-line and the
structure of the selected paylines:
[{"event":"bet","context":{"total":50,"betPerLine":5,"paylines":[[1,1,1,1,1],[0,0,0,0,0],[2,2,2,2,2],[0,1,2,1,0],[2,1,0,1,2],[0,0,1,2,2],[2,2,1,0,0],[1,0,1,2,1],[1,2,1,0,1],[0,2,2,1]],"maxWinCap":0}}]
7.
Client
sessions
As it will
be shown a single game round can require the game client to send multiple
requests to the game server. For each client the game server holds in memory
the state of the game round by mapping it to the sessionID specified by the client
in the HTTP request.
When a game
client sends a HTTP request that contains the bet action, the server clears the state associated to the client
because in this case a new game round is about to start.
The
lifetime for a client session can be configured on the server. This is
important as it makes it possible to resume interrupted game rounds.
8.
Game flow
When a
client is loaded it is meant to send a config action to the server. This is used by the client to
retrieve the game configuration by the server and it is meant to be invoked
only once during the life cycle of the client.
The client
can also choose to send a bet action
together with the config
action in the same request in order to set the initial bet.
As already
described upon receiving a bet action
the server creates a game instance for the client.
To initiate
a game round the client sends to the server an action called play. The play action tells the server to initiate a game round and by
default it takes no arguments.
Upon
receiving a play request the game server generates the outcome of the base game
and sends the results to the client. Depending on the outcome there can be a
number of events fired by the game engine, but because a spin has been played
the response will always contain at least a playedSpin event, as described
here:
http://www.slot-ide.com/gameengine.html#event_playedSpin
If no bonus
is entered then the response will also contain a gameEnd event:
http://www.slot-ide.com/gameengine.html#event_gameEnd
For each
win obtained in the visible matrix as a result of the spin the response
contains a spinWin
event:
http://www.slot-ide.com/gameengine.html#event_spinWin
If a bonus
is entered no gameEnd
event will appear in the response because the game round isn't over. In this
case the client is meant to continue playing the freespins
or the bonus rounds by sending additional HTTP requests with the play action.
The state
of the bonus is sent to the client by the server in the spinTrigger, enterBonus, playedBonusSpin
and playedBonusSpins
events.
Here below
the client/server communication for an example client session is shown.
The Client starts
and sends an initial config
request to the server:
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action":"config"}]
The server
replies with the game configuration:
[{"event":"config","context":{"symbols":["Atkins","Steak","Ham","Drumstick","Sausage","Eggs","Butter","Cheese","Bacon","Mayonnaise","Scale"],"symbolsPay":{"line":["Atkins","Steak","Ham","Drumstick","Sausage","Eggs","Butter","Cheese","Bacon","Mayonnaise"],"scatter":["Scale"]},"wildSymbols":["Atkins"],"lineAlign":"left","lineCoinciding":false,"window":{"reels":5,"rows":3},"availablePayLines":[[1,1,1,1,1],[0,0,0,0,0],[2,2,2,2,2],[0,1,2,1,0],[2,1,0,1,2],[0,0,1,2,2],[2,2,1,0,0],[1,0,1,2,1],[1,2,1,0,1],[0,2,2,2,1],[2,1,1,1,0],[1,0,0,1,2],[1,2,2,1,0],[1,1,0,1,2],[1,1,2,1,0],[0,1,0,1,2],[2,1,2,1,0],[2,1,0,0,1],[0,1,2,2,1],[0,1,1,2,1],[0,1,0,1,0],[2,1,2,1,2]]}}]
The client wants
to play a game round and sends a request containing bet (bet on ten paylines with one credit bet per line) and play actions:
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action":"bet","context":[10,1]},{"action":"play"}]
The server
replies with the outcome of the game round (last event in red is gameEnd
indicating that the game is over with a zero win):
[{"event":"bet","context":{"total":10,"betPerLine":1,"paylines":[[1,1,1,1,1],[0,0,0,0,0],[2,2,2,2,2],[0,1,2,1,0],[2,1,0,1,2],[0,0,1,2,2],[2,2,1,0,0],[1,0,1,2,1],[1,2,1,0,1],[0,2,2,2,1]],"maxWinCap":0}},{"event":"gameStart","context":{"totalBet":10,"betPerLine":1}},{"event":"spinStart","context":{"symbols":["Atkins","Steak","Ham","Drumstick","Sausage","Eggs","Butter","Cheese","Bacon","Mayonnaise","Scale"],"symbolsPay":{"line":["Atkins","Steak","Ham","Drumstick","Sausage","Eggs","Butter","Cheese","Bacon","Mayonnaise"],"scatter":["Scale"]},"wildSymbols":["Atkins"],"lineAlign":"left","lineCoinciding":false,"stops":[4,31,4,28,26],"ranges":[32,32,32,32,32]}},{"event":"playedSpin","context":[["Eggs","Scale","Sausage"],["Eggs","Butter","Butter"],["Drumstick","Bacon","Cheese"],["Ham","Butter","Mayonnaise"],["Drumstick","Ham","Cheese"]]},{"event":"gameEnd","context":{"win":0}}]
When a
bonus is triggered (freespin bonus or other kinds as
well) the client is meant to send additional play requests in order to receive the outcome for each freespin or bonus round that is going to be played.
In the
response to the last play request the
client will receive the gameEnd
event with the final win.
9.
Resuming interrupted games rounds
The server
makes it possible for the client to recreate and replay both interrupted game
rounds and completed game rounds. This is possible because the server holds in
memory all the information that is needed to reproduce completely the state of
a game round.
Currently
the game server supports a simple mechanism for resuming games that will be
briefly described in this section. Other mechanisms can easily be implemented.
When a game round is interrupted on the client side or a client session is terminated abruptly (network error, client crashing or being closed etc.) the client is meant to be restarted some time later with the same session ID. In this case upon receiving the initial config request from the client the game server replies with the full list of events held in memory for the client session. In both the case where the client session got interrupted just before the end of a game round or in the middle of a game round (as in the case where the player was in a freespin bonus with a number of freespins left to play) the client can easily reconstruct the game round out of the list of events received from the server.
10.
Forcing
game outcomes
When the
game server is configured to run in test mode it is possible to force
the outcome of the game rounds. This is done by specifying a list of random
numbers as the context for the initial play
action.
The random
numbers provided can be used to force the complete outcome of the game round
including bonus features. For instance, in a five reels game the first five
numbers provided determine the stop positions of the reels in the base game (initial
spin). If a bonus is triggered and freespins are won
then the next random numbers in the list determine the stop positions of the
reels during the bonus freespins.
As an
example, the request shown below forces the Atkins
game to enter the bonus. The stop positions in red determine the spin in the
base game and force three scatters on the first three reels so that the bonus
is triggered.
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action":"bet","context":[10,1]},{"action":"play",
"context": [2,2,2,10,20,10,10,10,10,10]}]
When
sending the subsequent request in order to play the first freespin
if no additional number is provided in the context of the play action then the remaining five numbers (10,10,10,10,10) specified in the initial
request will determine the outcome of the spin.
In order to
force the outcomes for features that depend on pickRandomly and customTrigger a
float number in the [0,1) range is to be used.
In the
following example a play request is sent with a context that sets the stop positions for the spin in the base game
and the value 0.2 to force the
outcome of a mystery bonus feature:
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action":"bet","context":[10,1]},{"action":"play",
"context": [2,2,2,10,20,0.2]}]
11.
Gamble
support
The game
server script extends the APIs of the game engine in order to support gambling.
Currently
double-up and triple-up are supported and game clients can choose the let
players gamble the win of the entire game round or just the win obtained in the
current spin (for games without bonus or in game rounds where the player does
not enter any bonus the win of the game round comes from the single spin played
in the base game and therefore these two forms of gambling are equivalent).
Game
clients support gambling by sending an additional request to the game server
that contains the gamble action. Here
is an example request where the player attempts to triple up the win obtained
during the last spin:
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action":"gamble","context":{"context":
"spin", "type": "triple_up"}}]
The
attributes in the gamble context are:
- context: determines whether the player is wanting to gamble the entire win of the game round or the win obtained during the last spin. In the first case the value is "game_round", in the latter the value for this attribute is "spin". A game client should send a gamble request with the context set to "game_round" only at the end of the game round (after receiving the gameEnd event)
- type: one of "double_up" and "triple_up" (defaults to "double_up")
Depending
on the gamble context specified in the gamble request the game server
determines the win amount being gambled and after drawing randomically
the result of the gamble it fires a gamble event that is returned to the
client. Here is an example event for a losing gamble fired by the game server:
{"event":"gamble","context":{"context":"spin","win":0}}
The context of the gamble event contains a win attribute that indicates the result of the gamble. A win value of zero means that the player has lost the win, any other value corresponds to the new win after gambling.
When a game
client supports gambling and gives players the possibility to gamble the final
win is not determined at the end of the game round because players have to
choose whether to collect the win or to gamble it. Therefore in these cases the
game flow is slightly modified with the addition of a collect request that clients are meant to send to the server when
the player chooses to collect the win at the end of the game round.
The
modified flow will now be described.
At the end
of a game round (no more spins left to play) in response to a play request as usual the game server
sends to the game client a gameEnd event:
{"event":"gameEnd","context":{"win":4580}}
The player
chooses whether or not to gamble the win.
If the
player does not want to gamble then the game client sends a collect request to the server, like the
following:
http://serverIp/path/gameserver.php?sid=mysession&game=atkins_slot.js&actions=[{"action":"collect"}]
The server
replies with a gameRoundOver
event that contains the final win of the game round (in this case the value
matches what was sent previously in the gameEnd event because the player chose not to gamble)
{"event":"gameRoundOver","context":{"win":4580}}
If the
player decides to gamble then the game client will send one or more gamble
requests to the server up to when either the player loses the gamble or
eventually decides to collect the win obtained.
In the
first case the server will send a response containing both the result of the
losing gamble and the gameRoundOver
event with the updated win value:
[{"event":"gamble","context":{"context":"spin","win":0}},{"event":"gameRoundOver","context":{"win":4530}}]
In the
latter case the game client has sent a collect request to the server and the
game server will reply with a gameRoundOver response
containing the updated win value.
The flow
that was described assumes that the slot game round ends with a positive win
value. For losing game rounds (game rounds that finish with a zero win) where
there is not win to gamble in order to be consistent the game server sends a gameRoundOver
event together with the gameEnd
event at the end of the game round.
Thus from
an accounting point of view when gamble is supported the gameRoundOver event is what needs
to be considered in order to close the game round.
NodeJS game server
The following package contains a game server based on SLOT-IDE game engine that runs under NodeJS.The game server can be run with a valid SLOT-IDE license (using the encrypted game engine and the custom NodeJS executable that are in the package) or with a regular NodeJS installation (under Windows, Linux or Mac) using the unencrypted game engine.
The package contains a document that describes how the game server works and the client/server communication protocol.
Click on the link below to download the game server package:
SLOT-IDE_GameServer_v0.5.zip