Finding the match(es) a user is in

Is there a way for the server side code to find any match(es) a user may be in? The use case is a game crash or other interruption on a mobile device where the user restarts the game. Upon restart we would like to be able to do a quick check to see if the user is still part of some game in progress and if so, resume the game.

The only API call that I can find that could help is:

MatchList(ctx context.Context, limit int, authoritative bool, label string, minSize, maxSize *int, query string) ([]*api.Match, error)	

It’s documented here: Function Reference - Heroic Labs Documentation but I can’t seem to find anything about the query syntax. I have seen something about it somewhere, but the docs are somewhat unorganized and really hard to find anything in. What I was looking for was something that would allow me to do approximately:

var query = "user:" + user.Id
MatchList(...., query)

or

UserMatchList(ctx context.Context, userId string) ([]*api.Match, error)	

It doesn’t seem to work like that at least. :slight_smile: Another approach would be to just brutally iterate through all active matches and found those where the user’s id is an active presence, but I can’t seem to find any API to do that either.

query argument can be used to filter matches based on user defined labels, it’s syntax is described here

You can keep up to date list of player ids in match labels using MatchJoin and MatchLeave , both of which have dispatcher argument with MatchLabelUpdate method.

MatchLabelUpdate accept json encoded string with a full set of labels to set on a match, so it is probably best to keep reference set of labels somewhere in the match state.

When you need to find match for a given player , you invoke MatchList and pass query param to find matches for a player

Doesn’t that become somewhat slow if the label contains a bunch of JSON that has to be decoded all the time when checking if players are in a match?

I’m probably somewhat daft, but I can’t see how Bleve could find something based on an array of player ids. It seems to be only about really simple queries on individual numeric or string fields, not anything more complex than that.

	var players []string

	// players are kept in our custom match state
	for _, player := range state.players {
		// the Id is Nakama's UUID
		players = append(players, player.Id)
	}

	var labelMap = map[string]interface{}{
		// the mode is, well, a game mode. A numeric value already being queried for
		"mode":    state.mode, 
		"players": players,
	}

	// marshal to JSON and update the label
	...

It seems that an API that allowed users to do own filtering would be more handy and faster? Something like a MatchFind where we’d pass in a function that takes an *api.Match and an interface{} representing our custom match state, and which would return a boolean indicating if the match is included in the result or not. Optionally the function could return a second boolean to indicate that the search is now finished.

Maybe the ids have to be concatenated into a single string like:

var players = "aaa,bbb,ccc,ddd...."

and then queried using regular expressions:

var wantedId = "bbb"
var query = "+label.players:/.*" + wantedId + ".*"

This doesn’t seem too efficient for a real time game server.

If your players label contains array of player ids, you should be able to search for it with +labels.players:$id . There is a test for a similar case.

MatchList uses index which is updated every label_update_interval_ms (default is 1s, set in your match config) , so it should be pretty efficient.

Thank you for the tip. I did not try it yet though, as I for now moved the functionality that was in the label out to an external component. So now when I need to check if a player has a current match going on or when doing matchmaking I ask that component instead.