GT - COMPETITION - English

In this tutorial we will learn how to configure the competitions technique in Funifier platform. At the end of this tutorial you will have learned how to create a competition, register a player in a competition, invite players to a competition, present partial and final results of a competition and how to determine the final winners.

THE COMPETITION TECHNIQUE

Competition is a dispute between two or more players that happens within a set period to evaluate which players achieve the best results. A competition must stipulate the maximum number of participants as well as the maximum number of winners. In addition the criterion of classification of the competitors must be defined. Players must register in the competition in order to participate and be considered in the determination of the winners. As a reward, the winners of a competition win the title of winner of the competition with their respective position in the standings, and can also win other prizes such as points. Competition involves various game techniques such as leaderboard, status points, quest lists, antecipade parade, progress bar, crowning, instant feedback, monitor attachment, envy cloud, group quest, appointment dynamics, countdown timer, moats, suspenseful limit, evanescent opportunity.

CONFIGURING THE COMPETITION TECHNIQUE

To create a new competition using Funifier Rest API, use the endpoint /v3/competition. To create the competition you must define some very important information such as the title of the competition, the period of the competition, the maximum number of competitors and the maximum number of winners, as well as the operation to calculate the winners and eventual rewards for the winners. See the example below:

POST http://service2.funifier.com/v3/competition

{
 "title" : "Competition",
 "description" : "Competition Description",
 "image" : "http://image.com/holiday.png",
 "period" : {"expression": "2018-07-30T00:00:00-03:00;+1M+"},
 "maxWinners" : 3,
 "maxPlayers" : -1,
 "operation" : {"type" : 1, "item" : "sell"},
 "requires" : [ ],
 "rewards" : [
   {"total" : 1, "type" : 0, "item" : "point", "extra" : { }},
   {"total" : 10, "type" : 0, "item" : "point", "extra" : { "position" : 1 }}
 ],
 "notifications" : [
   {"event" : 0, "type" : 0, "scope" : 0, "content" : "Parabéns {{player.name}} você ganhou a competição"}
 ],
 "active" : true,
 "autoExecute" : true,
 "extra" : { "holiday" : "Carnival" },
 "_id" : "my_competition"
}

FIELD

EXAMPLE

DESCRIPTION

title

Competition

The title, description and image fields are the friendly way the competition will be presented to players.

period.expression

2018-01-30T00:00:00-03:00;+1M+

It represents the start and finish dates to calculate the winners of the competition. The two dates are separated by (;) and accept the international date format with timezone (2018-01-30T00:00:00-03:00) and Funifier date expression (+1M+). In this example the competition is scheduled to start at zero time on the day 2018-01-30 and end on the last hour of the last day of the following month (+1M+).

maxWinners

3

Maximum number of winners allowed for the competition. In general it is a positive number, for example 3 winners. But you can define that all registered competitors are winners, so in this case you can enter the number -1 for this.

maxPlayers

-1

Maximum number of competitors accepted in the competition. In general it is a positive number, for example 100 participants. But you can define that the competition has unlimited participants, so in this case you can use the number -1.

operation

Players with more sales

{"type" : 1, "item" : "sell"}

Determine how the winners will be calculated. For example, the winners are the players with the highest number of sales actions registered in the gamification. For this you can set the type of operation (type: 1) to count the total actions. The item that will be posted (item: sell).

requires

[

{"total": 1, "type": 3, "item": "master", "operation" : 0},

{"total": 1, "type": 0, "item": "coin", "operation" : 1},

]

List the requirements to participate in the competition. These requirements are checked at the time the player registers to join the competition. The requirements may be for verification only and may also be for debiting the player's balance. Example, check if the player is at master level and debit a coin to enter the competition.

rewards

[

{"total" : 1, "type" : 0, "item" : "point", "extra" : { }},

{"total" : 10, "type" : 0, "item" : "point", "extra" : { "position" : 1 }}

]

List of rewards of the competition, each reward must inform the total, type and item. Example: 1 point xp for all winners, would be represented as {"total": 1, "type": 0, "item": "xp"}. You can also set rewards for the winner to stay in a specific position, Example: 10 gold points for the winner in the first position, would be represented as {"total": 10, "type": 0, "item": "gold" , "extra": {"position": 1}}

notifications

[
{"event" : 0, "type" : 0, "scope" : 0, "content" : "Parabéns {{player.name}} você ganhou a competição"}
]

List of messages that will be triggered when a competition-related event occurs. For example, when a player wins a competition, they present a private message saying "Congratulations, you won the competition".

active

true

Indicates whether the competition is active or not. Players can not enter an inactive competition.

autoExecute

true

Determines whether the funifier should automatically calculate the winners of a competition or not. If true, the funifier will perform this operation at the end date and time of the competition, calculated from the criteria defined in the period expression.

