Enhance matchmaker to validate mode and create authoritative matches
- Implement MatchmakerMatched callback for true matchmaking flow - Enforce strict 1v1 pairing (ignore non-2 player matches) - Read `mode` from matchmaker ticket properties - Prevent mismatched-mode players from being paired - Automatically create authoritative `tictactoe` match when valid pair found - Provide match parameters so match handler receives selected mode - Improve logging for debugging and visibility Ensures clean, mode-aware matchmaking queues and proper server-side match creation.
This commit is contained in:
@@ -23,50 +23,39 @@ func MatchmakerMatched(
|
||||
) (string, error) {
|
||||
|
||||
if len(entries) != 2 {
|
||||
logger.Warn("MatchmakerMatched triggered but incorrect player count: %d", len(entries))
|
||||
return "", runtime.NewError("requires exactly 2 players", 3)
|
||||
logger.Warn("MatchmakerMatched triggered with %d players", len(entries))
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Extract player data
|
||||
ticketA := entries[0]
|
||||
ticketB := entries[1]
|
||||
|
||||
propsA := ticketA.GetProperties()
|
||||
propsB := ticketB.GetProperties()
|
||||
propsA := entries[0].GetProperties()
|
||||
propsB := entries[1].GetProperties()
|
||||
|
||||
modeA, okA := propsA["mode"].(string)
|
||||
modeB, okB := propsB["mode"].(string)
|
||||
|
||||
if !okA || !okB {
|
||||
logger.Error("Matchmaker ticket missing mode property")
|
||||
return "", runtime.NewError("matchmaking requires game mode", 13)
|
||||
logger.Warn("MatchmakerMatched missing mode property — ignoring")
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// ✅ Ensure both players queued for the same mode
|
||||
// ✅ If modes don’t match, let Nakama find another pairing
|
||||
if modeA != modeB {
|
||||
logger.Warn("Players queued for different modes: %s != %s", modeA, modeB)
|
||||
return "", runtime.NewError("players must select same mode", 3)
|
||||
logger.Warn("Mode mismatch %s vs %s — retrying matchmaking", modeA, modeB)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// ✅ Create authoritative match
|
||||
matchParams := map[string]interface{}{
|
||||
"mode": modeA,
|
||||
}
|
||||
|
||||
// ✅ Create authoritative match instance
|
||||
matchID, err := nk.MatchCreate(ctx, "tictactoe", matchParams)
|
||||
if err != nil {
|
||||
logger.Error("MatchCreate failed: %v", err)
|
||||
return "", runtime.NewError("failed to create match", 13)
|
||||
}
|
||||
|
||||
logger.Info("✅ Match created: %s — mode=%s — players=%s, %s",
|
||||
matchID,
|
||||
modeA,
|
||||
ticketA.GetPresence().GetUserId(),
|
||||
ticketB.GetPresence().GetUserId(),
|
||||
)
|
||||
|
||||
// ✅ Return match ID so Nakama notifies clients over WebSocket
|
||||
logger.Info("✅ Match created %s — mode=%s", matchID, modeA)
|
||||
return matchID, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user