feat: add rpc_find_match for basic 2-player matchmaking

- Implement rpc_find_match Nakama RPC function
- Search for existing authoritative TicTacToe matches via MatchList
- Return first match with available slot (size < 2)
- Create new match using MatchCreate when none available
- Add request/response structs for future extensibility
- Log match search, selection, and creation flow
- Gracefully handle optional JSON payload and invalid input
This commit is contained in:
2025-11-26 16:09:48 +05:30
parent fa4d4d00be
commit 0fb448dd45
2 changed files with 74 additions and 0 deletions

View File

@@ -34,6 +34,10 @@ func InitModule(
logger.Error("Failed to register RPC: %v", err)
return err
}
if err := initializer.RegisterRpc("rpc_find_match", rpcFindMatch); err != nil {
logger.Error("RegisterRpc rpc_find_match failed: %v", err)
return err
}
logger.Info("Go module loaded successfully!")
return nil

70
plugins/matchmaking.go Normal file
View File

@@ -0,0 +1,70 @@
package main
import (
"context"
"database/sql"
"encoding/json"
"github.com/heroiclabs/nakama-common/runtime"
)
type FindMatchRequest struct{}
type FindMatchResponse struct {
MatchID string `json:"match_id"`
}
func rpcFindMatch(
ctx context.Context,
logger runtime.Logger,
db *sql.DB,
nk runtime.NakamaModule,
payload string,
) (string, error) {
logger.Info("rpc_find_match called")
var req FindMatchRequest
if payload != "" {
if err := json.Unmarshal([]byte(payload), &req); err != nil {
logger.Warn("rpc_find_match: invalid request payload: %v", err)
}
}
const limit = 10
authoritative := true
labelFilter := "tictactoe" // must match MatchInit label
var minSize, maxSize *int // nil = no constraint
matches, err := nk.MatchList(
ctx,
limit,
authoritative,
labelFilter,
minSize,
maxSize,
"", // query
)
if err != nil {
logger.Error("rpc_find_match: MatchList failed: %v", err)
return "", runtime.NewError("internal error", 13)
}
for _, m := range matches {
if m.Size < 2 {
logger.Info("rpc_find_match: found match %s with size=%d", m.MatchId, m.Size)
out, _ := json.Marshal(FindMatchResponse{MatchID: m.MatchId})
return string(out), nil
}
}
matchID, err := nk.MatchCreate(ctx, "tictactoe", map[string]interface{}{})
if err != nil {
logger.Error("rpc_find_match: MatchCreate failed: %v", err)
return "", runtime.NewError("internal error", 13)
}
logger.Info("rpc_find_match: created new match %s", matchID)
out, _ := json.Marshal(FindMatchResponse{MatchID: matchID})
return string(out), nil
}