SpikerSystems_SideBet plug-in design guide for e-Gamers architecture

 

By Marty Wollner

Architect, SpikerSystems, L.L.C.

 

01-Feb-2011

 

 

Overview: 1

Goals: Clean Delineation of Functions: 2

Configuring e-Gamers platform to call a side-bet plug-in.. 3

How the configured SBn causes the side-bet plug-in get called.. 3

Handling side-bets in configurations running multiple concurrent games. 3

Terminology for handling multiple side-bets within a game: 4

Startup parameter notations and definitions: 4

Startup parameters: 6

Runtime Calls and Assumptions: 8

Side bet plug-in function call syntax: 9

Example call sequences for multi-player payouts of a jackpot.. 10

Complete Example with all code for the Survivor-5-Poker side bet.. 12

Database modifications: 12

Game table. 12

WagerClass Table. 13

Game_WagerClass table. 14

Wager table. 14

WagerRoll table. 15

Existing Module Modification: SpikerSystems_SideBet_PlugIn_Lib.bas. 16

Existing Module Modification: Player_in_1_DMQ.txt. 16

New Module Creation: SB_PI_7001_ColdStart.bas. 17

 

Overview:

 

This is a guide for writing a side-bet interface for SpikerSystems e-Gamers architecture.

 

Side bets are treated by the architecture as “plug-ins” in that the actual code to track the use of the wager and to determine winnings is made available as a set of wager specific modules used for these purposes.

 

It is envisioned that these modules will be supplied by the various vendors who create and/or own the rights to these wagers.

 

The example below demonstrates how a side bet named “Survive-5-Poker” is easily and seamlessly integrated into e-Gamers architecture.

 

Goals: Clean Delineation of Functions:

 

The goal is to provide a clear delineation BETWEEN:

 

What the e-Gamers architecture does to implement the play of multiple concurrent games (stuff “generic and separate” from specific plug-ins)

 

AND

 

What a vendor creating a specific side-bet plug-in is expected to know about the calling system (hopefully, not much at all!).

 

How is this done? ENCAPSULATION of Functions:

 

.

 

 

 

 

 

Configuring e-Gamers platform to call a side-bet plug-in

 

The “connection” between the game and the plug-in is defined solely in the PayoutNumerator column of the WagerClass table. Simply by defining the value as a NEGATIVE number, the system will look for and call plug-ins named according to the number. That’s all there is to it!

 

Each negative number is considered to be a “SIDE-BET ID NUMBER” or “SBn” for short, which corresponds to a callable plug-in routine assumed to be linked into the processing.

 

How the configured SBn causes the side-bet plug-in get called

 

In the container program, a list of forwarding links (shown in the example code below) associates the SBn with a set of callable routines of which the plug-is consists of.

 

For example, if a wager for which PayoutNumerator.WagerClass is defined as 275 needs to be paid off, a set of callable plug-ins named

 

  1. SB_PI_000275_ColdStart

 

  1. SB_PI_000275_WarmStart

  2. SB_PI_000275_ShutDown

 

  1. SB_PI_000275_RunTime

 

Are assumed to already be linked into a “CONTAINER” program, and available to process the wager payouts if and when called.

 

Handling side-bets in configurations running multiple concurrent games

 

Not a problem for plug-ins!

 

Even though a dealer might be controlling multiple concurrent games under the e-Gamers architecture, a given side-bet wager need not worry about identifying its use among them, and this is true even for situations where the same identical side-bet is used in multiple games in a configuration.

 

The calling system isolates these calls by-game so the plug-in doesn’t have to even know or care about it.

 

Terminology for handling multiple side-bets within a game:

 

A single dealer controls a game and can handle multiple possible side bets being played concurrently for it. In order to distinguish these side-bets from one-another, we need to denote each of them with an ID, for example, SBn.

 

Each side bet can possibly support multiple jackpots, so in order to distinguish these from each other, we need to denote each of these with an ID, for example, Jn.

 

