<style>
#main {
float: left;
width: 90%;
}
nav {
display: block;
float: left;
margin-top: 28px;
width: 100%;
box-sizing: border-box;
border-left: 1px solid #ccc;
padding-left: 16px;
}
pre {
overflow-x: auto;
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
}
</style>
# Game Message Template Mapping Guide for GDM Ported Game Clients
Message template mapping is a data mapping language which involves a source data which mapped to target message place holders. The message lace holder is a handlebars template place holder which accepts JSON path of the source data. The data value can be transformed using helper functions before expressed. The overall translation process as explained below.

## Source Data
### Request
The request source data is arising from game provider’s game. If it a JSON it can used as such. If it is an xml parsers are available is the GDM adapter which can be used to convert the XML to JSON. Id the data is a proprietary format then specific parsers to be used. If game provider needs to use a specific parser for their message to be converted to JSON they can maintain them and make it available in the global scope or we can integrate it with the GDM adapter on need basis. The parsers to be configured in the game specific or provider specific template file as the below example.
```json
let requestTemplateDefinitions =
{
gameProvider:'RGS',
currentFeatureIdParam: 'CFG',
requestParsers:[
['INIT','RGSParser'],
['LOGIC', 'RGSParser'],
['ENDGAME','RGSParser']
]
}
```
In the above example RGS sends three types of messages INIT, LOGIC and ENDGAME which are xmls. So the parser is mapped to each message type. RGSParser is an XML parser which is already integrated with the GDM Adapter. It can be re-used to parse any game provider XMLmessages. This configuration is available in the game provider specific template file. So no need to repeat for every game. Once the source message is parsed it is readily available for data mapping in the target message. The below example show how RGS LOGIC request mapped to GDM bet request.
**RGS Request**\
```xml
<GameRequest type="Logic">
<Header affiliate="703" ccyCode="" channel="I" freePlay="N"
gameCodeRGI="monsterwinsagainscratch_89" gameID="20375" glsID="4" lang="en_us"
promotions="N"
sessionID="v9SmczbkdgHRktGcHwQRQJVyYtxUhkyN81Zv4WkapsH7z631rPwIrDXH/QWN+znHbOz670WrJw43R4n64+y3kQVBmsTzvNX0DbbP3nEw9jY="
userID="1000025442" userType="C" versionID="1_0">
<Stake numTickets="2" total="100" >
<AccountData>
<CurrencyMultiplier>1</CurrencyMultiplier>
</AccountData>
</GameRequest>
```
**GDM Request Mapping**
```json
bet_request_type3 = {
template:"&MSGID=BET&BPL={{_divide (getAttributeValueFromObject GameRequest.Stake '@total')
(getAttributeValueFromObject GameRequest.Stake '@numTickets')}}
&LB={{getAttributeValueFromObject GameRequest.Stake '@numTickets'}}&ABPM=0&"
}
```
GDM bet request need Bet per line (BPL) and Lines Bet (LB). RGS sends total stake and numTickets. The total stake is accessible by the json path. GameRequest.Stake element and attribute \@total. In the place holder we can use a helper function to get this value from the JSON object (JSON object is the result of the parser configured for that message type). getValueFromObject accepts a key and return value from JSON. Now the value GameRequest.Stake \@total is the total stake we need to divide it by numTickets to get BPL. So it
uses another helper function divide. So the whole place holder expression would be
```json
{{_divide (getAttributeValueFromObject GameRequest.Stake '@total')
(getAttributeValueFromObject GameRequest.Stake '@numTickets')}}
```
The handlebars expression syntax can be obtained from handlebars documentation and the expression is simple to learn.
### Response
Response arise from GDM server. The GDM messages are proprietary format. So it has its own simple parser in the GDM adapter which is configured against message types in the provider specific template. If the GDM message protocol changes from current format to something else then new parser has to be integrated and configurations to e updated. For JSON or XML no new parser is required. The current GDM parser do simple parsing where it splits the message payload by the character ‘&’ and then split by the character ‘=’. So in the resulted JSON object has the keys that the key will be the text value left hand side of = and the value will be the text at the right hand side of the =. Further parsing and transformation will be taking place in the template mapping itself. The response parser configuration present in the game provider specific template file and no need to repeat for every game.
```json
let responseTemplateDefinitions =
{
gameProvider:"RGS",
msgIdParam:"MSGID",
msgIdFromResponse:"(message)=>{return message.match(/MSGID=([A-Z ]*)/)[1]}",
responseParsers:[
["INIT","GDMParser"],
["REELSTRIP", "GDMParser"],
["BET","GDMParser"],
["FREE_GAME","GDMParser"],
["FEATURE_START","GDMParser"],
["FEATURE_PICK","GDMParser"],
["FEATURE_END","GDMParser"],
["ENDGAME","GDMParser"],
["ERROR","GDMParser"]
]
}
```
Once the source message is parsed it is readily available for data mapping in the target message. The below example show how snippet of GDM BET response mapped to RGS XML data.
**GDM Response**
```json
&MSGID=BET&B=10700&VER=1.0.00&RID=1&NRID=1&BPL=100&LB=1&TW=800&WC=0|3|0|&WS=-1;100;0;5;7;|-1;200;3;4;6;|-1;500;1;2;8;&IFG=0&MUL=10&SUB=0&GA=0&AB=10700&FRBAL=0&SID=495b091d-73e0-4cbf-8457-95a283910a3b&R=0&SSS=1;3;3;2;2;1;2;1;3&GSD=SYMS~1;2;3#ATI~0#AI~1;2;3#BGW~800#ISMW~0#EG~1&
```
From this response let us take WS
```json
WS=-1;100;0;5;7;\|-1;200;3;4;6;\|-1;500;1;2;8;\|
```
So we have three win sequence
in the response.
**RGS Response XML Mapping**
So those three win sequence in RGS response is as below as three symbol wins
```xml
<GameResult stake="100" stakePerLine="0" paylineCount="0" totalWin="800" betID="">
<ScratchCard count="1" symArr="1|3|3|2|2|1|2|1|3" symbolWinsCount="0" win="800" totalWin="800" FreeSpin="N" bonusTriggered="N">
<SymbolWin index="0" symbolId="1" symCount="3" awardIndex="1" awardTableIndex="0" positions="0|5|7" win="100"></SymbolWin>
<SymbolWin index="1" symbolId="2" symCount="3" awardIndex="2" awardTableIndex="0" positions="3|4|6" win="200"></SymbolWin>
<SymbolWin index="2" symbolId="3" symCount="3" awardIndex="3" awardTableIndex="0" positions="1|2|8" win="500"></SymbolWin>
</ScratchCard>
</GameResult>
```
Let us say we are going to get the positions for each symbol win. The logic is split WS by ‘\|’, then loop through the split results. For each split resulted string we split again by ‘;’ and remove two elements from left, then join the remain of the array by ‘\|’
The mark up + place holder as below up to a single symbol win position…
```json
{{setVariable "scatterArray" (_split WS '|')}}
{{#each scatterArray}}
{{setVariable "winSeqStrs" (_split this ';')}}
{{silent (_shift @root.winSeqStrs)}}
{{silent (_shift @root.winSeqStrs)}}
{{setVariable "winSeq" (_arrayNew)}}
{{#each @root.winSeqStrs}}
{{silent (_push @root.winSeq this)}}
{{/each}}
{{setVariable "winSeqStrs" (_arrJoin @root.winSeq '|')}}
{{#if (isEqual (_nth (_split this ';') 0) '-1')}}
```
```xml
<SymbolWin index="{{@index}}" positions="{{@root.winSeqStrs}"} symbolId="{{_nth (_split (getFromGSD @root.GSD 'SYMS') ';') @index}}" symCount="{{_arrayLength @root.winSeq}}" awardIndex="{{_nth (_split (getFromGSD @root.GSD 'AI') ';') @index}}" awardTableIndex="{{getFromGSD @root.GSD 'ATI'}}"
```
Line 1 – uses helper function \_split to split WS by ‘\|’ and store it in a variable “scatterArray” using helper function setVariable – anything set by setVariable has to be accessed by \@root.\<variable_name\>
Line 2 – Loop through the split result of WS. This will create the RGS mark up
\<SymbolWin for 3 times as the GDM response WS has 3 win sequence.
Line 3 – Split the string of the “scatterArray” again by ‘;’ and store in a
variable “winSeqStrs”
Line 4 – Shift the array to left one time using helper function \_shift
Line 5 – Shift the array to left one time using helper function \_shift
Line 6 – Declare a new array using helper function \_arrayNew
Line 7 – Loop through “winSeqStrs” and push it to the declared array in Line 6.
Line 8 – join the array by a delimiter ‘\|’ using helper function \_arrJoin.
Line 9 – split the “scatterArray” by ‘;’ and take 0th index value is equal to -1 i.e it is a symbol win or scatter win (_split this ';') – Split scatter array by ‘;’ (_nth (_split this ';') 0) - Split scatter array by ‘;’ and take 0th value. Sub expressions enclosed by parenthesis and arguments are separated by space. So the helper function \_nth takes an array and index and return the index value from that array. In the above example the array is a subexpression (_split this ';') and then the index is 0 separated by a space.
Line 10 – RGS XML markup, in that positions ={{\@root.winSeqStrs}} which we stored in Line 8.
**Note:** all these can be done as positions ={{getSymPositions WS}} by having a getSymPositons helper function encapsulating all the above logic. Currently we give only basic helper functions. Higher level functions to be evolved by the games dev and if it found the logic to be repeated many times we can incorporate the helper function in the adapter.
For readability the mark up and template literals can be separately defined as below
```javascript
let initialization = '{{setVariable \'winSeq\' (_split WS \';\')}}{{_shift @root.winSeq}}{{_shift @root.winSeq}}'
let callingNumbers = '{{_array2Str (shuffleArr (addMoreUniqueRandomToArr (getValuesByIndexArray (_split SSS \';\') @root.winSeq) (_split SSS \';\') 1 75 35)) \'|\'}}'
let boardNumbers = '{{strReplaceAll SSS \';\' \'|\'}}'
let ai ='{{getFromGSD GSD \'AI\'}}'
let pati ='{{getFromGSD GSD \'PATI\'}}'
let template =`${initialization}<BoardNumbers>${boardNumbers}</BoardNumbers><CallingNumbers>${callingNumbers}</CallingNumbers><WinningPattern awardIndex="${ai}" index="${pati}"/>`
gamespecificgameresult_ballroombingo_85 = {
template:template
}
```
## Template Organization Structure
Templates are chunk of target message with markup plus template place holders. So for target message it has a common part and game specific part. So the template files are split in to and distributed in two places.
1. A game provider specific template file. It present in the adapter gdm_translator/templates folder. This file has commonly defined template parts. Message state machine. Note the message state machine is driven by both GDM params and game provider message specific params. So it is present n the game provider template file. For new provider it can be inherited or newly created. The convention for this file name are a) \<gameprovider name lowercase\>Requestmessagetemplate.js and b) \<gameprovider name lowercase\>Responsemessagetemplate.js. When more games get ported more new common parts may be get moved in this file.
2. Game specific template file. It is present at the root folder of the game with a naming convention msg_template.js. This file contains templates of game specific nature and a template mapping for the request and response. Template mapping is a JSON structure aggregate common and game specific templates in to a complete target message structure. Template mapping is explained more in its own section.
Templates are organized in to parts. Main template and partials. Partials are inner/ sub templates. Each message has a main template and one or many sub/ partial templates. Each template part is a JSON object which has a key “template” and holds the message markup and place holders. The following example explain it.

