Sign In Register

How can we help you today?

Start a new topic
Answered

Simple Challenge System!

I want to set up a very simple challenge where 


Player 1 plays the game, gets a score of 10 

Sends this score to Player 2 

Player 2 plays the game, gets a score then we check the 2 scores and see who has won.


But i can't seem to get this working with Gamesparks, when i do a CreateChallengeRequest with scriptData of scoreToBeat i don't see it on the challengeInstance?! Is there something i am missing?


Regards 

Abdullah


Best Answer

Ah so in this case we must create the challenge, wait for the response, on the response log an event with an attribute for the challengeInstanceId and the score, in the cloud code of that event have it set the scriptData to the challenge like in the example above.


You can do this in Unity by nesting the LogEvent in the Response of the CreateChallengeRequest and taking the challengeInstanceId from the response. The reason we use LogEvent instead of LogChallengeEvent in this case is that if you LogChallengeEvent before the challenge has started/not your turn your event will not fire. LogEvent lets us manipulate the challenge without the safety features getting in the way.


I've added you to a game that has this set up. A run through looks like:


Player1:  

{
 "@class": ".AuthenticationRequest",
 "password": "password",
 "userName": "shane"
}

{
 "@class": ".AuthenticationResponse",
 "authToken": "9759a8ca-3ea2-4e64-b05e-672ddc60a438",
 "displayName": "shane",
 "scriptData": null,
 "userId": "54b7d355e4b05c5f26339dad"
}

{
 "@class": ".CreateChallengeRequest",
 "accessType": "PRIVATE",
 "challengeShortCode": "mainChallenge",
 "endTime": "2015-12-31T12:00Z",
 "usersToChallenge": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".CreateChallengeResponse",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47",
 "scriptData": null
}

{
 "@class": ".LogEventRequest",
 "eventKey": "TakeTurnOnCreate",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47",
 "player1Score": "10"
}

{
 "@class": ".LogEventResponse",
 "scriptData": null
}

  

--------

Player2:

    

{
 "@class": ".AuthenticationRequest",
 "password": "password",
 "userName": "oisin"
}

//You wont see the script data here as the message was sent as soon as the challenge was created
{
 "@class": ".ChallengeIssuedMessage",
 "messageId": "54b7d61ee4b0ebe653e6af48",
 "notification": true,
 "summary": ".ChallengeIssuedMessage",
 "who": "shane",
 "challenge": {
  "challengeId": "54b7d61ee4b0ebe653e6af47",
  "scriptData": {},
  "shortCode": "mainChallenge",
  "startDate": null,
  "accepted": [
   {
    "name": "shane",
    "id": "54b7d355e4b05c5f26339dad"
   }
  ],
  "challenged": [
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenger": {
   "name": "shane",
   "id": "54b7d355e4b05c5f26339dad"
  },
  "expiryDate": null,
  "endDate": "2015-12-31T12:00Z",
  "challengeName": "mainChallenge",
  "state": "ISSUED"
 },
 "playerId": "54b7d35de4b05c5f26339e16"
}
//At any point after this player2 will see the player1Score scriptData, before accepting the challenge you could call a "getChallengeRequest" to see the field

{
 "@class": ".AuthenticationResponse",
 "authToken": "887345cc-2f15-4d02-957a-74e5fb3d83d9",
 "displayName": "oisin",
 "scriptData": null,
 "userId": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".AcceptChallengeRequest",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47"
}

{
 "@class": ".AcceptChallengeResponse",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47",
 "scriptData": null
}

{
 "@class": ".ChallengeStartedMessage",
 "messageId": "54b7d73fe4b0ebe653e6b00c",
 "notification": true,
 "summary": ".ChallengeStartedMessage",
 "challenge": {
  "challengeId": "54b7d61ee4b0ebe653e6af47",
  "scriptData": {
   "player1Score": "10"
  },
  "shortCode": "mainChallenge",
  "startDate": "2015-01-15T15:05Z",
  "accepted": [
   {
    "name": "shane",
    "id": "54b7d355e4b05c5f26339dad"
   },
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenged": [
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenger": {
   "name": "shane",
   "id": "54b7d355e4b05c5f26339dad"
  },
  "expiryDate": null,
  "endDate": "2015-12-31T12:00Z",
  "challengeName": "mainChallenge",
  "state": "RUNNING"
 },
 "playerId": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".LogChallengeEventRequest",
 "eventKey": "Player2Turn",
 "challengeInstanceId": "54b7d8d5e4b05c5f2633aa23",
 "player2Score": "20"
}

