Updated documenation/comments

This commit is contained in:
Joseph Holley
2018-11-16 05:23:30 -05:00
parent 008ac9c516
commit 4e4be7049e
3 changed files with 88 additions and 54 deletions

View File

@ -7,24 +7,50 @@ import 'api/protobuf-spec/messages.proto';
service Backend {
// Calls to ask the matchmaker to run a matchmaking function.
//
// Run MMF once. Return a matchobject that fits this profile.
// INPUT: MatchObject message with these fields populated:
// - id
// - properties
// - [optional] roster, any fields you fill are available to your MMF.
// - [optional] pools, any fields you fill are available to your MMF.
// OUTPUT: MatchObject message with these fields populated:
// - id
// - properties
// - error. Empty if no error was encountered
// - rosters, if you choose to fill them in your MMF. (Recommended)
// - pools, if you used the MMLogicAPI in your MMF. (Recommended, and provides stats)
rpc CreateMatch(messages.MatchObject) returns (messages.MatchObject) {}
// Continually run MMF and stream matchobjects that fit this profile until
// client closes the connection.
// client closes the connection. Same inputs/outputs as CreateMatch.
rpc ListMatches(messages.MatchObject) returns (stream messages.MatchObject) {}
// Delete a matchobject from state storage manually. (Matchobjects in state
// storage will also automatically expire after a while)
// INPUT: MatchObject message with the 'id' field populated.
// (All other fields are ignored.)
rpc DeleteMatch(messages.MatchObject) returns (messages.Result) {}
// Call for communication of connection info to players.
//
// Call fors communication of connection info to players.
// Write the connection info for the list of players in the
// Assignments.messages.Rosters to state storage. The FrontendAPI is
// responsible for sending anything written here to the game clients.
// responsible for sending anything sent here to the game clients.
// Sending a player to this function kicks off a process that removes
// the player from future matchmaking functions by adding them to the
// 'deindexed' player list and then deleting their player ID from state storage
// indexes.
// INPUT: Assignments message with these fields populated:
// - connection_info, anything you write to this string is sent to Frontend API
// - rosters. You can send any number of rosters, containing any number of
// player messages. All players from all rosters will be sent the connection_info.
// The only field in the Player object that is used by CreateAssignments is
// the id field. All others are silently ignored.
rpc CreateAssignments(messages.Assignments) returns (messages.Result) {}
// Remove DGS connection info from state storage for all players in the
// messages.Roster.
// Remove DGS connection info from state storage for players.
// INPUT: Roster message with the 'players' field populated.
// The only field in the Player object that is used by
// DeleteAssignments is the 'id' field. All others are silently ignored. If
// you need to delete multiple rosters, make multiple calls.
rpc DeleteAssignments(messages.Roster) returns (messages.Result) {}
}

View File