After registering the competition through Rest Api the Funifier will calculate some additional information of the competition, the following data are automatically generated by the system.

FIELD

DESCRIPTION

start

Starting date of the competition. This is the start date from which the results calculation data will be considered.

end

End date of the competition. This is the final date to be considered in determining the winners' results.

created

Creation date of the competition in the system.

updated

Date the competition was last updated on the system.

OPERATION: WINNERS CALCULATION CRITERIA

There are several possible operations to determine the winners of a competition. The operation field has the following fields internally:

FIELD

DESCRIPTION

EXAMPLES

type

Defines the type of operation that will be performed, operations can be 1 (count total action logs), 2 (add a specific attribute of action logs), 3 (sum total achievements) or 4 (average with one specific attribute of action logs)

type:1

achievement_type

This field is used exclusively when the type equals 3. It defines the type of achievement that should be considered. The types of achievements can be 0 (points), 1 (challenge), 2 (items in a catalog), 3 (level).

achievement_type:0

item

Determines the item to be posted. If the type is 1, 2 or 4 then the id of the action that should be considered in the calculation must be informed. If the type is 3 then the id of the achievement that is being calculated according to the achievement_type must be given.

item:”sell”

attribute

This field is used only when the type equals 2 or 4. It indicates the attribute within the attributes field of the action log that should be counted.

attribute:”price”

filters

Filters can be applied to operations related to action logs 1, 2, and 4. In the filter you can enter define only actions where the attributes have a certain value. For example, suppose you want to filter only the action logs where the attributes.product field is equal to "book", so you can define a filter with the structure on the side.

"filters": [{"param":"product", "operator":1, "value":"book"}]

Here are some examples of object operations structures below:

DESCRIPTION

EXAMPLE

Sum all values from the "attributes.price" field of all "sell" action logs.

"operation": {

        "type": 2,

        "item": "sell",

        "attribute": "price",

        "sort": -1

}

Find the total "sell" action logs with the "attributes.product" field equal to "book".

"operation": {
   "type": 1,
   "sort": -1,
   "item": "sell",
   "filters": [
           {"param":"product", "operator":1, "value":"book"}
   ]
 }

Find the average value of sales of books, that is, average the "attributes.price" field of the "sell" action logs where the "attributes.product" field is equal to "book".

"operation": {

        "type": 4,

        "item": "sell",

        "attribute": "price",

        "sort": -1,

        "filters": [

                {"param":"product", "operator":1, "value":"book"}

        ]

}

Find out the total "coin" points that each player registered in the competition has won.

"operation": {

        "type": 3,

        "item": "coin",

        "achievement_type": 0,

        "sort": -1

}

REGISTERING A PLAYER IN A COMPETITION

For a player to enter a competition there are some prerequisites, the competition must be active, the player must meet the requirements determined in the competition and he also need to register his intention to participate through the endpoint /v3/competition/join. See below how to register the player in a competition.

POST http://service2.funifier.com/v3/competition/join

{
 "player" : "tom",
 "competition" : "my_competition"
}

If the player does not meet the competition requirements, the system will return a message informing the identified restriction.

{
   "restrictions": [
       "insufficient_requirements"
   ],
   "status": "UNAUTHORIZED"
}

If the player meets all requirements the system will present a message of success.

{

    "join": {

        "competition": "my_duel",

        "player": "tom",

        "created": 1535418242948,

        "_id": "5b849f82421c4812231730ec"

    },

    "status": "OK"

}

REMOVING A PLAYER FROM A COMPETITION

A player may leave a competition at any time. But when leaving the competition there is no reversal of the debits made at the time of entry. See the example below of how to leave a competition using the rest api.

DELETE http://service2.funifier.com/v3/competition/join

{
 "player" : "tom",
 "competition" : "my_competition"
}

FINDING PLAYERS REGISTERED IN A COMPETITION

To find all players who have registered into a competition you can use the endpoint /v3/competition/join and make the filters as needed. Below is the query to bring all the records of a competition:

GET http://service2.funifier.com/v3/competition/join?competition=my_competition

As a result you should get a list of joins made, with player and competition entered, as well as the date the player entered the competition:

[
   {
       "competition": "my_competition",
       "player": "tom",
       "created": 1535396257310,
       "_id": "5b8449a1421c480fa33fbff9"
   },
   {
       "competition": "my_competition",
       "player": "jerry",
       "created": 1535396983022,
       "_id": "5b844c77421c480fa33fbffa"
   },
   {
       "competition": "my_competition",
       "player": "ben",
       "created": 1535397026124,
       "_id": "5b844ca2421c480fa33fbffb"
   },
   {
       "competition": "my_competition",
       "player": "ric",
       "created": 1535397137635,
       "_id": "5b844d11421c480fa33fbffc"
   }
]

PRESENTING PARTIAL RESULT OF A COMPETITION

To view the current leaders of a competition you can use the endpoint /v3/competition/leader. The leaders are verified in real time, and only the results within the start and end dates of the competition are considered for those players who have join the competition. However, if there is no player join the competition, then Funifier understands that it should consider all players. See below:

GET http://service2.funifier.com/v3/competition/leader?id=my_competition

As a result you should receive a list of leaders, with id, position, and total:

[
   {"player": "tom", "total": 3, "position": 1},
   {"player": "jerry", "total": 2, "position": 2},
   {"player": "ben", "total": 1, "position": 3},
   {"player": "ric", "total": 1, "position": 4}
]

PRESENTING PARTIAL RESULT OF A COMPETITION WITH AN AGGREGATION

If you need to retrieve additional information from the leaders of a competition you can use the aggregation feature. For example, you need to retrieve the leaders name and photo, this information does not appear by default in the query leader of a competition, but can be included using the endpoint competition / leader / aggregate. See below for an example of how to include the player's name on the competition leader list.

POST http://service2.funifier.com/v3/competition/leader/aggregate?id=sell_book_duel

Content-Type: application/json
Authorization: Basic NWI5MThhZmJkOTZjN...
[
        {"$lookup":{"from": "player", "localField":"player", "foreignField":"_id", "as": "p"}},
        {"$unwind":"$p" },
        {"$project":{ "name":"$p.name", "player":1, "total":1, "position":1 }},
        {"$sort":{ "position":-1 }}
]

EXECUTING THE FINAL RESULT OF A COMPETITION

If the competition has been configured not to execute automatically, you can calculate the final result of the competition using the endpoint /v3/competition/{id}/execute. This will determine who the winners are, distribute any rewards to each of the winners, trigger the notifications, record the achievement of the competition and run the triggers linked to the competition. This operation can be performed only once per competition. After that, funifier will record the date of calculation of the result in the competition object. See below the results of the competition.

GET http://service2.funifier.com/v3/competition/{id}/execute

As a result you should get the list of achievers and the configuration of the competition that was executed.

{
   "winners": [
       {
           "player": "tom",
           "total": 1,
           "type": 9,
           "item": "my_competition",
           "time": 1535413666675,
           "extra": {
               "total": 3,
               "position": 1
           },
           "_id": "5b848da2421c480d18cbf908"
       },
       {
           "player": "jerry",
           "total": 1,
           "type": 9,
           "item": "my_competition",
           "time": 1535413666892,
           "extra": {
               "total": 2,
               "position": 2
           },
           "_id": "5b848da2421c480d18cbf90b"
       },
       {
           "player": "ben",
           "total": 1,
           "type": 9,
           "item": "my_competition",
           "time": 1535413666939,
           "extra": {
               "total": 1,
               "position": 3
           },
           "_id": "5b848da2421c480d18cbf90e"
       }
   ],
   "competition": {
       "title": "Competition",
       "description": "Competition Description",
       "image": "http://image.com/holiday.png",
       "period" : {"expression": "2018-07-30T00:00:00-03:00;+1M+"},
       "maxWinners": 3,
       "maxPlayers": -1,
       "operation": {
           "type": 1,
           "achievement_type": 0,
           "item": "sell",
           "sort": 0,
           "sub": false
       },
       "requires": [],
       "rewards": [
           {
               "total": 1,
               "type": 0,
               "item": "point",
               "operation": 0,
               "extra": {}
           },
           {
               "total": 10,
               "type": 0,
               "item": "point",
               "operation": 0,
               "extra": {
                   "position": 1
               }
           }
       ],
       "notifications": [
           {
               "event": 0,
               "type": 0,
               "scope": 0,
               "content": "Parabéns {{player.name}} você ganhou a competição"
           }
       ],
       "active": true,
       "autoExecute": true,
       "extra": {
           "holiday": "Carnival"
       },
       "created": 1535392754528,
       "updated": 1535395241104,
       "executed": 1535413667011,
       "_id": "my_competition"
   }
}

EXECUTING TRIGGERS IN COMPETITIONS

Triggers can be executed at diferent moments during a competition, when creating a competition, when a player wins a competition, when a player join a competition, and when the player accepts the invitation to participate in a competition. Below is the table of these various events related to competitions that accept triggers.

ENTITY

EVENTS

DESCRIPTION

competition

before_create, after_create

When a new competition is being created. The entity passed in the trigger script is a Competition.

competition

before_win, after_win

When a player wins a competition. The entity passed in the trigger script is an Achievement.

competition_join

before_create, after_create

When a player joins a competition. The entity passed in the trigger script is a CompetitionJoin.

On Invite (mensagem)

On Accept Invite or Reject an Invite

DELETE A COMPETITION

You can delete a competition using the endpoint /v3/competition. When you delete a competition, all data linked to the competition will be removed, such as joins, achievements and notifications. See the example of how to exclude a competition.

DELETE http://service2.funifier.com/v3/competition/my_competition

EXAMPLE: CREATING A DUEL WITH RANDOM OPPONENTS

With competition technique you can create a duel, competition between two people. Suppose you want to make a duel between two random opponents and the winner will be the one who has the highest sales result. To make a duel we will start by creating a competition with a maximum of two competitors and only one winner, where the scoring operation consists of the sum of the "price" attributes of the "sell" actions that each participant made. See below the example of setting up our sales duel for random players.

POST http://service2.funifier.com/v3/competition

{
 "title" : "Duel",
 "description" : "Duel among the best sellers",
 "image" : "http://image.com/duel.png",
 "period" : {"expression": "2018-07-30T00:00:00-03:00;+1M+"},
 "maxWinners" : 1,
 "maxPlayers" : 2,
 "operation": {
   "type": 2,
   "achievement_type": 0,
   "item": "sell",
   "attribute": "price",
   "sort": -1
 },
 "requires" : [ ],
 "rewards" : [
   {"total" : 10, "type" : 0, "item" : "point", "operation" : 0, "extra" : { "position" : 1 }}
 ],
 "notifications" : [
   {"event" : 0, "type" : 0, "scope" : 0, "content" : "Congratulations {{player.name}} you won the sales duel"}
 ],
 "active" : true,
 "autoExecute" : true,
 "extra" : {},
 "_id" : "my_duel"
}

After creating your competition, we’ll let the system choose two opponents randomly. For this we will make a request in the endpoint "join" informing the key word "FUNIFIER_RANDOM_PLAYER" in place of the player id. See below how to join a random player.

POST http://service2.funifier.com/v3/competition/join

{
 "player" : "FUNIFIER_RANDOM_PLAYER",
 "competition" : "my_duel"
}

As a result the system will choose a randomly valid player and return in the player field.

{

    "join": {

        "competition": "my_duel",

        "player": "tom",

        "created": 1535418242948,

        "_id": "5b849f82421c4812231730ec"

    },

    "status": "OK"

}

EXAMPLE: PRESENTING THE FINAL RESULT OF A COMPETITION

To view the winners of a competition you can use the endpoint /v3/database/achievement/aggregate. When a competition is completed, achievements are recorded for the winners. And we can create a query by aggregating the winners' achievement with the data of the player object, to create a list with friendly information from competitors who have won a competition. See below for an example that shows the name, photo and position of the winner in a competition. If you are not very familiar with the aggregation operation below, see the documentation (FUNIFIER REST API - Aggregation).

POST http://service2.funifier.com/v3/database/achievement/aggregate

[
{ "$match":{ "item":"my_competition" }},
{ "$lookup": {"from":"player", "localField":"player", "foreignField":"_id", "as":"p" }},
{ "$unwind" : "$p" },
{ "$project": { "competition":"$item", "player":1, "player_name":"$p.name", "position":"$extra.position", "total":"$extra.total" }},
{ "$sort":{ "position": 1 }}
]

EXAMPLE: DUEL OF THE LARGEST BOOK SELLERS

Let's say your players are posting book sales actions on their gamification with the action/log structure below:

POST http://service2.funifier.com/v3/action/log

{

        "actionId" : "sell",

        "userId" : "ricardo",

        "attributes":{

                "product":"book"

        }

}

You want to create a duel to see which of two players will record more book sales in the month. For this you can create a competition by informing in the operation type: 1, to count action/logs. In the item enter the id of the action "sell" that will be counted, and finally enter in the filters field the parameter "product" with value equal to "book". In the end your competition will have structure below:

POST https://service2.funifier.com/v3/competition

{
 "title" : "Book Sales Duel",
 "description" : "Evaluate who sell more books",
 "image" : "http://image.com/duel.png",
 "period" : {"expression": "2018-07-30T00:00:00-03:00;+1M+"},
 "maxWinners" : 1,
 "maxPlayers" : 2,
 "operation": {
   "type": 1,
   "sort": -1,
   "item": "sell",
   "filters": [
           {"param":"product", "operator":1, "value":"book"}
   ]
 },
 "requires" : [ ],
 "rewards" : [
   {"total" : 10, "type" : 0, "item" : "coin", "operation" : 0, "extra" : { "position" : 1 }}
 ],
 "notifications" : [
   {"event" : 0, "type" : 0, "scope" : 0, "content" : "Congratulations {{player.name}} you won the book sales duel"}
 ],
 "active" : true,
 "autoExecute" : true,
 "extra" : {},
 "_id" : "sell_book_duel"
}