{
 "@class": ".ChallengeWonMessage",
 "messageId": "54b7daa8e4b05c5f2633ade8",
 "notification": true,
 "summary": ".ChallengeWonMessage",
 "currency1Won": 0,
 "currency2Won": 0,
 "currency3Won": 0,
 "currency4Won": 0,
 "currency5Won": 0,
 "currency6Won": 0,
 "challenge": {
  "challengeId": "54b7d8d5e4b05c5f2633aa23",
  "endDate": "2015-12-31T12:00Z",
  "challengeName": "mainChallenge",
  "scriptData": {
   "player1Score": "10",
   "player2Score": "20"
  },
  "shortCode": "mainChallenge",
  "startDate": "2015-01-15T15:13Z",
  "accepted": [
   {
    "name": "shane",
    "id": "54b7d355e4b05c5f26339dad"
   },
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenged": [
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenger": {
   "name": "shane",
   "id": "54b7d355e4b05c5f26339dad"
  },
  "expiryDate": null,
  "state": "COMPLETE"
 },
 "playerId": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".LogChallengeEventResponse",
 "scriptData": null
}

    


Shane


Hi Abdullah,


So the challenge technically doesn't exist until the player receives a CreateChallengeResponse, this is where you should set the score to beat. We can do this by taking the challengeInstanceId from the response and using that to load the challenge object and then set the scriptData like so:


Cloud Code -> Responses -> CreateChallengeResponse

  

var thisChallenge= Spark.getChallenge(Spark.getData().challengeInstanceId);

if(thisChallenge.shortCode === "abdullahsGame"){
    challenge.setScriptData("scoreToBeat", 10);
}
 

 

As you can see, we are actually checking the shortCode of the challenge to make sure it's the one we want to set scriptData against. This is because CreateChallengeResponse is called for every challenge type and you might not want to store a turn on all of them right away.


Shane

Thanks for the reply, but not quite what i am after.


challenge.setScriptData("scoreToBeat", 10);

the 10 for the value is something i do not want to hardcode as i am setting the ScriptData "scoreToBeat" to X from Unity and the request shows the scriptData going through fine, its when the opponent receives it he has no ScriptData. 


So what i am looking for is a way to first getScriptData from the challengeRequest and then setScriptData with that value, so that when my opponent receives the Challenge he can see that the score he needs to beat is X.


Regards

Abdullah Awan


Answer

Ah so in this case we must create the challenge, wait for the response, on the response log an event with an attribute for the challengeInstanceId and the score, in the cloud code of that event have it set the scriptData to the challenge like in the example above.


You can do this in Unity by nesting the LogEvent in the Response of the CreateChallengeRequest and taking the challengeInstanceId from the response. The reason we use LogEvent instead of LogChallengeEvent in this case is that if you LogChallengeEvent before the challenge has started/not your turn your event will not fire. LogEvent lets us manipulate the challenge without the safety features getting in the way.


I've added you to a game that has this set up. A run through looks like:


Player1:  

{
 "@class": ".AuthenticationRequest",
 "password": "password",
 "userName": "shane"
}

{
 "@class": ".AuthenticationResponse",
 "authToken": "9759a8ca-3ea2-4e64-b05e-672ddc60a438",
 "displayName": "shane",
 "scriptData": null,
 "userId": "54b7d355e4b05c5f26339dad"
}

{
 "@class": ".CreateChallengeRequest",
 "accessType": "PRIVATE",
 "challengeShortCode": "mainChallenge",
 "endTime": "2015-12-31T12:00Z",
 "usersToChallenge": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".CreateChallengeResponse",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47",
 "scriptData": null
}

{
 "@class": ".LogEventRequest",
 "eventKey": "TakeTurnOnCreate",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47",
 "player1Score": "10"
}

{
 "@class": ".LogEventResponse",
 "scriptData": null
}

  

--------

Player2:

    

{
 "@class": ".AuthenticationRequest",
 "password": "password",
 "userName": "oisin"
}

//You wont see the script data here as the message was sent as soon as the challenge was created
{
 "@class": ".ChallengeIssuedMessage",
 "messageId": "54b7d61ee4b0ebe653e6af48",
 "notification": true,
 "summary": ".ChallengeIssuedMessage",
 "who": "shane",
 "challenge": {
  "challengeId": "54b7d61ee4b0ebe653e6af47",
  "scriptData": {},
  "shortCode": "mainChallenge",
  "startDate": null,
  "accepted": [
   {
    "name": "shane",
    "id": "54b7d355e4b05c5f26339dad"
   }
  ],
  "challenged": [
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenger": {
   "name": "shane",
   "id": "54b7d355e4b05c5f26339dad"
  },
  "expiryDate": null,
  "endDate": "2015-12-31T12:00Z",
  "challengeName": "mainChallenge",
  "state": "ISSUED"
 },
 "playerId": "54b7d35de4b05c5f26339e16"
}
//At any point after this player2 will see the player1Score scriptData, before accepting the challenge you could call a "getChallengeRequest" to see the field