@ -2,66 +2,68 @@ syntax = 'proto3';
package messages;
option go_package = "github.com/GoogleCloudPlatform/open-match/internal/pb";
message Profile{
string id = 1; // By convention, a UUID
string properties = 2; // By convention, a JSON-encoded string
string name = 3; // OPTIONAL: Arbitrary developer-chosen, human-readable string.
// When you send a Profile to the backendAPI, it looks to see if you populated
// this field with protobuf-encoded PlayerPool objects containing valid the filters
// objects. If you did, they are used by OM. If you didn't, the backendAPI
// next looks in your properties blob at the key specified in the 'jsonkeys.pools'
// config value from config/matchmaker_config.json - If it finds valid player
// pool definitions at that key, it will try to unmarshal them into this field.
// If you didn't specify valid player pools in either place, OM assumes you
// know what you're doing and just leaves this unpopulatd.
repeated PlayerPool pools = 4; // Reserved by OM to store protobuf-encoded copies of your player pools.
}
// A MMF takes the Profile object above, and generates a MatchObject.
// Open Match's internal representation and wire protocol format for "MatchObjects".
// In order to request a match using the Backend API, your backend code should generate
// a new MatchObject with an ID and properties filled in (for more details about valid
// values for these fields, see the documentation). Open Match then sends the Match
// Object through to your matchmaking function, where you add players to 'rosters' and
// store any schemaless data you wish in the 'properties' field. The MatchObject
// is then sent, populated, out through the Backend API to your backend code.
//
// MatchObjects contain a number of fields, but many gRPC calls that take a
// MatchObject as input only require a few of them to be filled in. Check the
// gRPC function in question for more details.
message MatchObject{
string id = 1; // By convention, a UUID
string properties = 2; // By convention, a JSON-encoded string
string error = 3; // OUTPUT: Reserved by OM to return errors, useful to backend clients.
repeated Roster rosters = 4; // OUTPUT: Reserved by OM to store protobuf-encoded copies of the matchobject rosters.
repeated PlayerPool pools = 5; // OUTPUT: Reserved by OM to return filter stats, useful to backend API clients.
string error = 3; // Last error encountered.
repeated Roster rosters = 4; // Rosters of players.
repeated PlayerPool pools = 5; // 'Hard' filters, and the players who match them.
}
// Data structure to hold a list of players in a match.
// Data structure to hold a list of players in a match.
message Roster{
string name = 1; // OPTIONAL: Arbitrary developer-chosen, human-readable string. By convention, set to team name.
repeated Player players = 2; // REQUIRED: Player profiles on this roster.
string name = 1; // Arbitrary developer-chosen, human-readable string. By convention, set to team name.
repeated Player players = 2; // Player profiles on this roster.
}
// A filter to apply to the player pool.
// A 'hard' filter to apply to the player pool.
message Filter{
string name = 1; // OPTIONAL: Arbitrary developer-chosen, human-readable name of this filter. Appears in logs and metrics.
string attribute = 2; // REQUIRED: Name of the player attribute this filter operates on.
int64 maxv = 3; // OPTIONAL: Maximum value. Defaults to +inf.
int64 minv = 4; // OPTIONAL: Minimum value. Defaults to 0.
Stats stats = 5; // OUTPUT: Once a filter has been applied, this will be populated with information.
string name = 1; // Arbitrary developer-chosen, human-readable name of this filter. Appears in logs and metrics.
string attribute = 2; // Name of the player attribute this filter operates on.
int64 maxv = 3; // Maximum value. Defaults to positive infinity (any value above minv).
int64 minv = 4; // Minimum value. Defaults to 0.
Stats stats = 5; // Statistics for the last time the filter was applied.
}
// Holds statistics
message Stats{
int64 count = 1; // OUTPUT: Number of results returned from state storage.
double elapsed = 2; // OUTPUT: How long the state storage query took.
int64 count = 1; // Number of results.
double elapsed = 2; // How long it took to get the results.
}
// PlayerPools are defined by a set of 'hard' filters, and can be filled in
// with the players that match those filters.
//
// PlayerPools contain a number of fields, but many gRPC calls that take a
// PlayerPool as input only require a few of them to be filled in. Check the
// gRPC function in question for more details.
message PlayerPool{
string name = 1; // REQUIRED: Arbitrary developer-chosen, human-readable string.
repeated Filter filters = 2; // REQUIRED: All filters are logical AND-ed (a player must match every filter to be returned).
Roster roster = 3; // OUTPUT: Roster of players that matched all filters.
Stats stats = 4; // OUTPUT: Stats for all combined filters.
string name = 1; // Arbitrary developer-chosen, human-readable string.
repeated Filter filters = 2; // Filters are logical AND-ed (a player must match every filter).
Roster roster = 3; // Roster of players that match all filters.
Stats stats = 4; // Statisticss for the last time this Pool was retrieved from state storage.
}
// Data structure for a profile to pass to the matchmaking function.
// Data structure to hold details about a player
message Player{
message Attribute{
message Attribute{
string name = 1; // Name should match a Filter.attribute field.
int64 value = 2;
}
string id = 1; // By convention, a UUID
string properties = 2; // By convention, a JSON-encoded string
string pool = 3; // A PlayerPool with this name will be searched for this player.
string pool = 3; // Optionally used to specify the PlayerPool in which to find a player.
repeated Attribute attributes= 4; // Attributes of this player.
}
@ -76,12 +78,8 @@ message Result{
message IlInput{
}
// Epoch timestamp in seconds.
message Timestamp{
int64 ts = 1;
}
// Simple message used to pass the connection string for the DGS to the player.
// DEPRECATED: Likely to be integrated into another protobuf message in a future version.
message ConnectionInfo{
string connection_string = 1; // Passed by the matchmaker to game clients without modification.
}

View File

@ -5,10 +5,11 @@ option go_package = "github.com/GoogleCloudPlatform/open-match/internal/pb";
// The protobuf messages sent in the gRPC calls are defined 'messages.proto'.
import 'api/protobuf-spec/messages.proto';
// The MMLogic API provides utility functions for common MMF functionality, such
// as retreiving profiles and players from state storage, writing results to state storage,
// and exposing metrics and statistics.
service MmLogic {
// Profile and match object functions
// If your matchmaking logic makes a match, it should CreateProposal. If it
// cannot, it should ReturnError.
// Send GetProfile a match object with the ID field populated, it will return a
// 'filled' one.
@ -16,16 +17,20 @@ service MmLogic {
// backendapi when accepting a profile
rpc GetProfile(messages.MatchObject) returns (messages.MatchObject) {}
// CreateProposal does the following:
// CreateProposal is called by MMFs that wish to write their results to
// a proposed MatchObject, that can be sent out the Backend API once it has
// been approved (by default, by the evaluator process).
// - adds all players in the Roster to the proposed player ignore list
// - writes the proposed match to the provided key
// - adds that key to the list of proposals to be considered
// - [NYI] adds that key to the list of proposals to be considered
rpc CreateProposal(messages.MatchObject) returns (messages.Result) {}
// NYI
// ReturnError is called by MMFs that wish to notify that backend of an error.
rpc ReturnError(messages.Result) returns (messages.Result) {}
// Player listing and filtering functions
//
// RetrievePlayerPool gets the list of players for every Filter in the
// RetrievePlayerPool gets the list of players that match every Filter in the
// PlayerPool, and then removes all players it finds in the ignore list. It
// combines the results, and returns the resulting player pool.
rpc GetPlayerPool(messages.PlayerPool) returns (stream messages.PlayerPool) {}
@ -37,4 +42,9 @@ service MmLogic {
// RetrieveIgnoreList retrieves players from the ignore list specified in the
// config file under 'ignoreLists.proposedPlayers.key'.
rpc ListIgnoredPlayers(messages.IlInput) returns (messages.Roster) {}
// NYI
// UpdateMetrics sends stats about the MMF run to export to a metrics aggregation tool
// like Prometheus or StackDriver.
// rpc UpdateMetrics(messages.NYI) returns (messages.Results) {}
}