Hi team,
The documentation on CloudSave queries is very sparse, and I’m not even able to find YouTube videos for it. My situation is this:
I have potential 2 player matches set up as individual custom Ids. I have created a basic ‘offline’ lobby system where Player1 can set up a game and even make their first move. Player2 then comes and injects their PlayerId into the Player2 slot to make a match.
It is therefore possible that in a low-use scenario, a player could create a game as Player1 and then later try to start a new game and be injected into Player2 of the game in which they are already Player1.
How can I use CloudSave Queries to only return a list of customIds/matches where:
The key “Player2” is null (meaning it is empty and available to join)
The key “Player1” which holds a value (serialised) of type ServerGamePlayer and property PlayerId is not equal to context.PlayerId (i.e. this requesting player).
Thanks
Nathan
If mods are reading this, a query example in the documentation would be useful.
This is a great question, and I agree the documentation for Cloud Save Queries is a bit thin right now - we’ve got an update to the documentation for how to use Queries from the SDK coming this week and more updates planned.
When specifying a query (in Unity, or in Cloud Code) the results must both be true for a result to be found.
If you you are using Custom Items to store state for player matches, when looking for a new game to join you could avoid the scenario you describe by adding an an index on the “player1” and “player2” keys and using a NE (does not equal) filter so it only returns matches where the player is not already Player1.
For example, in Unity a query to do this from a game client might look like:
var query = new Query(
new List<FieldFilter>
{
new FieldFilter("player1", AuthenticationService.Instance.PlayerId, FieldFilter.OpOptions.NE, true),
new FieldFilter("player2", null, FieldFilter.OpOptions.EQ, true)
},
new HashSet<string>
{
"player1",
"player2"
}
);
var results = await CloudSaveService.Instance.Data.Custom.QueryAsync(query, new QueryOptions());
Debug.Log($"Number of results from query: {results.Count}");
results.ForEach(r =>
{
Debug.Log($"Custom Item ID: {r.Id}");
r.Data.ForEach(d => Debug.Log($"Key: {d.Key}, Value: {d.Value.GetAsString()}"));
});
I appreciate this isn’t an example for Cloud Code but the Filter logic works the same way - I’ve made a note we should have a similar example using Queries from Cloud Code.
Note: I’m not entirely sure that matching Player 2 would actually work exactly this way (as I’m not sure if you can actually save / match on a null value) but you could certainly use a value like the string “NULL” or an empty string.
Thanks. I’ll investigate further. In hindsight, I think I might be able to get away with just the Player1 criterion as a fallback by keeping another method I am already using, but querying against both would be more efficient. I won’t want to replace null with “NULL” as that feels more like a hack and may domino through my code.