{
 "@class": ".AuthenticationResponse",
 "authToken": "887345cc-2f15-4d02-957a-74e5fb3d83d9",
 "displayName": "oisin",
 "scriptData": null,
 "userId": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".AcceptChallengeRequest",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47"
}

{
 "@class": ".AcceptChallengeResponse",
 "challengeInstanceId": "54b7d61ee4b0ebe653e6af47",
 "scriptData": null
}

{
 "@class": ".ChallengeStartedMessage",
 "messageId": "54b7d73fe4b0ebe653e6b00c",
 "notification": true,
 "summary": ".ChallengeStartedMessage",
 "challenge": {
  "challengeId": "54b7d61ee4b0ebe653e6af47",
  "scriptData": {
   "player1Score": "10"
  },
  "shortCode": "mainChallenge",
  "startDate": "2015-01-15T15:05Z",
  "accepted": [
   {
    "name": "shane",
    "id": "54b7d355e4b05c5f26339dad"
   },
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenged": [
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenger": {
   "name": "shane",
   "id": "54b7d355e4b05c5f26339dad"
  },
  "expiryDate": null,
  "endDate": "2015-12-31T12:00Z",
  "challengeName": "mainChallenge",
  "state": "RUNNING"
 },
 "playerId": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".LogChallengeEventRequest",
 "eventKey": "Player2Turn",
 "challengeInstanceId": "54b7d8d5e4b05c5f2633aa23",
 "player2Score": "20"
}

{
 "@class": ".ChallengeWonMessage",
 "messageId": "54b7daa8e4b05c5f2633ade8",
 "notification": true,
 "summary": ".ChallengeWonMessage",
 "currency1Won": 0,
 "currency2Won": 0,
 "currency3Won": 0,
 "currency4Won": 0,
 "currency5Won": 0,
 "currency6Won": 0,
 "challenge": {
  "challengeId": "54b7d8d5e4b05c5f2633aa23",
  "endDate": "2015-12-31T12:00Z",
  "challengeName": "mainChallenge",
  "scriptData": {
   "player1Score": "10",
   "player2Score": "20"
  },
  "shortCode": "mainChallenge",
  "startDate": "2015-01-15T15:13Z",
  "accepted": [
   {
    "name": "shane",
    "id": "54b7d355e4b05c5f26339dad"
   },
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenged": [
   {
    "name": "oisin",
    "id": "54b7d35de4b05c5f26339e16"
   }
  ],
  "challenger": {
   "name": "shane",
   "id": "54b7d355e4b05c5f26339dad"
  },
  "expiryDate": null,
  "state": "COMPLETE"
 },
 "playerId": "54b7d35de4b05c5f26339e16"
}

{
 "@class": ".LogChallengeEventResponse",
 "scriptData": null
}

    


Shane

Ah ok Brilliant thats much better! Thanks


Just one more thing I've noticed today. When i do send the LogEvent by Player A and the PlayerB receives the challenge etc. Sometimes when i do a LogChallenge event with PlayerB it says NOT_YOUR_TURN but other times it works fine.


In my cloud code for LogEvent (which is sent by PlayerA straight after the create challenge) i have got the following:


var thisChallenge = Spark.getChallenge(Spark.getData().challengeInstanceId);

thisChallenge.setScriptData("scoreToBeat", Spark.getData().scoreToBeat);


and in the takeTurn ChallengeEvent (which is sent by PlayerB) i have got the following


var thisChallenge = Spark.getChallenge(Spark.getData().challengeInstanceId);


var scoreToBeat = thisChallenge.getScriptData("scoreToBeat");


var playerScore = Spark.getData().playerScore;

var opponentID = Spark.getData().opponentID;

checkWinner();


function checkWinner(){

if(playerScore > scoreToBeat){

thisChallenge.winChallenge(Spark.player);

}

if(playerScore < scoreToBeat){

thisChallenge.winChallenge(Spark.loadPlayer(opponentID));

}

if(playerScore == scoreToBeat){

thisChallenge.drawChallenge();

}

thisChallenge.consumeTurn(Spark.player);

}


Thanks

Hi Abdullah,


It's important to make sure that the challenge is not set to "Turn Based" in the Configurator. While this is a turn based scenario, we know player 1 will always have set their score to the challenge and that once player 2 has received/accepted the challenge it will be there go. This should fix your problem.


Shane

Login to post a comment