In order to account for the plug-ins use under multiple currencies, the calling routine and all parameters define money in terms of “UNITS” rather than Dollars, Euros, etc.

 

The Survive-5-Poker example is intended for use in a roulette game, so we can call the randomization for it a “SPIN”. Note that although other forms of randomizations might be used like dice being rolled, for the sake of consistency we will still call the roll (or deal, or toss or pitch or whatever form of randomization is used), a spin.

 

Bets on certain wagers (including Survive-5-Poker), often take place over several spins; we call such action “PHASED BETS”, as opposed to “one-time roll” bets.

 

Looking at it like an assembly line, the bet moves in phases, one-way, from “STATION” to station:

 

(0)    (1)  (2)  (3)  (4)  (5)

       

 

Once the Survive-5-Poker bet moves from station (0) to station (1), it cannot be increased, decreased, or removed; it becomes what craps table terminology refers to as a “contract bet”.

 

We will call bets currently in a phase in which they cannot be increased, removed, or reduced “COMMITTED” bets.

 

Startup parameter notations and definitions:

Some of the following is repetitive for clarity…

 

  1. SBn

    Denotes a specific side-bet possibly being played. This is called the SIDE BET ID.

    For Survive-5-Poker, SBn = 7001 for American Roulette and 10037 for European Roulette.

 

  1. Jn

    Within a given side-bet (SBn) supporting possibly multiple jackpots, Jn denotes a specific jackpot. This is called the JACKPOT ID.

    Right now, Survive-5-Poker uses only 1 jackpot, so Jn =1.

 

  1. STn

    Within a given SBn consisting of a set of phases, STn denotes a particular position within the STack, but lets stick to the assembly-line analogy and call it a STation.

    For Survive-5-Poker, STn = 0 through 5. (This is how the calls map the STack position to the STations they virtually represent.)

 

  1. “Units”

    An integer number used to denote generic currency values.

    For Survive-5-Poker, the discussions have been $1 (low-limit) and $5 (high-limit). These are represented as 1 unit (= $1) and 5 units (= $5).

 

  1. “Bet” vs. “Wager”

    For consistency, we call the facility a “wager”(the Survive-5-Poker wager), we call the use of it a “bet” ($3 bet on Survive-5-Poker).

 

  1. “Spin”

    The randomization source (the roulette table spin) occurrence.

    For Survive-5-Poker we identify spins by the numbers 1 – 36, and then 37 for zero and 38 for double-zero. These identities are placed in the STack and passed on to the plug-in  routine in the call.

 

  1. “Phased Bet”

    A phased bet is a wager that is treated differently from one spin to the next. The game of traditional roulette has no phased bets; every bet is a “one-time” bet. The game of craps has phased bets, for example, the pass-line bet.

    For the Survive-5-Poker wager, it is a phased bet made upon a roulette table, and thus unique.

 

  1. “Committed Bet”

    A contract bet, for example the pass-line bet in craps, becomes “committed” the moment the come-out roll for a point number is made.

    Starting from STation (0), the Survive-5-Poker wager is not only a phased bet, it becomes a committed bet the instant the wheel spin occurs.

 

  1. “Surrender”

    A player’s option to remove, reduce, or cash-in a committed phased bet is called “surrender”.

 

  1. “Containing Program”

    Is the name for the program that runs the plug-in code.

 

