babalae/better-genshin-impact · error · InvalidOperationException
{fieldName} OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOc
Error message
{fieldName} OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOcrCount} 次一致,最大连续次数={stableValues.MaxConsecutiveCount},末次结果={lastText} What it means
`ReadLevelPairWithRetry` samples the level text up to `MaxOcrAttempts` (10) times, requiring `RequiredStableOcrCount` (3) consecutive identical parses. If it never achieves three-in-a-row it throws, reporting the best streak and the last raw text. This protects against returning a noisy/wrong level/limit pair.
Source
Thrown at BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterDevelopmentTask.cs:942
if (isStable)
{
return (level, limit);
}
}
else
{
stableValues.Reset();
_logger.LogDebug("角色养成识别:{FieldName} OCR 第 {Attempt}/{MaxAttempts} 次解析失败,结果={Text}",
fieldName, attempt, MaxOcrAttempts, lastText);
}
if (attempt < MaxOcrAttempts)
{
await Delay(OcrRetryDelayMilliseconds, _ct);
}
}
throw new InvalidOperationException(
$"{fieldName} OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOcrCount} 次一致," +
$"最大连续次数={stableValues.MaxConsecutiveCount},末次结果={lastText}");
}
/// <summary>
/// 重复 OCR 武器名,并先通过标准武器表纠错;纠错后的名称连续三次一致才返回。
/// </summary>
private async Task<string> ReadWeaponNameWithRetry()
{
var stableNames = new StableValueAccumulator<string>(RequiredStableOcrCount);
var lastOcrText = string.Empty;
var lastMatchedName = string.Empty;
for (var attempt = 1; attempt <= MaxOcrAttempts; attempt++)
{
using var capture = CaptureToRectArea();
lastOcrText = OcrText(
capture,
Rect1080(1465, 132, 346, 42)).Trim();View on GitHub (pinned to a7cb36712d)
Solutions
- Confirm the capture resolution and `_assetScale` produce an ROI that actually covers the level text.
- Raise `MaxOcrAttempts` / add a longer `OcrRetryDelayMilliseconds` if jitter is transient.
- Update the level ROI constants if the in-game layout changed.
- Preprocess the ROI (threshold/upscale) to stabilize PaddleOCR output.
Example fix
// before: ROI misaligned, never stable var (lvl, lim) = await ReadLevelPairWithRetry(Rect1080(1467,207,172,35), "角色等级"); // after: correct ROI for current layout, or increase attempts private const int MaxOcrAttempts = 20;
Defensive patterns
Strategy: retry
Validate before calling
// The loop already retries 10×; prevent by ensuring the ROI is correct: // verify _assetScale and the level ROI cover 'Lv.X/Y' at the current resolution.
Try / catch
try { await ReadLevelPairWithRetry(roi, fieldName); }
catch (InvalidOperationException ex) when (ex.Message.Contains("OCR"))
{ /* log lastText, check ROI/scale, optionally raise MaxOcrAttempts */ } Prevention
- Confirm capture resolution and _assetScale place the ROI on the level text.
- Update level ROI constants when the in-game layout changes.
- Increase MaxOcrAttempts / retry delay for genuinely noisy captures.
When it happens
Trigger: Persistent OCR jitter on the level ROI (e.g. 'Lv.90/90' flickering between parses); the ROI covering the wrong region so it never parses two numbers; animations/particles overlapping the level text.
Common situations: Wrong capture resolution breaking the 1080p-scaled ROI; a game UI change moving the level text; slow render making early frames unreadable; anti-aliasing/overlay interference.
Related errors
- 天赋详情 OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOcrCount}
- 武器名称 OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOcrCount}
- 无法从 {fieldName} OCR 结果中解析等级:{text}
- 图像通道数必须为3,当前为{channels}
- Unable to GetLabelByIndex: index {i} out of range {labels.Co
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/6b4c49a839eb2b54.
Report an issue: GitHub.