Sign In Register

How can we help you today?

Start a new topic

Add participant data to pending match created from cloud code

Hi,

Is there a way to set participantData (not matchData) to a pending match besides a matchmakingRequest?


i am creating pending matches with 

Spark.getConfig().getMatchConfig(shortcode).createPendingMatchWithCustomQuery(matchGroup, skill, customQuery, matchData, players);

 because two or more players can be already matched when starting matchmaking in case of a rematch ( i have a 4 player game, at the end of each match players can do a rematch but if some players do it and some players don't then I need to fill the match up to 4)

I also have need to transfer some data from the just ended match to the next one. I can't use matchData for this because non-rematch matches also have their own matchData and when a pendingMatch is joined I have no control over which matchData is kept (they don't merge and I have no callback in which I can do it myself)

for this I created a "rematch" collection and I do   

var toIns = {matchOrder:matchOrder, shortCode:data.match, matchGroup:data.matchGroup, ts:Date.now(),properties:data.properties}
Spark.runtimeCollection("rematch").insert(toIns);

 (where matchOrder is an array of objects with playerId and other stuff)

in the MatchFoundMessage script I do  

Spark.runtimeCollection("rematch").find({"matchOrder.UserId":{$in:participants}}).sort({ts:-1}).limit(1);

 to retrieve it, set what I need in scriptData and remove that row from mongodb


the problem is that if that row doesn't get consumed (because player killed the app, cancelled matchmaking or something else) the next time that player joins a match and it's not a rematch the stale row gets picked up and bad stuff happens

(another concern is the performance of a query over an array, even if it's indexed)


I tought I could use participantData by setting the row id (or directly the rematch data) for each player that are doing rematch, then get each player's rematch data in match found (if more than one player have it, they should be all equal - part of the custom query is about preventing rematching players to match with another set of rematching players so a subset of players have the same rematch data and the others have nothing)


is there a MatchConfig.createPendingMatchWithParticipantData(matchGroup, skill, customQuery, matchData, players, participantData) or similar? or a PendingMatch.setParticipantData(playerId, participantData)?


there is a PendingMatch.getMatchedPlayers but there is absolutely no documentation on that and no autocomplete on cloud code editor either.


any help? we still have cases in which the wrong row gets pulled...


i try to put a quick summary of my requirements:

- there is data that need to be transferred from a match to the next

- a pending match is created with some of the players, potentially not all of them

- other players can join that match, if a player that left the previous match joins the same match again, it is considered new

- matchData is already used for other stuff, so we can't assume which survives (the "rematch" one with the data we need or the "new player" ones)

- we should be able to both reliably find that data if it should exist and discard old data that players could have left in the db for previous matches they joined

Hi,


- I don't want rematching players to match other rematching players because there are some properties that are transferred to the next match, and they can be incompatible with each other

-- i.e. the game is actually 2 vs 2, and if 2 player chose to rematch they should keep their relative positions in turn order and if they are allies or oopponents

-- I also have a "matchId" counter that keeps track of how many times a rematch happened, and a move counter that should not be reset as long as at least one player is rematching

- I am currently storing that information in a mongodb collection "rematch" indexed by each participant id in my LogEventRequest_CreatePendingMatch call, in which each client pass everything

-- i would end up with something like this: {_id:{$oid:"..."}, matchOrder:[{UserId:"player1",<other info>},{UserId:"player2",<...>},...],properties:{...}}

-- then in the MatchFoundMessage I fetch the info from mongodb with query {"matchOrder.UserId":{$in:["player1","player2",...]}} (which finds row with stored list intersects with arg). if I found anything, I count it as rematch, store everything in matchData and delete the row

-- the problem is if the row doesn't get deleted (perhaps because only one player clicked rematch, and then aborted or closed the app before matchmaking completed, therefore MatchFoundMessage didn't get fired) that row remains indefinitely in the db until next time that player joins another match. at this point, invalid data gets pulled from the db and interferes with the app.

-- i attempted to mitigate this by adding some cleanup in the LogEventRequest_CreatePendingMatch: 

    var updM = Spark.runtimeCollection("rematch").updateMulti({"matchOrder.UserId" :{$in:players}}, {$pull:{matchOrder:{UserId:{$in:players}}}});
    var rem = Spark.runtimeCollection("rematch").remove({matchOrder:{$size:0}});
    Spark.getLog().info({Cleanup:{update:updM,remove:rem}});

 and i'm currently testing if it works, but i'm unsure about (1) performance, and (2) if this fixes everything


I would use the participant data to have stuff transferred from all the pending matches I create to the resulting match (either the id of that row or directly all the data) and not bleed to other matches the player will join after.

Hi Mauro,


So just to clarify the scenario you are working with here. You have a four player match (as an example), that match ends and two of the four choose to rematch by clicking a button. These players get added to a pendingMatch in the hope of finding 2 more new players. From my understand you don't want to match players from another match that are looking for a rematch also ? Is that correct ? Can you give us an example of how you would plan to use the participant data here ? I don't think it's possible to create a pending match with participant data currently I'm afraid. For matchData you could simply get the data from the old match and set it to the new one when it's created. Once we have a clearer image of the exact requirement here we'll be able to point you in the right direction.


Thanks,

Liam

Login to post a comment