Startup parameters:

 

  1. /Jackpot_SBn_TermnateOnColdStartError = (T or F)

    If  T, terminate the containing program if, when calling the plug-in routine during a cold start, a return of FALSE occurs.

 

  1. /Jackpot_SBn_TermnateOnWarmStartError = (T or F)

    If  T, terminate the containing program if, when calling the plug-in routine during a warm start, a return of FALSE occurs.

 

  1. /Jackpot_SBn_TermnateOnProcessingError = (T or F)

    If  T, terminate the containing program if, when calling the plug-in routine during a spin processing, a return of FALSE occurs.

  2. /Jackpot_SBn_Jn_StartBalance = n

    The number of units jackpot Jn starts at for side-bet SBn. Lets use an example,

    /Jackpot_7001_1_StartBalance = 46,000

 

  1. /Jackpot_SBn_Jn_Shared = (T or F)

    True if jackpot n for side-bet SBn is to be shared, false if not. Lets use an example,

    /Jackpot_7001_1_Shared = Y

 

  1. /Jackpot_SBn_Jn_MaxPayout = n

    Maximum number of units jackpot Jn for side-bet SBn can pay for a jackpot. Lets use an example,

    /Jackpot_7001_1_MaxPayout = 100,000

 

  1. /Jackpot_SBn_Jn_RakeNumerator = n
    /Jackpot_SBn_Jn_RakeDenominator = n

    Integers representing the portion of the player’s bet to be accumulated into jackpot Jn when the spin occurs. Let’s use an example,

    /Jackpot_7001_1_RakeNumerator = 1
    /Jackpot_7001_1_RakeDenominator = 1

    The above indicates that 100% of the side-bet is to be accumulated into jackpot #1.

 

  1. /Jackpot_SBn_Jn_SurrenderAllowed = (T or F)

    True if a player may surrender a committed bet made for side-bet SBn, false if not. Let’s use an example,

    /Jackpot_7001_1_SurrenderAllowed = F

 

  1. /Jackpot_SBn_DisplayString_n = (string)

    These are strings displayed for the side-bet, by standard, 1 – 4 are pre-determined as shown in this example:

    /Jackpot_7001_DisplayString_1 = Survive-5-Poker
    /Jackpot_7001_DisplayString_2 = By Marty Wollner
    /Jackpot_7001_DisplayString_3 = SpikerSystems, L.L.C.
    /Jackpot_7001_DisplayString_4 = Patent number : (Pending)

 

  1. /Jackpot_SBn_ParamString_n = (string)

    These are additional strings  that may be used as input parameters for the specific side-bet routine. Let’s use an example,

    /Jackpot_7001_ParamString_1 = T
    /Jackpot_7001_ParamString_2 = (The above T is used to indicate that partial wilds ARE to be used. This one would be specific for Survive-5-Poker 2, etc)

 

Runtime Calls and Assumptions:

 

The routine should be an encapsulated module, and will be called in the following 4 scenarios:

 

  1. Cold-Start (one time)

    The containing program calls the routine ONE TIME when it is started. The routine is provided with the capability to parse for any expected startup parameters it needs, and should do so at this time, as shown in the examples below.

    It is expected that the routine will parse and store them in its own cache for subsequent use, however, it can depend on the containing program to keep these parameters available as needed, although, these values may change in the event of a warm-startup. Please see the notes on warm-startups, below.

 

  1. Runtime (zero to many times)

    At an indeterminable amount of time after the one-time cold start call, it is assumed that the routine will be called EXCLUSIVELY to track, control, and make payouts for the wager,

    AFTER EACH SPIN.

    As such, it does NOT need to worry about any payouts made while it was not up and running. In other words, it is assumed that the game cannot have gone on using another dealer in such cases as a power failure, or if so, when the routine is re-started, the correctly adjusted /Jackpot_SBn_Jn_StartBalance parameter will be re-issued in the (new) one-time cold-start call.

    Specifically, the routine is called a series of times upon the completion of each spin, once for each station that each player that has any SBn side-bet booked, for the game.

    See the examples below describing how payouts occur for multiple players sharing the same jackpot. Each call will include the partial portion the individual player has bet, in relation to all bets for the given wager.

    While the series of calls is made, no action is allowed (the entire system s frozen from any player changes). The relative sequence of calls is unimportant, and the routine should not assume the calls are made in any particular order, for example, by player ID number order.

 

  1. At Warm-start time (zero to many times)

    A warm-start is a way for the calling system to make changes to the runtime program states without requiring a cold-start. The call to the side-bet plug-in is made AFTER the calling routine has established the new running state as a convenience so it may re-initialize itself as well.

 

  1. At shut-down (zero to one time)

    In the normal shut-down sequence of the calling system, a call is made to each side-bet plug-in currently in operation. Thus is also done as a convenience for the routine, HOWEVER, PLEASE BE AWARE that in some cases of abnormal termination this call may not arrive, and so it is STRONGLY suggested that no critical functions be written into these calls, for example, making the jackpot balances known so it can be used to initialize the next startup..

    If anything like that (saving items on disc, for example) needs to occur, the plug-in should do so a part of the processing performed in each runtime call, NOT here.

 

Side bet plug-in function call syntax:

 

Here is an example set of function declarations shown in VB6 syntax:

 

public function SB_PI_000275_ColdStart () as Boolean

 

public function SB_PI_000275_WarmStart () as Boolean

public sub SB_PI_000275_ShutDown ()

public function SB_PI_000275 ( _

Last_n_Stack() as integer,
n as integer,
Bet_ID as integer,
Bet as long,
optional Current_nj_Jackpot() as long,
optional nj as integer,
optional JP_Split_Denominator() as long) as long


WHERE:

Last_n_Stack() : is an array of the n most recent integers,
each representing the 1 to r range randomization (the last 5 spins)...
If Bet_ID = 7001 then r = 38, or if Bet_ID = 10037, r = 37.
Contents: The spin numbers 1 - 36 = 1 - 36, spin Zero = 37, spin Double-Zero = 38.
The stack is ordered from oldest (index n - 1) to newest (index 0)

n : is the number of elements in Last_n_Stack(), always 5 in your case*.

Bet_ID : is 10037 for European roulette, 7001 for American Roulette.

Bet is a long integer representing the number of UNITS bet. Doing so allows us to avoid multi-national currencies.

Current_nj_Jackpot() : is an array of jackpots, each representing the number of UNITS available for payouts**.

nj : is the integer number of elements in Current_nj_Jackpot() and JP_Split_Denominator(), always 1 in your case.

* implies this routine will only be called upon completion of the 5th spin after the bet was placed, and the stack will contain all 5 (non-null) spin values.
** implies that this routine may be called several times for a given wheel spin, each call for one and only one player, however, there can be several players, so for jackpot payouts, this must be accounted for !!! Without also supplying the algorithm with the exact breakdown of bets by player, it can't be done. And so, the JP_Split_Denominator defines the exact portion to split jackpots for this individual player, and the routine is called once for each player, each time with that player's portion of the jackpot due.

ALL OF THE ABOVE PARAMETERS ARE FOR INPUT, READ-ONLY. The authors of these routines must not attempt to write over any of them.

SB_PI_000275 returns a long number representing the number of units the bet pays off.

 

 

Example call sequences for multi-player payouts of a jackpot

 

 

Example 1: 5 numbers are spun:
30 – 31 – 35 – 34 – 29
anyone who made the bet at the start of the 5–roll sequence just hit a natural straight, and the function would return 800 to pay (200 to 1) under the following input:

Last_n_Stack() : 30 – 31 – 35 – 34 – 29
n : 5
Bet_ID : 7001
Bet : 4
(other parameters null for now)

It’s all straightforward until we start talking about jackpots… what if 5 people all hit a jackpot at the same time… it WILL happen a lot in this Survive-5-Poker wager because of its no-choices-shared-booking nature.

Example 2: Lets say this is one of the big jackpot sequences with a payout of 50% of the progressive, now at $46,000. The routine is supplied at runtime with:

Current_nj_Jackpot() : 46,000
nj : 1 (always 1 for you, till you come up with more jackpots…)

So now the routine knows that 23,000 of the 46,000 must pay for the jackpot. If there was only one lucky winner, he’d get it all, and that would be that.

Example 3: But life is never that simple, so this guy has 4 of his evil twins all betting at the same time at different terminals and some are playing different games against the same LIVE roulette spins, concurrently;


