{"record":{"id":"5f2510ff22d93592","repo":"babalae/better-genshin-impact","slug":"ocr-maxocrattempts-requiredstabl","errorCode":null,"errorMessage":"武器名称 OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOcrCount} 次一致，最大连续次数={stableNames.MaxConsecutiveCount}，末次原文={lastOcrText}，末次匹配={lastMatchedName}","messagePattern":"武器名称 OCR 在 (.+?) 次内未达到连续 (.+?) 次一致，最大连续次数=(.+?)，末次原文=(.+?)，末次匹配=(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterDevelopmentTask.cs","lineNumber":994,"sourceCode":"                        attempt, MaxOcrAttempts, lastOcrText, match.Name, match.Distance, match.Similarity);\n                }\n                else\n                {\n                    var isStable = stableNames.Add(match.Name);\n                    if (isStable)\n                    {\n                        return match.Name;\n                    }\n                }\n            }\n\n            if (attempt < MaxOcrAttempts)\n            {\n                await Delay(OcrRetryDelayMilliseconds, _ct);\n            }\n        }\n\n        throw new InvalidOperationException(\n            $\"武器名称 OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOcrCount} 次一致，\" +\n            $\"最大连续次数={stableNames.MaxConsecutiveCount}，末次原文={lastOcrText}，末次匹配={lastMatchedName}\");\n    }\n\n    private bool TryFindTalentPoints(ImageRegion capture, out List<Point> points)\n    {\n        var roi = GetTalentListRoi(capture);\n        var regions = capture.FindMulti(RecognitionObject.Ocr(roi));\n        try\n        {\n            var candidates = regions\n                .Where(region => region.Text.Contains(\"Lv\", StringComparison.OrdinalIgnoreCase))\n                .OrderBy(region => region.Y + region.Height / 2)\n                .ToList();\n            var minDistance = Math.Max(1, (int)Math.Round(30 * _assetScale));\n            points = [];\n            foreach (var region in candidates)\n            {","sourceCodeStart":976,"sourceCodeEnd":1012,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterDevelopmentTask.cs#L976-L1012","documentation":"`ReadWeaponNameWithRetry` repeats OCR + `WeaponNameMatcher.Match` up to 10 times, requiring 3 consecutive identical *matched standard names* (and each match must be `IsReliable`). If it never stabilizes, it throws with the raw OCR text and the last matched candidate. This guards against recording an uncorrected or jittery weapon name.","triggerScenarios":"OCR text is too garbled for `Match` to be reliable every time (distance > 1 or similarity < 2/3); the weapon isn't in `item.csv` so the nearest match keeps changing; the weapon-name ROI captures the wrong line.","commonSituations":"Newly released weapon absent from `Assets/Model/ItemV2/item.csv`; resolution mismatch moving the weapon-name ROI onto another element; stylized weapon text confusing OCR.","solutions":["Add the missing weapon to `item.csv` so `Match` can return a reliable, stable name.","Verify the weapon-name ROI (`Rect1080(1465,132,346,42)`) matches the current layout.","Loosen `WeaponNameMatcher` reliability thresholds only if false matches are acceptable.","Increase `MaxOcrAttempts` for genuinely noisy captures."],"exampleFix":"// before: weapon missing from item.csv → unreliable every attempt\n// after: add the weapon row to Assets/Model/ItemV2/item.csv with item_class_id starting 'weapon:'","handlingStrategy":"retry","validationCode":"// Ensure the weapon exists in the table before relying on Match:\nif (!WeaponNames.Value.Contains(standardWeapon)) { /* add to item.csv */ }","typeGuard":null,"tryCatchPattern":"try { await ReadWeaponNameWithRetry(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"武器名称 OCR\"))\n{ /* inspect lastOcrText/lastMatchedName; add weapon to item.csv or fix ROI */ }","preventionTips":["Keep Assets/Model/ItemV2/item.csv updated with new weapons.","Verify the weapon-name ROI matches the current layout.","Adjust WeaponNameMatcher reliability thresholds only after checking false-positive risk."],"tags":["ocr","retry-exhausted","weapon-name","levenshtein","item-csv","character-development"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}