**On Game Load**

'
**On Game Message**

Below is an example of the common part and the game specific part.
```xml
<GameResponse type="Logic">
<Header sessionID="495b091d-73e0-4cbf-8457-95a283910a3b" ccyCode="SEK" deciSep="." thousandSep="," lang="en_US" gameID="ballroombingo" versionID="1.0.00" fullVersionID="1.0.00" isRecovering="N"/>
<AccountData>
<CurrencyMultiplier></CurrencyMultiplier>
<Payload>
<PayloadItem request="wager">
<Payload>
<map-item>
<key>OPENBET_CONTAINER_PAYLOAD</key>
<value>CASH=17750;FREEBET=0;</value>
</map-item>
</Payload>
</PayloadItem>
<PayloadItem request="outcome">
<Payload>
<map-item>
<key>OPENBET_CONTAINER_PAYLOAD</key>
<value>CASH=17750;FREEBET=0;</value>
</map-item>
</Payload>
</PayloadItem>
</Payload>
</AccountData>
<Balances>
<Balance name="CASH_BALANCE" value="17750"/>
<Balance name="BONUS_BALANCE" value="0"/>
</Balances>
<!--GAME SPECIFIC CONTENT-->
<GameResult stake="100" stakePerLine="0" paylineCount="0" totalWin="5000" betID="">
<BoardNumbers>1|26|31|57|67|14|16|36|48|73|6|19|-1|56|62|8|17|33|49|64|12|23|45|55|66</BoardNumbers> <CallingNumbers>69|62|15|23|48|56|63|74|21|31|54|26|60|47|1|34|61|6|64|48|66|39|17|57|35|10|28|73|45|46|73|38|41|65|22|6|17|12|14|52|26|23|55|68|67|31|19|50|32|25|9</CallingNumbers>
<WinningPattern awardIndex="3" index="14"/>
</GameResult>
<!--GAME SPECIFIC CONTENT ENDS-->
<GameWinInfo BGWin="0" FGWin="0" totalWagerWin="5000" isMaxWin="N" isEndGame="1" />
</GameResponse>
```
The green highlighted part is common for most of the RGS game response. The yellow part vary greatly for game to game. So the message is divided in to multiple template part and organized together in to one complete message. The mapping present in the game specific template file, so game can aggregate the template parts in whichever way it wants.
Below is an example of the template distribution of the above message.
### Bet Response Template Mapping - Example
```json
BET: {
main: game_response_template,
partials: {gameresult:gameresult_type4,gamespecificgameresult:gamespecificgameresult_ballroombingo_85},
cacheResponseOnEnd:0
}
```
From the above mapping it uses 3 template parts. 1 main and two partials gameresult and gamespecificgameresult. The partial template names/ keys can’t be changed because that is the key the main template looks for. In the above example main: game_response_template and gameresult:gameresult_type4 both present in the game provider specific template with GDM adapter. The partial template gamespecificgameresult:gamespecificgameresult_ballroombingo_85 present in the game specific template file which is deployed with the game.
#### Templates with Adapter:
```json
game_response_template = {
template:'{{#if (isEqual MSGID 'BET')}}{{setVariable "betResponseObj" @root}}{{else}}{{setVariable "betResponseObj" (getAttributeValueFromObject @root 0)}}{{/if}}
<GameResponse type="Logic">
<Header sessionID="{{SID}}" ccyCode="{{currencyCode}}" deciSep="{{decimalSeparator}}" thousandSep="{{thousandseparator}}" lang="{{locale}}" gameID="{{gameName}}" versionID="{{VER}}" fullVersionID="{{VER}}" isRecovering="{{convertBool2YNString R}}"/>
<AccountData>
<CurrencyMultiplier>{{currencyMultiplier}}</CurrencyMultiplier>
<Payload>
<PayloadItem request="wager">
<Payload>
<map-item>
<key>OPENBET_CONTAINER_PAYLOAD</key>
<value>CASH={{B}};FREEBET={{FRBAL}};</value>
</map-item>
</Payload>
</PayloadItem>
<PayloadItem request="outcome">
<Payload>
<map-item>
<key>OPENBET_CONTAINER_PAYLOAD</key>
<value>CASH={{B}};FREEBET={{FRBAL}};</value>
</map-item>
</Payload>
</PayloadItem>
</Payload>
</AccountData>
<Balances>
<Balance name="CASH_BALANCE" value="{{B}}"/>
<Balance name="BONUS_BALANCE" value="{{FRBAL}}"/>
</Balances>
{{> (lookupTemplate templateList 'gameresult') }}
{{> (lookupTemplate templateList 'gameresult1') }}
{{> (lookupTemplate templateList 'gameresult2') }}
{{> (lookupTemplate templateList 'gameresult3') }}
{{> (lookupTemplate templateList 'gameresult4') }}
</GameResponse>'
}
```
The above template looks for a partial template named “gameresult”. So in the template mapping we mapped “gameresult_type4” against the key “gameresult”. So it incorporate the gameresult_type4 template as a partial template.
```json
gameresult_type4 = {
template:'{{#if (_not (isNull BPL))}}{{#if (_not (isNull LB))}}{{setVariable 'totalStake' (_multiply BPL LB)}}
{{else}}{{setVariable 'totalStake' -1}}{{/if}}{{/if}}
<GameResult stake="{{@root.totalStake}}" stakePerLine="0" paylineCount="0" totalWin="{{TW}}" betID="">
{{> (lookupTemplate templateList 'gamespecificgameresult') }}{{>
(lookupTemplate templateList 'gamespecificgameresult2') }}
{{#if (isGreaterThan (convertStr2Int TFG) 0)}}{{> (lookupTemplate templateList 'freegame') }}{{/if}}
</GameResult>
<GameWinInfo BGWin="{{getFromGSD GSD 'BGW'}}" FGWin="{{nullToZero FGTW}}" totalWagerWin="{{TW}}" isMaxWin="{{convertBool2YNString (getFromGSD GSD 'ISMW')}}" isEndGame="{{EG}}" />
{{> (lookupTemplate templateList 'basegamerecovery')}}'
}
```
#### Template with Game:
The above template in the adapter looks for a another partial template named ”gamespecificgameresult”. In the mapping we mapped gamespecificgameresult_ballroombingo_85 against ”gamespecificgameresult”. So it incorporate the game specific nature of the template from the game template file. The game specific template as below for ballroombingo.
```json
gamespecificgameresult_ballroombingo_85 = {
template:'{{setVariable 'winSeq' (_split WS ';')}}{{_shift @root.winSeq}}{{_shift @root.winSeq}}
<BoardNumbers>{{strReplaceAll SSS ';' '|'}}</BoardNumbers>
<CallingNumbers>{{_array2Str (shuffleArr (addMoreUniqueRandomToArr (getValuesByIndexArray (_split SSS ';') @root.winSeq) (_split SSS ';') 1 75 35)) '|'}}</CallingNumbers>
<WinningPattern awardIndex="{{getFromGSD GSD 'AI'}}" index="{{getFromGSD GSD 'PATI'}}"/>'
}
```
So the complete message is constructed by multiple template parts distributed with the adapter and game specific template file. The mapping give freedom of mix and match any combination of those templates.
If the templates In the GDM adapter is re-defined in the game specific template file then the template in the game specific file will be used and the one in the adapter will be ignored.
#### Alternate Templates
In the below example both BET and FREEGAME has same templates.
```json
BET: {
main: game_response_template,
partials: {gameresult:gameresult_type4,
gamespecificgameresult:gamespecificgameresult_goldfishscratch_86},
cacheResponseOnEnd:1
},
FREE_GAME: {
main: game_response_template,
partials: {gameresult:gameresult_type4,
gamespecificgameresult:gamespecificgameresult_goldfishscratch_86},
cacheResponseOnEnd:1
},
```
In case needs to use a different template for “gameresult” then handle bars doesn’t accept two templates in the same partial template name. So alternate template provisions upto 4 alternates available. So instead of gameresult, we can use gameresult2 for Freegame. So the main template look first for “gameresult” and if not available it take “gameresult2”. If both available then it express both. The below example shows using alternate template for free game.
```json
BET: {
main: game_response_template,
partials: {gameresult:gameresult_type4,
gamespecificgameresult:gamespecificgameresult_goldfishscratch_86},
cacheResponseOnEnd:1
},
FREE_GAME: {
main: game_response_template,
partials: {gameresult2:gameresult_type_freegame,
gamespecificgameresult:gamespecificgameresult_goldfishscratch_86},
cacheResponseOnEnd:1
},
```
#### Injects
```json
let responseTemplateDefinitions =
{
Injects: ‘../goldfish/msgtemplate.js’
```
The injects section in the Template Definition object can load one or more javascript files. For example redhot10s is a clone, so it doesn’t needs to have its own template file, but load template file from another location, then just to define a inject.
## Template Mapping
Template mapping is aggregating partial templates and directing selected behavior of the message service. For a game two sets of Template mapping is necessary 1) Request Template mapping and 2) Response Template mapping. Common templates are present and will be moved to the adapter while game specific templates present in the game specific template file as explained in the above sections.
Template mapping is a key value pair JSON where the keys are defined and not to be changed. We have two sets of template mapping, one for the request message types and another for the response. Template mapping should be present in the game specific template file (msg_template.js) under the game’s root folder. Below are examples of templating mapping which are more or less self-explainable as it is discussed above.
```json
requestTemplateMap = {
globalpartials:[],
gameProvider:'RGS',
INIT: {
main: init_request_template,
partials: {}
},
REELSTRIP: {
main: reelstrip_request_template,
partials: {}
},
BET: {
main: bet_request_type1,
partials: {}
},
FREE_GAME: {
main: freegame_request_template,
partials: {}
},
FEATURE_START: {
main: featurestart_request_template,
partials: {}
},
FEATURE_PICK: {
main: featurepick_request_template,
partials: {}
},
FEATURE_END: {
main: featureend_request_template,
partials: {}
},
ENDGAME: {
main: endgame_request_template,
partials: {}
}
};
responseTemplateMap ={
globalpartials:[],
gameProvider:'RGS',
INIT: {
main: init_response_template,
partials: {betdefinitions:betdefinitions_type2, awardsinfo:awardsinfo_goldfishscratch_86,
rtpinfo:rtpinfo_type3}
},
REELSTRIP: {
main: init_response_template,
partials: {betdefinitions:betdefinitions_type2, awardsinfo:awardsinfo_goldfishscratch_86,
rtpinfo:rtpinfo_type3}
},
BET: {
main: game_response_template,
partials: {gameresult:gameresult_type4,
gamespecificgameresult:gamespecificgameresult_goldfishscratch_86},
cacheResponseOnEnd:1
},
FREE_GAME: {
main: game_response_template,
partials: {gameresult:gameresult_type4,
gamespecificgameresult:gamespecificgameresult_goldfishscratch_86},
cacheResponseOnEnd:1
},
FEATURE_START: {
main: featurestart_response_template,
partials: {}
}
,
FEATURE_PICK: {
main: featurepick_response_template,
partials: {}
}
,
FEATURE_END: {
main: featureend_response_template,
partials: {}
},
ENDGAME: {
main: endgame_response_template,
partials: {}
},
ERROR: {
main: errorResponseTemplate,
partials: {}
}
};
```
Some of the message type has a flag “cacheResponseOnEnd” if that is set \> 1 then for that number of times when the game make request the cached response will be served and no call with be made to server. A use case may be send complete scratch response once and when client game looks for it multiple times then it can be served from memory. The number of times the response served from cache is available for the template through the key “responseServed”. In the above example it set to 1 because goldfish game send the same request two times and get the same response i.e one time when the spin button is clicked and second time when the reveal all button clicked.
## Template Helpers
Within the handlebars template space only registered methods are available. Not all javascript methods available. So we register many utility methods to be used with the templates. The list is TBD soon.’
All lodash methods available as helpers. Lodash methods are accessed by \_. (underscore + dot). But here the same lodash function to be accessed without the . (dot). For example \_.nth of lodash to be accessed as \_nth.
(_nth (_split this ';') 0) '-1') here \_nth is a lodash function. If any other good helper libraries required we can take them in with the adapter. Lodash documentation available at <https://lodash.com/docs/4.17.15> (Though this documentation not very good, some of the functions not behave as described in the document. So if decided to use lodash functions verify it separately before using. However many functions work well)
We also have custom helper functions. The list will be updated soon. We will evelove with more helper functions which are common for many games.
Game can register its own game specific helper functions in the game specific templates. For example
```javascript
Handlebars.registerHelper('fnGameSpecific', ()=>{return 'Hello world')
```
First argument is a function name and second is the pointer to that function.