Sign In Register

How can we help you today?

Start a new topic
Answered

Sharing data between players in pending match

Hi,

is there a way to share data between players that are in a pending match during matchmaking process?

there is a matchData but it seems read-only...


what I want to do is:

players start matchmaking for a 4-player match

while there are exactly 2 players in the pending match, they can set a flag to play the 2-player variant (by pressing a button int their UI)

if both players have set the flag, abort the matchmaking process and put them in a separate 2-player match (instantly)

(then wait for the MatchFoundMessage to start a RT session)


Best Answer
Hey Mauro,

There is an option when setting up a match to have it accept the min number of players. You can also enable the match to be drop-in/drop-out.
So in your example, a match has min-2, max-4 players, and a match can accept the min number of players.
This means that when two players join the match, they both get matchFound messages, and a match ID.

The match ID is important, as you can use this to find the match using the SparkMultiplayer API.
The process would work as follows....

[1] - you create a custom event which will load the match.
[2] - you then use the SparkMatch API to set the match data stating that this player has opted for a 1v1 match.
[3] - if more than one player has opted into the match, create a new match with only those two player IDs
[4] - cancel matchmaking for each player

This will cause the two players to get MatchFound messages for their 1v1 match.

Does that make sense?
Let me know if you need anymore info on this, i have included an outline of how this can be done in a cloud-code script attached.

Thanks,
Sean

 

js

ok, I tried with a new match config with the attached RT script.

this is the same script I used for exploring RT API some weeks ago (shortcode "ExampleRT") and I didn't modify it since then.

STILL NO LOG FROM IT and no packet sent to the client (my MatchFoundMessage has the new shortcode in it and its config has been created directly with ExampleRT script attached). it seems the entire RT platform is broken


js
(773 Bytes)

ok, I tried with a new match config with this exact RT script:  

 

// ====================================================================================================
//
// Cloud Code for module, write your code here to customise the GameSparks platform.
//
// For details of the GameSparks Cloud Code API see https://portal.gamesparks.net/docs.htm			
//
// ====================================================================================================

var counter = 0;

RTSession.setInterval(function(){
    ++counter;
    RTSession.newPacket()
        .setReliable(true)
        .setOpCode(1)
        .setData(RTSession.newData().setNumber(1, counter))
        .send();
}, 1000);
RTSession.onPlayerConnect(function(player){
    RTSession.getLogger().info("player connected: "+player.getPlayerId()+" as "+player.getPeerId());
})

 

this is the same script I used for exploring RT API some weeks ago (shortcode "ExampleRT") and I didn't modify it since then.

STILL NO LOG FROM IT and no packet sent to the client (my MatchFoundMessage has the new shortcode in it and its config has been created directly with ExampleRT script attached). it seems the entire RT platform is broken


Hi,

I am starting to experiment with your process, except I am using realtime, so if I have the match (and the session) early I can sync everything there.

for now I do:

[1] - players do a LogEventRequest_CreatePendingMatch, which in turn it does a Spark.getConfig().getMatchConfig(data.match).createPendingMatch(data.matchGroup , skill, playerData)

  [1.1] I use a custom event because I am planing to support players creating [pending]matches with friends, then search for random players to fill the empty positions (game is default 4 players 2v2, a player will be able to play alone with 3 random others or invite X friends [x in 1..3] and find (3-X) random players to match - those players may already be paired with 1 friend and "count 2")

[2] - Players get a MatchFoundMessage and start a RT session

[3] - player will stay in a waiting state (i.e. bot in RT session and in matchmaking) until either:

  [3a] 4 players join the session

  [3b] exactly 2 players join the session and bot have the flag set (flag will be sent as RT packet)

[4] match starts


what I am still missing is: 

[1] prevent other players to join the match if the game is started (I check after they join and kick them out) - is cancelling matchmaking enough?

  [1.1] more generally, if i cancel the matchmaking can someone else still join my match (and RT session)?

[2] have a MFM as early as I create the [pending] match - this will cover the following cases:

  [2.1] less duplication between before and after the RT session - now I have to do the same stuff twice depending if I am still alone or not

  [2.2] having 1 player vs 3 bots if there isn't enough players online - see my question here

    [2.2.1] I tried createPendingMatch with 3 players I created as bots, but it seems GameSparks doesn't match them if they are not online


Hey Mauro,

Just wanted to keep you informed on this post.
I will try setup a match using this criteria to test your setup and let you know how it goes.

My thinking is that this will be a special 2 player match which you can create from the live player and one of your bots.
Then you can add in the code to run the 3 bots yourself?
You could add 3 dummy players into a 4 player match, but if you can get it working with only 2 players matched it would reduce the MAU caused by using these dummy players.

Sean

ok thanks.


I noticed that sometimes i lose some packets:

each client sends a Init packet inside its OnReady callback (with GameSparksRT.DeliveryIntent.RELIABLE) but the first one doesn't arrive on the server (it sends it before getting OnPlayerConnected for the other player - is it a bug or I need to wait something else before sending packets?

this (Init) is the only packet for which I noticed this loss, other packets I send after seems to arrive just fine

 

Hey Mauro,


So i have a solution to setting up your 1v4 match with bots.
This will work for a 1vbot with 2 bots controlled by client or RT script, or setup between 1player and 3bots.

[1] Create a new custom event.

[2] search for an available bot using whatever username you use to define bots.

[3] create a new match using the ID of the the player and your bots.

[4] enable realtime on this match (and add the specific script you need, see api )

[5] return the necessary data needed to connect to the server (port,host, access-token)


You only need the live player's data so you can return those details only.


