babalae/better-genshin-impact · error · InvalidOperationException
未检测到合法角色卡片。
Error message
未检测到合法角色卡片。
What it means
`FindAndClickAvatar` runs `DetectCharacterCards` (white-bar connected-component detection) up to `EmptyDetectionRetryCount` (3) times per grid page. If no valid card is produced on all three attempts it throws, because the avatar model cannot run without candidate cards. This usually means the grid ROI doesn't actually contain the character list (wrong screen, overlay, or detection threshold).
Source
Thrown at BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterSelectionHelper.cs:244
for (var attempt = 1; attempt <= EmptyDetectionRetryCount; attempt++)
{
using var capture = CaptureToRectArea();
using var gridRegion = capture.DeriveCrop(gridRoi);
var cards = DetectCharacterCards(
gridRegion.SrcMat, assetScale, out var rejectedCount, out var connectedComponentCount);
logger.LogDebug(
"角色养成识别:白色底栏连通域 {ConnectedComponentCount} 个,生成 {CardCount} 个合法卡片,边界丢弃 {RejectedCount} 个(第 {Attempt}/{RetryCount} 次)",
connectedComponentCount, cards.Count, rejectedCount, attempt, EmptyDetectionRetryCount);
if (cards.Count == 0)
{
if (attempt < EmptyDetectionRetryCount)
{
await Delay(200, ct);
continue;
}
throw new InvalidOperationException("未检测到合法角色卡片。");
}
foreach (var card in cards.OrderBy(card => card.CardRect.Y).ThenBy(card => card.CardRect.X))
{
using var cardRegion = gridRegion.DeriveCrop(card.CardRect);
using var avatar = gridRegion.SrcMat.SubMat(card.AvatarRect);
using var element = gridRegion.SrcMat.SubMat(card.ElementRect);
var candidate = recognizer.Recognize(avatar, element, target.RecognizeElementType);
logger.LogDebug("角色养成识别:识别头像 {CharacterName},元素={ElementType},score={Score:0.000}",
candidate.CharacterName, candidate.ElementType, candidate.Score);
if (target.Matches(candidate.CharacterName) && candidate.Score >= MatchThreshold)
{
cardRegion.Click();
await Delay(300, ct);
return candidate;
}
}
View on GitHub (pinned to a7cb36712d)
Solutions
- Confirm the task is actually on the character list screen when this handler runs (fix upstream state detection).
- Verify capture resolution and `_assetScale` match the 1080p-based grid ROI and card-size constants.
- Tune `FixedSizeGridCardDetector` thresholds if the white-bar styling changed.
- Increase `EmptyDetectionRetryCount` and the inter-retry delay if the panel opens slowly.
Example fix
// before: handler runs while filter panel still open → no cards
// after: strengthen IsCharacterList detector so FindAndClickAvatar only runs on the real list
if (!CharacterSelectionHelper.IsFilterPanel(capture, scale)) { /* proceed */ } Defensive patterns
Strategy: retry
Validate before calling
// Ensure FindAndClickAvatar only runs on the real character list:
if (!IsCharacterList(capture) || CharacterSelectionHelper.IsFilterPanel(capture, scale))
return StateHandlerResult.Wait; Try / catch
try { await FindAndClickAvatar(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("未检测到合法角色卡片"))
{ /* verify screen state, capture scale, and card detector thresholds */ } Prevention
- Strengthen IsCharacterList detection so the handler only runs on the real list.
- Verify capture resolution/_assetScale match the 1080p grid ROI and card-size constants.
- Tune FixedSizeGridCardDetector thresholds when the white-bar styling changes.
When it happens
Trigger: The grid ROI (`GridRoi1080 = (40,76,641,897)`) covers an empty/non-list area; the character list panel failed to open; an overlay (notification, toast) covers the grid; detection thresholds reject all connected components; resolution mismatch shrinks the effective ROI.
Common situations: State machine thinks it's on the character list but isn't (filter panel still open, animation in progress); capture scale wrong so card sizes fall outside the detector; UI theme/event overlay changing the white-bar appearance.
Related errors
- 角色养成识别:头像识别器尚未初始化。
- 角色养成识别:当前角色尚未初始化。
- 角色养成识别:当前结果尚未初始化。
- 角色 {CurrentTarget.Name} 缺少武器筛选类型。
- 未找到目标角色 {CurrentTarget.Name}。
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/953afb997b286d4f.
Report an issue: GitHub.