Initialization and Ranking

First, Setting up the Cards

For a game like this to work, we need a way to store the game's cards somewhere where it will be easy to access, manage, and edit them. For this, we'll use the Game Data Service.

Creating a Data Type for Cards

First, we need to create a new Data Type and add index fields to it:

1. Go to Configurator>Game Data and click Add. The Add Data Type Index page opens.

2. Create a new cardTable Data Type:

3. Add the following index fields for the new Data Type:

Once you've created the cardTable Data Type, its time to populate it. Each card will be it's own document, and the reasons will become obvious later on in the tutorial.

Populating the Data Type with Cards

To populate your Data Type:

1. Go to Data Explorer. The new cardTable will be listed on the Data Types panel.

2. Select cardTable and click the Insert tab.

For our example card game, we'll need to create 3 cards as documents belonging to the cardTable Data Type. Each card will have a value for the fields we've indexed for the Data Type and to serve the following purposes:

3. Insert three documents into the cardTable Data Type for three common cards, as follows:

ID:archer
{
  "spawnCost": 1,
  "tier": "common",
  "attack": 2,
  "health": 2
}

ID:warrior
{
  "spawnCost": 1,
  "tier": "common",
  "attack": 1,
  "health": 3
}

ID:mage
{
  "spawnCost": 1,
  "tier": "common",
  "attack": 3,
  "health": 1
}

Creating a Data Type for Player Decks

It's worth noting that the ID of your card documents is important in finding the cards in a player's deck. Because you'll have to access the cards statistics when you pull it out during the game, then you need a convenient way of getting that card's statistics from the cardTable Data Type.

For this tutorial, we're going to be using the name of the card as the ID. So that means our player's deck will need to have the card's name, identical to the ID of the card's entry in the cardTable Data Type. To do this in the most convenient way, we're going to create a playerDeck Data Type, which is going to save our player's decks. This Data Type will not need any indexes because we're not going to query it. The entry IDs for this Data Type is going to be the player's ID, so it's easy to reference in Cloud Code. Here's an example of one player's entry:

{
  "decks": {
    "startingDeck": [
      "warrior",
      "mage",
      "archer"
    ],
    "Brute Deck": [
      "warrior",
      "clubber",
      "ogre"
    ],
    "Assassins": [
      "dagger",
      "rogue",
      "archer"
    ]
  },
  "currentDeck": "startingDeck"
}

The string value 'currentDeck' just tells the game which deck the player is using at the moment.

You'd get that entry through the player's ID, like so:

  var API = Spark.getGameDataService();
  var entry = API.getItem("playerDeck",Spark.getPlayer().getPlayerId());

Player Initialization

We'll need to initialize our players once they're registered by creating their starting deck in the playerDeck Data Type and setting a default rank. To do this, we're going to create a new entry for the deck table and set the rank as scriptData for the player for easy access.

Head over to the Configurator>Cloud Code section. Once there, navigate to the Responses tab, expand it, and look for the RegistrationResponse. We'll edit our RegistrationReponse to look like this:


if(!Spark.hasScriptErrors() && Spark.getPlayer() != null){
    //
    var API = Spark.getGameDataService();

    var entry = API.createItem("playerDeck", Spark.getPlayer().getPlayerId());

    var data = entry.getData();

    var decks = data.decks = {};
    decks.startingDeck = ["warrior","mage","archer"];
    data.currentDeck = "startingDeck";

    var status = entry.persistor().persist().error();

    if(status){
        Spark.setScriptError("ERROR", status);
        Spark.exit();
    } else{
        Spark.getPlayer().setScriptData("rank", 25);
        Spark.getPlayer().setScriptData("stars", 0);
    }
}

Our RegistrationResponse will set the player's rank to 25 with no stars. The response will also construct the player's deck by giving the player that registers 3 common tier cards. The deck will also be saved in playerDeck Data Type table instead of scriptData because once the player's deck gets bigger and if later you give your players a chance to make more decks, the player's details will get clogged. So we'll leave the deck in playerDeck table and retrieve it when we want to using an Event.

Ranking

When a player loses or wins in a ranked match, their rank and stars will be affected. So it's only logical to place this logic in the ChallengeWon and ChallengeLost messages, which can be found under the UserMessages tab in the Cloud Code section. Within these messages, we'll be calling a module which will process the ranking after the result of the challenge.

ChallengeWonMessage:


//If it's a ranked match, process rank
if(Spark.getData().challenge.shortCode === "chalRanked")
{
    //This player was victorious so declare the outcome to 'Victory'
    var outcome = "victory";

    //Depending on the outcome variable the 'processRank' module will either increase rank or decrease player rank
    require("processRank");
}

ChallengeLostMessage:


//If it's a ranked match, process rank
if(Spark.getData().challenge.shortCode === "chalRanked")
{
    //This player lost so declare the outcome to 'loss'
    var outcome = "loss";

    //Depending on the outcome variable the 'processRank' module will either increase rank or decrease player rank
    require("processRank");
}

The processRank module moves the player up or down depending on the outcome of the challenge.

The processRank module:

//Retrieve the number of stars the player earned
var currentStars = Spark.getPlayer().getScriptData("stars");
//Retrieve current rank
var currentRank = Spark.getPlayer().getScriptData("rank");


if(outcome === "victory"){

    //Because the player just won, add a star
    currentStars++;
    //Save the number of stars the player has
    Spark.getPlayer().setScriptData("stars", currentStars);

    //Check for rank range
    if(currentRank >= 25 && currentRank <= 21 ){

        //Check for number of stars and if they qualify a levelup
        if (currentStars >= 2){
            //If number is met, level up by descending down towards rank 1
            Spark.getPlayer().setScriptData("rank", currentRank - 1);
            //Reset and save the number of current stars
            Spark.getPlayer().setScriptData("stars", 0);
        }

    }
    else if(currentRank >= 20 && currentRank <= 16 ){
        //Check for number of stars and if they qualify a levelup
        if (currentStars >= 3){
            //If number is met, level up by descending down towards rank 1
            Spark.getPlayer().setScriptData("rank", currentRank - 1);
            //Reset and save the number of current stars
            Spark.getPlayer().setScriptData("stars", 0);
        }
    }
    else if(currentRank >= 15 && currentRank <= 11 ){
        //Check for number of stars and if they qualify a levelup
        if (currentStars >= 4){
            //If number is met, level up by descending down towards rank 1
            Spark.getPlayer().setScriptData("rank", currentRank - 1);
            //Reset and save the number of current stars
            Spark.getPlayer().setScriptData("stars", 0);
        }
    }
    else{

        //Don't do anything if player is rank 1 because they can't advance anymore
        if(currentRank > 1)
        {
            //Check for number of stars and if they qualify a levelup         
            if (currentStars >= 5){
                //If number is met, level up by descending down towards rank 1
                Spark.getPlayer().setScriptData("rank", currentRank - 1);
                //Reset and save the number of current stars
                Spark.getPlayer().setScriptData("stars", 0);
            }
        }
    }
}

else{

    //Does the player have stars?
    if(currentStars > 0){

    //Because the player just lost, remove a star
    currentStars--;
    //Save the number of stars the player has
    Spark.getPlayer().setScriptData("stars", currentStars);

    }

    //Check if player rank is less than 25 because that's the lowest level
    if(currentRank < 25){
        //If player has 0 stars
        if(currentStars < 1){
            //Decrease level by 1
            Spark.getPlayer().setScriptData("rank", currentRank + 1);

            if(currentRank >= 1 && currentRank <= 9){
                Spark.getPlayer().setScriptData("stars", 5);
            }
            if(currentRank >= 10 && currentRank <= 14 ){
                Spark.getPlayer().setScriptData("stars", 4);
            }
            if(currentRank >= 15 && currentRank <= 19){
                Spark.getPlayer().setScriptData("stars", 3);
            }
            if(currentRank >= 20 && currentRank <= 24){
                Spark.getPlayer().setScriptData("stars", 2);
            }

        }

    }
}

And that's it for initialization, your game is ready for the Matchmaking.

Did this page help you? Please enter your feedback below. For questions about using this part of the platform, please contact support here