1. He’s playing TraditionalRoulette and has bet $2 on Survive-5-Poker.
2. His “tall” evil twin is also playing Roulette but he’s bet $7 on Survive-5-Poker.
3. His “short” evil twin is playing RB_CraplessCraps and bet $17 on Survive-5-Poker.
4. His “blonde” evil sister twin is tearing it up with Coin-Flip on the TruePlace_EasyGames_CC layout and bet $1 on Survive-5-Poker.
5. His “genious” evil redheaded twin sister is playing a concurrent set of heavily hedged and extremely complex strategies on the RouleDice layout, and she’s bet $5 on Survive-5-Poker.

That’s $32 total in bets on Survive-5-Poker. Next, I (my computer program) will call you (your routine) once for each player who made the Survive-5-Poker bet (the five evil twins) as follows:

Last_n_Stack(4-0) : 30 – 31 – 35 – 34 – 29
n : 5
Bet_ID : 7001
Bet : 2
Current_nj_Jackpot(1) : 46,000
nj : 1
JP_Split_Denominator(1) : 32



Last_n_Stack(4-0) : 30 – 31 – 35 – 34 – 29
n : 5
Bet_ID : 7001
Bet : 7
Current_nj_Jackpot(1) : 46,000
nj : 1
JP_Split_Denominator(1) : 32





you get the idea. The payouts shown converted back into U.S. dollars are:

2/32 * 23,000 = $1,437.50
7/32 * 23,000 = $5,031.25
17/32 * 23,000 = $12,218.75
1/32 * 23,000 = $718.75
5/32 * 23,000 = $3,593.75


total: $23,000

Short people have all the luck.

 

 

 

 

Complete Example with all code for the Survivor-5-Poker side bet

 

Database modifications:

 

Game table

Even though a side-bet isn’t a game the database is set up that way so that a game like Rock-Paper-Scissors cab run stand-alone or be included as a side bet within another game. Add one new record:

 

GameID: 7010

GameDescription: Survive-5-Poker

 

WagerClass Table

This is where on the bets gets split up into phases, each within its own WagerClass.

 

The second phase (represented by WagerClassID 7012) specifies DecreaseOrRemoveAllowed = N, and AddOrEstabliashAllowed = N, implementing the bet’s “committed” status at that time.

 

In the last phase of the bet (represented by WagerClassID 7012), the numerator implements the hidden link to the side-bet plug-in, allowing it to be called to determine the payouts.

 

Add 5 new records:

 

WagerClassID: 7011

Description: Survive-5-Poker Pass

PayNumerator: 1

PayDenominator: 1

BetMin: 1

BetMax:50

Persists: N

PhasedWager: Y

DecreaseOrRemoveAllowed: Y

AddOrEstabliashAllowed: Y

OffOnComeout: N

 

 

WagerClassID: 7012

Description: Survive-5-Poker Come_1

PayNumerator: 1

PayDenominator: 1

BetMin: 1

BetMax:50

Persists: N

PhasedWager: Y

DecreaseOrRemoveAllowed: N

AddOrEstabliashAllowed: N

OffOnComeout: N

 

 

WagerClassID: 7013

Description: Survive-5-Poker Come_2

 

WagerClassID: 7014

Description: Survive-5-Poker Come_3

 

 

WagerClassID: 7015

Description: Survive-5-Poker Come_4

PayNumerator: -7000

PayDenominator: 1

BetMin: 1

BetMax:50

Persists: N

PhasedWager: Y

DecreaseOrRemoveAllowed: N

AddOrEstabliashAllowed: N

OffOnComeout: N

 

 

Game_WagerClass table

 

Associating GameID 7000 (for Survive-5-Poker) with WagerClassID 7011 – 7015 pulls all those in when a game named Survive-5-Poker is specified in the report generation that produces the list of wagers in the game.

 

Add 5 new records:

 

GameID: 7000

WagerClassID: 7011

 

GameID: 7000

WagerClassID: 7012

 

GameID: 7000

WagerClassID: 7013

 

GameID: 7000

WagerClassID: 7014

 

GameID: 7000

WagerClassID: 7015

 

 

