今天我们要自己假订一个配对情境,来做一个比官方稍微复杂一点点的 Demo,并且透过这个模拟情境的实践,来熟悉 Open-Match 在实作上须满足的接口与函式用法。
随机产生两个地区、两种职业与不同等级条件的配对请求,并且将两个不同职业才能配对的逻辑,加入我们的配对逻辑中
移除官方 demo (若无部署可以跳过)
kubectl delete namespaces open-match-demo
下载本次范例用 yaml
open-match/open-match-role-location-demo.yml at example-a.2 · WeiWeiWesley/open-match
主要基於官方 yaml 替换掉 demo 与 mmf 的 images 为本次范例所需要的情境
- name: om-demo
image: "weiweiwesley/open-match:example-a.2"
...
- name: om-function
image: "weiweiwesley/mmf_role_location:diff_role.2"
...
部署
kubectl create namespace open-match-demo
kubectl apply -n open-match-demo -f open-match-role-location-demo.yml
以时间乱数产生不同的配对请求,分别将不同型态的条件放到 StringArgs
与 DoubleArgs
内。实务上这些资料,更可能是由捞取使用者资料库获得。
var ticketId string
{
ticket := &pb.Ticket{}
//随机产生不同条件
//两个地区
//两种职业
//等级 0~30
switch time.Now().Unix() % 4 {
case 0:
ticket.SearchFields = &pb.SearchFields{
StringArgs: map[string]string{
"location": "Asia/Taiwan",
"role": "knight",
},
DoubleArgs: map[string]float64{
"level": float64(rand.Int31n(30)),
},
}
case 1:
ticket.SearchFields = &pb.SearchFields{
StringArgs: map[string]string{
"location": "Asia/Taiwan",
"role": "archer",
},
DoubleArgs: map[string]float64{
"level": float64(rand.Int31n(30)),
},
}
case 2:
ticket.SearchFields = &pb.SearchFields{
StringArgs: map[string]string{
"location": "Asia/Japan",
"role": "knight",
},
DoubleArgs: map[string]float64{
"level": float64(rand.Int31n(30)),
},
}
case 3:
ticket.SearchFields = &pb.SearchFields{
StringArgs: map[string]string{
"location": "Asia/Japan",
"role": "archer",
},
DoubleArgs: map[string]float64{
"level": float64(rand.Int31n(30)),
},
}
}
req := &pb.CreateTicketRequest{Ticket: ticket}
s.Status = fmt.Sprintf("Create ticket role: %s location: %s", ticket.SearchFields.StringArgs["role"], ticket.SearchFields.StringArgs["location"])
update(s)
time.Sleep(time.Second)
resp, err := fe.CreateTicket(ctx, req)
if err != nil {
panic(err)
}
ticketId = resp.Id
}
Match Function 是我们实作配对逻辑的部份,这边可以看到我们能针对 ticket.SearchFields
的内容,对请求是否进行同场配对做筛选 ,previousRole
在记录下玩家角色後,会拒绝配对相同角色的玩家。
func makeMatches(poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
tickets := map[string]*pb.Ticket{}
for _, pool := range poolTickets {
for _, ticket := range pool {
tickets[ticket.GetId()] = ticket
}
}
var matches []*pb.Match
t := time.Now().Format("2006-01-02T15:04:05.00")
thisMatch := make([]*pb.Ticket, 0, 2)
matchNum := 0
previousRole := ""
for _, ticket := range tickets {
log.Println("pairing:", ticket.Id, ticket.SearchFields.StringArgs["role"])
//若同职业则会跳过此次配对
if previousRole != ticket.SearchFields.StringArgs["role"] {
thisMatch = append(thisMatch, ticket)
previousRole = ticket.SearchFields.StringArgs["role"]
}
if len(thisMatch) >= 2 {
matches = append(matches, &pb.Match{
MatchId: fmt.Sprintf("profile-%s-time-%s-num-%d", matchName, t, matchNum),
MatchProfile: matchName,
MatchFunction: matchName,
Tickets: thisMatch,
})
log.Println("pairing success", thisMatch[0].SearchFields.StringArgs["role"], thisMatch[1].SearchFields.StringArgs["role"])
previousRole = ""
thisMatch = make([]*pb.Ticket, 0, 2)
matchNum++
}
}
return matches, nil
}
基於 Open-Match 框架已经将 MMF 独立为一个服务实体启动,我们可以利用 kubernetes rolling update 的特性,动态的抽换线上的 MMF。我们可以试着将本篇范例的 MMF,再度更换为官方demo 的映像党,并重新 apply 上便可以再度恢复成任意两人即可配对成功。
更换 MMF
- name: om-function
image: "gcr.io/open-match-public-images/openmatch-mmf-go-soloduel:1.2.0"
Just apply again
kubectl apply -n open-match-demo -f open-match-role-location-demo.yml
单纯利用 tickets 的资料进行条件筛选,这在 client or MMF 实作上都是非常简易的,我们可以依照游戏的各种特性,以及玩家游玩过程与实体所产生的资料来产生不同的配对条件。本次范例中仅用两种不同角色即可配对,而那些没有配对到的玩家,会等到出现不同角色时才配对,这可能会发生一个尴尬的情况:如果大家都是选择相同角色时,所有人都会卡在配对等待中的状态。为了避免等待时间过长,之後一点的篇幅会再用一个范例来教大家如何释放 tickets。
此外由於本次范例是想沿用官方 demo 介面,直接从官方demo fork 出来异动,会有一些 golang 相依上的一些问题,这与 Open-Match 本身的使用上没有直接相关,所以为了让范例顺利已将 images 放在 dockerHub 上。
>>: [13th][Day7] container 处理程序
列出常见的针对 Windows 提权的脚本 Windows Vista/7 – Elevation ...
前篇回顾 sed - 简介 读取编辑文字档的好工具 sed - 2 Pattern sed - 3 ...
什麽是 Serverless ? 若要将应用程序部属到生产环境,会需要考虑很多问题,包括计算资源是否...
缘由: 开发时或多或少会遇到因某个条件地达成,需要显示或隐藏画面中的另一个条件,若是区块在最底部,直...
Auto-sklearn 今日学习目标 了解 Auto-sklearn 运作原理 Meta Lear...