一键回到牌桌
结算画面现在可以直接再开一局同样的游戏,而「快速匹配」会把你放进一间已经在坐满的房间,而不是再开一间空房。

通俗版
开始一局游戏的最佳时机,就是上一局结束的那一秒。证据一直摆在眼前,我们却把它浪费了:回来打第二局的玩家里,超过一半是在上一局结束后两分钟内开始的——而我们在那一刻给他们的,只是一个回大厅的链接,然后还要选模式、选人数、建房间、等人。
现在结算画面上有一个「再来一局」按钮。点一下,你就进入了新的一局:同样的模式、同样的人数、空位已经坐满、游戏已经开始。不用回大厅,也没有任何设置要调。

「快速匹配」是同一个问题在大厅里的另一半。它以前是个按了没反应的按钮。现在它会把你送进你所选模式下最合适的一间开放房间:先看是不是真人建的房,再看哪一间最接近开局,最后看哪一间等得最久。只有确实没有房间可加入时,它才为你新开一间。
技术细节
「再来一局」没有新增任何服务端接口。它做的正是玩家手动做的事——建房间、逐个安排机器人入座(这个调用会挑下一个空位,并行执行会抢同一个座位),然后开局——每一步都以该玩家的身份授权,所以你自己建房时适用的每条规则在这里同样适用。
这一点很重要,因为按下按钮的是谁。首局离场里十有八九是投降而非破产,所以常见情形是有人离开了一局对其他人还在继续的游戏。它能成立,是因为已经退出一局的玩家不再被算作「正在一局中」——这条规则一年前是为另一个原因上线的,如今正是它让「再来一局」按钮合法。
「快速匹配」把决策放在一个纯函数里,所以不需要大厅和数据库就能测试。模式是筛选条件而不是偏好:选了闪电局却被丢进半小时的经典局,比稍等一会儿更糟。
// lib/lobby/quickMatch.ts — which open room to try, in order
.sort((a, b) => {
// 1. a human host: pool the people who are actually online
if (a.creator_is_bot !== b.creator_is_bot) return a.creator_is_bot ? 1 : -1;
// 2. fewest free seats: a nearly-full room starts sooner
const freeA = a.max_players - a.player_count;
const freeB = b.max_players - b.player_count;
if (freeA !== freeB) return freeA - freeB;
// 3. oldest: whoever has waited longest gets company first
return Date.parse(a.created_at) - Date.parse(b.created_at);
});返回的是排好序的完整列表而不是单一选择,因为座位数只是一个瞬间快照:调用方会沿列表往下走,直到某次加入真正成功——这就避免了两个人抢最后一个座位、结果两人都独自一间房。
