babalae/better-genshin-impact · error · PartySetupFailedException

切换角色:连续 3 次未检测到合法角色卡片

Error message

切换角色:连续 3 次未检测到合法角色卡片

What it means

Inside the card-detection retry loop of RecognizeTeamSlotsFromCharacterList, DetectCharacterCards returned zero accepted cards for all EmptyCardDetectionRetryCount (3) attempts on the final pass. With no cards the avatar set is empty, so recognition is aborted.

Source

Thrown at BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs:1402

            for (var attempt = 1; attempt <= EmptyCardDetectionRetryCount; attempt++)
            {
                using var capture = CaptureToRectArea(true);
                using var gridRegion = capture.DeriveCrop(gridRoi);
                var cards = DetectCharacterCards(
                    gridRegion.SrcMat, out var rejectedCount, out var connectedComponentCount);
                lastDetectedCardCount = cards.Count;
                LogCardDetection(cards, rejectedCount, connectedComponentCount, attempt);
                if (cards.Count < expectedTeamCount)
                {
                    if (attempt < EmptyCardDetectionRetryCount)
                    {
                        await Delay(200, ct);
                        continue;
                    }

                    if (cards.Count == 0)
                    {
                        throw new PartySetupFailedException("切换角色:连续 3 次未检测到合法角色卡片");
                    }
                }

                foreach (var card in cards
                             .OrderBy(card => card.CardRect.Y)
                             .ThenBy(card => card.CardRect.X)
                             .Take(expectedTeamCount))
                {
                    using var avatar = gridRegion.SrcMat.SubMat(card.AvatarRect);
                    var candidate = recognizer.Recognize(avatar);
                    _logger.LogDebug(
                        "切换角色:RECT({X},{Y},{Width},{Height}),角色={CharacterName},score={Score:0.000}",
                        card.CardRect.X,
                        card.CardRect.Y,
                        card.CardRect.Width,
                        card.CardRect.Height,
                        candidate.CharacterName,
                        candidate.Score);

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Inspect the LogCardDetection output (rejectedCount, connectedComponentCount) to see if candidates exist but are rejected — tune DetectCharacterCards thresholds.
  2. Confirm CharacterGridRoi1080 still bounds the grid in the current game version.
  3. Verify capture resolution/assetScale so the grid crop is sized as expected.
  4. If the grid legitimately has fewer than expected cards, reconcile expectedTeamCount rather than requiring 3.
Defensive patterns

Strategy: try-catch

Try / catch

try { await switchTask.Start(...); }
catch (PartySetupFailedException ex) when (ex.Message.Contains("未检测到合法角色卡片"))
{ _logger.LogError(ex, "角色卡片检测失败:检查网格 ROI 与 DetectCharacterCards 阈值"); }

Prevention

When it happens

Trigger: On attempt == EmptyCardDetectionRetryCount, cards.Count < expectedTeamCount and cards.Count == 0 — every card candidate was rejected by DetectCharacterCards (rejectedCount/connectedComponentCount logged via LogCardDetection) across all 3 passes.

Common situations: The character grid ROI CharacterGridRoi1080(24,86,766,743) is wrong for the current layout so the crop is blank; DetectCharacterCards' connected-component/threshold heuristics reject everything under different lighting or UI theming; the list is filtered to a state with no visible cards; capture scale mismatch.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/155b3324f29c0097. Report an issue: GitHub.