Now, bear in mind that im not sure how the RT script will act if you try to send data to those players who are not connected.
But this will allow you to connect to the RT server.

Sean

js
(864 Bytes)
Regarding the init-packet, it is possible that the server isnt fully config'd by the time OnReady is called.
I would suggest sending an packet from Onplayerconnected server-side to notify the player it is okay to send the init-packet.

Sean

 

ok, so

[1] I already have a custom event to switch from "Waiting" to "Game" mode, so I already have setup something similar

[2] by "available" you mean I should manually track whether a particular bot-player is currently in an RT session and use only free ones?

  [2.1] if so, is there an "RTSession ended" callback i should use?

  [2.2] if not, can I use a single bot player to act as a "ghost" only for the connection phase to start the session (that player will "join" the RT session but will never connect and I don't care if it leaves instantly, only that the session itself is up

[3][4][5] exactly what I already do (except now is human-only)


is there a range of OpCodes I can/should use for RT? (is 0 allowed? negatives? int.maxValue?) for now I stayed safe and used [1-127] but I'd like to put that new "pre-init" before (or at least grouped with my other init-ish opCodes)


[2] by "available" you mean I should manually track whether a particular bot-player is currently in an RT session and use only free ones?

Good point. I was originally thinking you might encounter problems trying to match two players who are already in an existing match, but it would appear that forcing the match means you can just re-use that same player.


[2.1] if so, is there an "RTSession ended" callback i should use?

There is not, but if you need this information in the future you can query the 'matchInstance' collection for a matching playerID in the participant data there.



is there a range of OpCodes I can/should use for RT? (is 0 allowed? negatives? int.maxValue?) for now I stayed safe and used [1-127] but I'd like to put that new "pre-init" before (or at least grouped with my other init-ish opCodes)

The value does have to be positive cannot be 0, anything over that is allowed. op-code is a 'uint' so max value is around 4M.


ok thanks.


I actually found out I am sending a "PlayerPause" packet in onPlayerConnect so I used that (I am manually tracking player connection by pinging each player constantly (every 15 seconds) and consider them paused if they don't respond in 10s, so if they have the app in background but their socket is not killed I can put bots in their place)

ps: I noticed when I call GameSparksRTUnity.Instance.Disconnect() it doesn't fire OnReady(false) as I would expect. is this intended (for now I poll GameSparksRTUnity.Instance.Ready each frame)

Hey Mauro,

So, unfortunately there is no ability to 'close' a match like this at the moment, but i am going to investigate adding that ability to the platform. I will keep you updated on what comes from that.
Cancelling matchmaking will only cancel it for a player who is currently looking. You do want to allow every player to continue to look for other match instances, so this might not be what you are after.

One alternative solution would be to disconnect the two players from the current RT session and create a new 2 player match with their IDs manually.

Im not sure what you mean by MFM, so if you could explain to me a bit on that topic i can help further. Sorry about that.

As for the bots, what i suggest is setting up a system to run a custom match when the player gets the MatchNotFoundMessage (you may need to add some script data to this message so you can tell the client to ignore any dialogue you may have by default for failed matches). This code can take the playerId and the IDs of 3 bot-players you keep a list of, and manually setup a match with those players.
Does that make sense?

Let us know if that advice is clear or if you need further information.

Thanks,
Sean

 

sorry, MFM stands for MatchFoundMessage


I am currently trying to do this (cancelling matchmaking, disconnect the RT and create a match with the IDs) without disrupting the existing code too much (which starts the RT and then manages internally the state - waiting or playing - and I literally rewrote to account for dropin/dropout)


I have to evaluate if it's better to create a separate RT script (duplicating code) or do everything in a single script


I noticed a "realtime modules" section appeared in my cloud code, but I can't find any docs. is it usable? 


for the MatchNotFoundMessage stuff:

1 - I tried to do a createPendingMatch before, but it seems to match only online players - is it a limitation of pendingMatch or the fact it's realtime? 

2 - for now I generate the bots client-side with a random GUID and sync them with the RT - what would be the preferred way to get a bot-player to match and how many do I need in total? is using the same 3 players to join every match that needs a bot enough or they would be removed from the other matches and I need to use a big enough player pool for this?

I dont think a separate script will make any difference, and you also have a small performance consideration that the RT script will be cached the first time it is used and for any following connection while that script is running in an instance.

So it would be slightly quicker, as you will most likely have many of the normal match instances running.

Now, i may be misunderstanding your question and you mean you will need a new script for the 1 player/3 bots match.

In this case i do recommend a separate script as your bots will have behaviors specific to that kind of match if you are going to balance it properly. But i reckon, in that case, it might be a good idea to take the match offline altogether and just simulate the match on the client.



[1] - You should be able to use createMatchById() to match players directly, you shouldnt use pending match for this example.


[2] - As mentioned above, bots with RT scripts are tricky.
Adding in dummy players to act as bots and complete the match will mean you get charged for those players as they will count towards your MAUs.


You also have no idea how many dummy-players you need. Though you could easily create a system in cloud code that finds a dummy-player not currently in a match and uses them; when there are no available dummy-players to join, you create a new one in cloud-code.


One thing you could do is have special match setup so that when MatchNotFound message is fired, all players in the pending match get put into a new match which has bots that run from the RT script and no dummy-players.

i.e, in a 4 player match, if two players stay pending for 30s or more, they get a MNF message. In there, you take those two playerIds and create a "2playerV2bot" match, which accepts only 2 players, but the RT script can send a message on connection to tell the user to spawn two additional players in the client that it will send packets to control those.

Does that make sense?
Please let me know if that is a suitable alternative.

Thanks,
Sean




Login to post a comment