From 3866c930652809067ea18947c4f7b1c86d0d8861 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Tue, 2 Jun 2026 00:57:25 -0400 Subject: [PATCH] refactor(matching): extend PairUpResult with IsAiFallback flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pure shape change ahead of Phase 3 AI-fallback wiring — all current callers pass IsAiFallback: false. TK2 will always emit false (PvpOnly policy); rank-battle's PvpFirstThenAiFallback branch sets true after the threshold elapses. Co-Authored-By: Claude Opus 4.7 --- .../Matching/IMatchingPairUpService.cs | 8 +++++++- SVSim.EmulatedEntrypoint/Matching/InProcessPairUp.cs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/SVSim.EmulatedEntrypoint/Matching/IMatchingPairUpService.cs b/SVSim.EmulatedEntrypoint/Matching/IMatchingPairUpService.cs index ffbadcc..551e4d6 100644 --- a/SVSim.EmulatedEntrypoint/Matching/IMatchingPairUpService.cs +++ b/SVSim.EmulatedEntrypoint/Matching/IMatchingPairUpService.cs @@ -34,5 +34,11 @@ public interface IMatchingPairUpService /// nothing else in TK2/ranked reads. We send the split anyway for prod fidelity in /// case a future flow (rematch UI, private rooms grafted on top) starts consuming it. /// +/// +/// is true when the resolution came from the +/// PvpFirstThenAiFallback policy expiring its threshold — caller is paired +/// with a silent NoOpBotParticipant. Maps to matching_state 3011 +/// (AI_BATTLE_MATCHING_SUCCEEDED). Always false for PvpOnly modes (TK2). +/// /// -public sealed record PairUpResult(PendingMatch Match, bool IsOwner); +public sealed record PairUpResult(PendingMatch Match, bool IsOwner, bool IsAiFallback); diff --git a/SVSim.EmulatedEntrypoint/Matching/InProcessPairUp.cs b/SVSim.EmulatedEntrypoint/Matching/InProcessPairUp.cs index 59e2b15..d611ddf 100644 --- a/SVSim.EmulatedEntrypoint/Matching/InProcessPairUp.cs +++ b/SVSim.EmulatedEntrypoint/Matching/InProcessPairUp.cs @@ -28,7 +28,7 @@ public sealed class InProcessPairUp : IMatchingPairUpService if (slot.Resolved.TryGetValue(player.ViewerId, out var cached)) { slot.Resolved.Remove(player.ViewerId); - return Task.FromResult(new PairUpResult(cached, IsOwner: true)); + return Task.FromResult(new PairUpResult(cached, IsOwner: true, IsAiFallback: false)); } // 2. Someone already waiting in this slot? Pair with them. @@ -46,7 +46,7 @@ public sealed class InProcessPairUp : IMatchingPairUpService var match = _bridge.RegisterBattle(p1, p2, BattleType.Pvp); // Cache the result for the FIRST arriver's next poll (consume-on-read). slot.Resolved[p1.ViewerId] = match; - return Task.FromResult(new PairUpResult(match, IsOwner: false)); + return Task.FromResult(new PairUpResult(match, IsOwner: false, IsAiFallback: false)); } // 3. Empty slot — park this caller.