Wager table

Create a set of 5 records for each instance of the wager that will appear on the game layout. Within this set of 5, linkages from one to the next implement the phased bet action.

 

For only one instance, add 5 records:

 

WagerID: 70011

WagerClassID: 7011

Description: Survive-5-Poker Pass Line

 

WagerID: 70012

WagerClassID: 7012

Description: Survive-5-Poker Come_1

 

WagerID: 70013

WagerClassID: 7013

Description: Survive-5-Poker Come_2

 

WagerID: 70014

WagerClassID: 7014

Description: Survive-5-Poker Come_3

 

WagerID: 70015

WagerClassID: 7015

Description: Survive-5-Poker Come_4

 

WagerRoll table

For each set of 5 records defined in the Wager table a set of records must be defined here to associate the 5 wager phases with the various spins that enact the outcomes. Because of the nature of this wager, each possible roulette spin must be accounted for in every phase, so all 38 records are defined for each.

 

Within each set of 38, linkages from one phase to the next of the set of 5 phases are defined to implement the phased bet action.

 

For only one instance, add 5 x 38 records: (SEE TABLE FOR COMPLETE EXAMPLE).

 

WagerID: 70011

RollID: (a 1 spin’s ident)

Description: Survive-5-Poker Pass Line : Spin 1

PhaseToWagerID: 70012

 

WagerID: 70011

RollID: (a 2 spin’s ident)

Description: Survive-5-Poker Pass Line : Spin 2

PhaseToWagerID: 70012

 

 

 

WagerID: 70012

RollID: (a 1 spin’s ident)

Description: Survive-5-Poker Come_1 : Spin 1

PhaseToWagerID: 70013

 

WagerID: 70012

RollID: (a 2 spin’s ident)

Description: Survive-5-Poker Come_1: Spin 2

PhaseToWagerID: 70013

 

 

etc…

 

WagerID: 70015

RollID: (a 1 spin’s ident)

Description: Survive-5-Poker Come_4 : Spin 1

PhaseToWagerID: (null)

 

 

 

Existing Module Modification: SpikerSystems_SideBet_PlugIn_Lib.bas

 

Add the linkages to the new plug-in routines:

 

Global_SpikerSystems_SideBet_PlugIn_Lib_asLinkTable(1).SBn_CS = _

SB_PI_7001_ColdStart

 

Global_SpikerSystems_SideBet_PlugIn_Lib_asLinkTable(1).SBn_WS = _

SB_PI_7001_WarmStart

 

Global_SpikerSystems_SideBet_PlugIn_Lib_asLinkTable(1).SBn_SD = _

SB_PI_7001_ShutDown

 

Global_SpikerSystems_SideBet_PlugIn_Lib_asLinkTable(1).SBn_RT = _

SB_PI_7001_RunTime

 

 

Existing Module Modification: Player_in_1_DMQ.txt

 

Enable jackpot processing and then specify all startup parameters used by the side-bet plug-in here:

 

/Jackpot_Handling_Enabled = Y

 

/Jackpot_7001_TerminateOnColdStartError = T
/Jackpot_7001_TerminateOnWarmStartError = T

/Jackpot_7001_TerminateOnProcessingError = T

/Jackpot_7001_1_StartBalance = 46,000

 

/Jackpot_7001_1_Shared = Y

 

/Jackpot_7001_1_MaxPayout = 100,000

 

/Jackpot_7001_1_RakeNumerator = 1
/Jackpot_7001_1_RakeDenominator = 1

/Jackpot_7001_1_SurrenderAllowed = F

 

/Jackpot_7001_DisplayString_1 = Survive-5-Poker
/Jackpot_7001_DisplayString_2 = By Marty Wollner
/Jackpot_7001_DisplayString_3 = SpikerSystems, L.L.C.
/Jackpot_7001_DisplayString_4 = Patent number : (Pending)

 

/Jackpot_7001_ParamString_1 = T

 

New Module Creation: SB_PI_7001_ColdStart.bas