Skip to content
mirkoperillo edited this page Apr 23, 2015 · 6 revisions

This section explores in detail our demo-game, which is packaged with the engine. Visit the administration web console to have a look to following explanations.

Mobility Game

The game target the mobility domain, where the objective is to incentivate the users of the mobility information application on planning the trips with the app focusing on the promoted transport means and modalities.

Game Concepts

The game defined three point concepts

  • green leaves, corresponding to the “green” movements in the city
  • health, corresponding to healthier transport means (bike, walk)
  • p+r (park-and-ride, where the external parkings and bike sharing is promoted.

Also, four badge collections concepts (green leaves, health, p+r, special) are introduced.The collections will be used to collect badges earned on the three point types plus a special one to collect special badges.

Game Actions

Moreover game has an action: save_itinerary.

Game Rules

A set of rules is specified to control the different type of points and to trigger badges and classifiations. For example, the following rule is used to state that the user will gain a “10-green-point” badge when he gains first 10 green points:

More specifically, this rule is executed when player has collected more than 10 points of type green leaves and he hasn’t yet earned the badge 10-point-green. Other two lines in condition part are used only to bound values in variables. When condition is satisfied a log message will be written, the badge 10-point-green is inserted in relative badge collections, a notification will be sent to the system to inform that user has gained a new badge, and the badge collection object will be updated.

rule "10 point green badge"
salience -1000
when
    PointConcept(name == 'green leaves', score \>= 10.0)
    $bc : BadgeCollectionConcept(name == "green leaves", badgeEarned not contains '10-point-green')
    Game( $gameId: id)
    Player( $playerId : id)
then
    log("apply \\'10-point-green badge\\'");
    $bc.getBadgeEarned().add('10-point-green');
    insert( new BadgeNotification($gameId,$playerId,'10-point-green'));
    update( $bc );
end

Game Classification Tasks

Our demo game defined six classification tasks. These tasks are used to calculated the week classifications on green leaves, health and p+r points and the final classifications.

In particular a week classification, green leaves for example, rewards the player with better score on green leaves points of the week. The same thing is done for health and p+r points.

A final classification rewards the better 3 players on single point type.

Game Execution

To simulate the game execution, the engine REST API may be exploited. The API defines the methods for triggering user action, reading the user state, and reading the user notifications. Detailed explanation of the engine REST API interface is [here](REST API engine).

NOTE: to access all the API methods the game ID parameter should be provided. Game ID is generated by the platform and is shown in the game “card” in the console. Use that value to perform the requests.

NOTE: all the API methods defined below are relative to the engine endpoint. In case of the local installation, the http://localhost:8080/gamification should be used. When the SaaS version is used, the following endpoint is due: https://dev.smartcommunitylab.it/gamification.

Initial State

Initially, the user state is empty. To read the user state the following request may be performed (here and later we will use the value “1” to represent the user ID):

GET /gengine</span>/state/<gameId>/1
{  
   "playerId":"1",
   "gameId":"<gameId>",
   "state":{  
      "BadgeCollectionConcept":[  
         {  "name":"p+r","badgeEarned":[] },
         {  "name":"green leaves", "badgeEarned":[]},
         {  "name":"special", "badgeEarned":[] },
         {  "name":"health", "badgeEarned":[] }
      ],
      "PointConcept":[  
         {  "name":"p+r", "score":0.0 },
         {  "name":"health", "score":0.0 },
         {  "name":"green leaves", "score":0.0 }
      ]
   }
}

Triggering User Action

In order to reflect the user activities (i.e., planning and performing the trips), the corresponding actions should be triggered. For example, to reflect the fact that the user has performed a trip of 1 km in bicycle:

POST /gengine/execute
{
    "gameId": "<gameId>",
    "userId": "1",
    "actionId": "save_itinerary",
    "data": {
        "bikeDistance": 1.0
    }
}

In the JSON request body we can see the fields used during a engine execution call:

  • gameId identifies the game
  • actionId activates a set of game rules
  • userId identifies the player target of execution
  • data is the set of data about user on which execute the action

Calling the player state again, we will see

  "playerId":"1",
   "gameId":"<gameId>",
   "state":{  
      "BadgeCollectionConcept":[  
         {  "name":"p+r","badgeEarned":[] },
         {  "name":"green leaves", "badgeEarned":[]},
         {  "name":"special", "badgeEarned":["zero-impact"] },
         {  "name":"health", "badgeEarned":[] }
      ],
      "PointConcept":[  
         {  "name":"p+r", "score":0.0 },
         {  "name":"health", "score":3.0 },
         {  "name":"green leaves", "score":5.0 }
      ]
   }
}

