Skip to content

fix: Add OCR cooldown guard to prevent skill spam false positives#2195

Closed
DCPMA wants to merge 4 commits intoFate-Grand-Automata:masterfrom
DCPMA:fix/skill-spam-cooldown-ocr-guard
Closed

fix: Add OCR cooldown guard to prevent skill spam false positives#2195
DCPMA wants to merge 4 commits intoFate-Grand-Automata:masterfrom
DCPMA:fix/skill-spam-cooldown-ocr-guard

Conversation

@DCPMA
Copy link
Copy Markdown

@DCPMA DCPMA commented Mar 16, 2026

Problem

Skill spam occasionally fires skills that are still on cooldown. This happens because the readiness check uses a small 30×30 icon match (imageRegion). When a cooldown number is displayed over the skill button, thin glyphs like 1 and 4 don't occlude enough pixels in that sample area, so the icon match still passes the similarity threshold and the skill is cast incorrectly.

This has been reported as a recurring problem (see #2073, #874, #540). Note: #2076 addresses the related "stuck window" symptom (wrong close-click coordinate); this PR addresses the separate root cause of the incorrect cast itself.

Related issue

Related pull request

Fix

Add a secondary OCR guard that reads the cooldown number region of each skill button. If a numeric cooldown is detected, the cast is suppressed regardless of what the icon match says.

BattleScreenLocations — adds cooldownTextRegion() targeting the area where the cooldown number text is rendered. The region is offset from the skill locate() point.

SkillSpam — replaces the direct in imageRegion check with isReadyForSpam(), which:

  1. Takes a snapshot and checks both icon match and that no cooldown digit is present (via OCR)
  2. If that passes, waits 100 ms and re-checks (stability gate to avoid frame-boundary false positives)
  3. Only then allows the cast

The OCR step normalises common Tesseract misreads (O0, I/l1) before extracting the number with a \d+ regex.

Scope

  • Changes are isolated to SkillSpam and BattleScreenLocations
  • Normal command-script skill casting is unaffected
  • No new settings or preferences added

Testing

Verified on TW server via BlueStacks with a debug build.

Thin cooldown glyphs (1, 4) don't occlude enough pixels in the existing
30x30 icon-match region, causing isReadyForSpam to return true while a
skill is still on cooldown.

Add cooldownTextRegion() in BattleScreenLocations targeting the 96x48
area where the cooldown number is rendered. In SkillSpam, replace the
direct imageRegion check with isReadyForSpam(), which requires both the
icon similarity check (>=0.9) and an OCR confirmation that no cooldown
digit is present. A 100ms stability re-check is also required before
the cast is allowed.

Common Tesseract misreads (O->0, I/l->1) are normalised before digit
extraction. Changes are isolated to SkillSpam; command-script skill
casting is unaffected.

Fixes Fate-Grand-Automata#2073
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 16, 2026

Build 957

Download the latest APK for testing here

Note

You need a GitHub account to download the APK.

This URL is valid as long as the artifact has not expired yet.

Per the contribution guide, manual similarity values in Region.exists()
should be avoided. Replace explicit similarity=0.9 with the in operator
(Region.contains) so the user's Fine-Tune min similarity setting is
respected, consistent with the rest of the codebase.

Remove the now-unused skillReadySimilarity constant.

This comment was marked as outdated.

DCPMA and others added 2 commits March 16, 2026 15:25
- Import Skill and use Skill.Servant instead of fully-qualified name,
  consistent with Caster.kt and the rest of the codebase
- Extract duplicated readiness predicate into local checkReady() to
  avoid repeating the icon-match + cooldown-guard expression
The cooldownTextRegion was positioned at y-offset 108 from the skill
locate() point, which lands on the NP bar area instead of the cooldown
text. ADB screenshot analysis confirmed the "剩餘X" (remaining X turns)
text renders at y-offset 40-90 from locate(). The old region never
captured any digits, making the OCR guard ineffective.

Changed from Region(8, 108, 96, 48) to Region(-5, 40, 100, 55) which
correctly covers the cooldown text area across all 9 skill positions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@DCPMA
Copy link
Copy Markdown
Author

DCPMA commented Mar 22, 2026

Closing — the underlying issue (skill spam false positives during cooldown) is still persisting despite this approach. Will revisit with a different strategy.

@DCPMA DCPMA closed this Mar 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants