Sign In Register

How can we help you today?

Start a new topic
Answered

Heartstone example, automatic challenge on MatchFoundMessage

Hi,


I've been implementing matchmaking and creating a challenge based on the Heartstone example like this:


// ===================================================================================

//

// Cloud Code for MatchFoundMessage, write your code here to customise the GameSparks platform.

//

// For details of the GameSparks Cloud Code API see https://portal.gamesparks.net/docs.htm

//

// ===================================================================================


//A match was found, now we will create a challenge coming from the first player to the second player

if(Spark.getPlayer().getPlayerId() == Spark.getData().participants[0].id) {

    //Create a challenge request

    var request = new SparkRequests.CreateChallengeRequest();

    //Fill in the details, give a date in the future, the right shortCode,

    //make it a private challenge and invite participant 2

    request.accessTyp = "PRIVATE";

    request.challengeShortCode = "STD_CHAL";

    request.endTime = addDays(new Date(), 4);

    request.expiryTime = addDays(new Date(), 3);

    request.usersToChallenge = [Spark.getData().participants[1].id];

    //Send the request

    request.Send();

}

//function to add days to a given date.

function addDays(startDate,numberOfDays)

{

 var returnDate = new Date(

       startDate.getFullYear(),

       startDate.getMonth(),

       startDate.getDate()+numberOfDays,

       startDate.getHours(),

       startDate.getMinutes(),

       startDate.getSeconds());

 return returnDate;

}


This used to work fine, but I've been testing it lately and it seems that the challenge is no longer created. I do see the MatchFoundMessage for both players of the match, but the player that is challenged does not get the ChallengeIssuedMessage.


Also, the Test Harness debugger doesn't break in the MatchFoundMessage Cloud Code. It does stop for the other cloud scripts I have, but not in this one. So I'm wondering what could be wrong here?


Best Answer

Hi Jeffry,


Messages such as the MatchFoundMessage are asynchronous so there is no debugger attached to the thread they are running on. That and other match related messages are the result of multiple processes. Therefore it would require both threads to have a debugger instanced and therefore run the code twice which would be undesirable behavior.. Have you checked your script.log for errors related to the challenges that are not being created properly in the MatchFoundMessage ? If you can let me know the name of your game we can take a closer look at this for you.


Thanks,

Liam


Answer

Hi Jeffry,


Messages such as the MatchFoundMessage are asynchronous so there is no debugger attached to the thread they are running on. That and other match related messages are the result of multiple processes. Therefore it would require both threads to have a debugger instanced and therefore run the code twice which would be undesirable behavior.. Have you checked your script.log for errors related to the challenges that are not being created properly in the MatchFoundMessage ? If you can let me know the name of your game we can take a closer look at this for you.


Thanks,

Liam


1 person likes this

Thanks Liam, that explains the debugger.


There was nothing in script.log, but since then I added some logger.debug messages and the cloud code is called fine, it seems that it sends the request, but I feel to see a ChallengeIssuedMessage appear in test harness.


if you could have a closer look, that would be great. The name of the game is Turns: Pirates vs Ninjas - DEV.


Let me know if you need anything else from me.


Thanks,

Jeffry

Try request.Execute() rather than .Send()

Checking the return value for errors could also turn up something (it did for me).


    // Send the request

    var response = request.Execute();

    

    if (response.error)

    {

        Spark.getLog().error(response.error.stringify());

    }


1 person likes this

Thanks, getting the response and checking the error property did it. The date format was incorrect.


Okay copying sample code, but then I should add some defensive programming concepts to it to make it more production ready ;)


Thanks for pointing me in the right direction!

I have another question. I found the error because I logged the complete response and saw this:

{\"@class\":\"GameSparksErrorResponse\",\"errors\":{\"message\":\"java.text.ParseException: Unparseable date: \\\"{\\\" (through reference chain: com.gamesparks.messages.requests.CreateChallengeRequest[\\\"endTime\\\"])\"}}


Notice the errors property (plural). Now, if I check for the existence of response.error it doesn't find it. But if I try response.errors I get a Gamesparks error saying that errors is not a valid property.


Am I doing something wrong here?

Looks like it is failing to parse 'endTime'. In your CreateChallengeRequest.


This is what I am personally using for endTime...


    request.endTime = getDateString(new Date(Date.now() + 60 * 60 * 1000)); // 1 hr


Where getDateString is this helper function... (someone in gamesparks support had to tell me what this was suppose to be, I have no idea why this is necessary or what this 'Z' shit is about).


function getDateString(date)

{

    var dateString = date.toISOString();

    return dateString.substr(0, dateString.lastIndexOf(".")) + "Z";

}

That's what I ended up doing. The Z is for UTC time and you have to strip off the milliseconds part. If you just put a new Date() in there, it will be serialized as "2016-09-07T21:15:28.870Z", but Gamesparks doesn't like the last part, so you have to turn it into "2016-09-07T21:15:28Z"

Note that I ultimately ended up doing all challenge creation / invitation / accepting from the client-side, in response to the match found message. Ultimately I wanted to be -sure- that both players were really still there and running the game, and to have timeouts so neither player can possibly get stuck in-between match found and gameplay starting - and it ended up making things more complicated instead of less if the server created the challenge on behave of one of the players who might not actually even be running the game anymore.


1 person likes this

So how did you decide which player creates the challenge and sends the invitation and which players accepts the challenge? Because they're both receiving the same MatchFoundMessage, right?

The first one in the 'participants' list (in the match found message) creates the challenge and invites the other player. The other player waits for the invitation and accepts it when it is received. Then both players handle the challenge started message to head into gameplay. Also they both start a timer when the match found message comes in. If more than 3 seconds have elapsed before the challenge started event comes in, then they restart searching (and the challenger also withdraws the challenge so it doesn't linger).


1 person likes this
Login to post a comment