feat(mm): wait longer for a real opponent; add "start with bots now"
- server: a lone player in the online-league queue now keeps waiting (re-checking every 15s) up to 75s so an online opponent has a real chance to join; the moment a 2nd human queues they're matched together, and a full 4 still forms instantly. Add PlayNow hub method to force-start with bots on demand. - client: matchmaking screen shows a "شروع با ربات / Start with bots" button after a few seconds so the player can skip the wait; waiting copy updated; raise the "connection stuck" hint threshold to 90s so it no longer fires during normal waits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -984,6 +984,35 @@ export class MockOnlineService implements OnlineService {
|
||||
this.matchmaking.phase = "idle";
|
||||
}
|
||||
|
||||
async playNow() {
|
||||
if (this.matchmaking.phase !== "searching" && this.matchmaking.phase !== "queued") return;
|
||||
const me = this.profile!;
|
||||
// Keep whoever has already joined; fill the remaining seats with bots.
|
||||
const players = this.matchmaking.players.slice();
|
||||
while (players.length < 4) {
|
||||
players.push({
|
||||
id: rid("bot"),
|
||||
displayName: pick(PERSIAN_NAMES),
|
||||
avatar: pick(AVATARS).id,
|
||||
level: randInt(1, 50),
|
||||
rating: me.rating + randInt(-150, 150),
|
||||
});
|
||||
}
|
||||
this.matchmaking.players = players;
|
||||
this.matchmaking.phase = "found";
|
||||
this.emitMM();
|
||||
this.after(700, () => {
|
||||
if (this.matchmaking.phase !== "found") return;
|
||||
this.matchmaking.phase = "ready";
|
||||
this.matchPlayers = players.map((p) => ({
|
||||
id: p.id, displayName: p.displayName, avatar: p.avatar, level: p.level,
|
||||
}));
|
||||
const opps = players.slice(1);
|
||||
this.currentOppRating = opps.reduce((s, p) => s + p.rating, 0) / Math.max(1, opps.length);
|
||||
this.emitMM();
|
||||
});
|
||||
}
|
||||
|
||||
onMatchmaking(cb: (s: MatchmakingState) => void): Unsubscribe {
|
||||
this.mmCbs.add(cb);
|
||||
return () => this.mmCbs.delete(cb);
|
||||
|
||||
@@ -132,6 +132,8 @@ export interface OnlineService {
|
||||
/* ----- matchmaking ----- */
|
||||
startMatchmaking(opts: MatchmakingOptions): Promise<void>;
|
||||
cancelMatchmaking(): Promise<void>;
|
||||
/** Stop waiting for online players — start now, filling empty seats with bots. */
|
||||
playNow(): Promise<void>;
|
||||
onMatchmaking(cb: (state: MatchmakingState) => void): Unsubscribe;
|
||||
|
||||
/* ----- match players (for the online game driver) ----- */
|
||||
|
||||
@@ -310,6 +310,10 @@ export class SignalrService implements OnlineService {
|
||||
this.emitMM("idle");
|
||||
}
|
||||
|
||||
async playNow() {
|
||||
await this.conn?.invoke("PlayNow");
|
||||
}
|
||||
|
||||
onMatchmaking(cb: (s: MatchmakingState) => void): Unsubscribe {
|
||||
this.mmCbs.add(cb);
|
||||
return () => this.mmCbs.delete(cb);
|
||||
|
||||
Reference in New Issue
Block a user