So player 1 gained 5 green leaves points, 3 health points and “zero-impact” badge in special badge collection.

How did he gain these points ? Let’s analyze an extract of greenPoints, constants, healthPoints and specialBadges rules, that are the rules involved in this.

rule "update green points"
when
    InputData( $bike : data["bikeDistance"], $walk : data["walkDistance"], $bus : data["busDistance"],$train : data["trainDistance"])
    $pc : PointConcept(name == "green leaves")
then
    log("apply \'update green points\'");
    Double bike = $bike != null ? (Double) $bike : 0;
    Double walk = $walk != null ? (Double) $walk : 0;
    Double bus = $bus != null ? (Double) $bus : 0;
    Double train = $train != null ? (Double) $train : 0;

    Long dist1 = Math.round(bike + walk);
    Long dist2 = Math.round(bus + train);
    
    $pc.setScore($pc.getScore() + green_walk_bike_points * dist1 +
                 green_bus_train_points * dist2);
    update($pc);
end

In greenPoints rule when a data bikeDistance is found, green score of player 1 is incremented of green_walk_bike_points * distance points (green_walk_bike_points is a constant and its value is in rule constants).

# GREEN BONUS
green_walk_bike_points=5

So for 1 kilometer in bicycle player 1 gained 5 points.

The same thing happened for health points assignment.

rule "update health points"
when
    InputData( $bike : data["bikeDistance"], $walk : data["walkDistance"])
    $pc : PointConcept(name == "health")
then
    log("apply \'update health points\'");
    Double bike = $bike != null ? (Double) $bike : 0;
    Double walk = $walk != null ? (Double) $walk : 0;

    Long dist1 = Math.round(walk);
    Long dist2 = Math.round(bike);
    
    $pc.setScore($pc.getScore() + health_walk_points * dist1 + 
                    health_bike_points * dist2);
    update($pc);
end
# HEALTH BONUS
health_walk_points=10
health_bike_points=3

Let’s see how zero-impact badge is assigned in specialBadges rules

rule "zero impact badge"
    salience -1000
when
       InputData((data['walkDistance'] != null || data['bikeDistance'] != null) 
      && ((data['busDistance'] == null || data['busDistance'] == 0) 
      &&  (data['carDistance'] == null || data['carDistance'] == 0)))
      
     $bc : BadgeCollectionConcept(name == "special", 
                                  badgeEarned not contains 'zero-impact')
     Game( $gameId: id)
     Player( $playerId : id)
then
    log("apply \'zero-impact badge\'");
    $bc.getBadgeEarned().add('zero-impact');
    update( $bc );
    insert( new BadgeNotification($gameId,$playerId,'zero-impact'));
end

In detail $bc.getBadgeEarned().add('zero-impact'); added badge to player 1 special badges, insert( new BadgeNotification($gameId,$playerId,'zero-impact')); send a notification in the system.

To see the notification, the notification REST API may be used. For example:

GET /gengine/notification/<gameId>/1

[
   {
"gameId":"demo-game",
"playerId":"1",
"timestamp":1427804153766,
"badge":"zero-impact"
   }
]

Clone this wiki locally