Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Eden Season Rewards Screenshot Processor

Automatically reads player contribution screenshots using OCR and writes the extracted values into the correct rows of the Eden rewards Excel spreadsheet.


Prerequisites

  • Python 3.10 or later (py --version to check)
  • Install dependencies once:
py -m pip install -r requirements.txt

EasyOCR downloads its model files (~50 MB) on first use. This happens automatically and only once.


Quick Start

1 — Preview only (safe, no writes)

py main.py

Processes all screenshots in x[seasonNumber]-screenshots#/ and prints a table of every player, extracted values, and the Excel row they would be written to. Nothing is written to the spreadsheet.

It is useful to be able to test this first to check that the OCR is extracting values correctly and that the correct Excel rows are being identified before committing any writes.

To test 10 images as an example

py main.py --limit 10

2 — Write with confirmation

py main.py --write

Shows the same preview table, then asks:

Write [xxx] rows to the spreadsheet? [y/N]

Type y to confirm. Any row with an ERROR is always skipped regardless.

3 — Write immediately (no prompt)

py main.py --write --yes

4 — Single image (dry-run)

py main.py --image "x[seasonNumber]-screenshots#\filename.jpg"

5 — Single image with manual ranking override

Use this for the ~9 top-ranked players where the small single-digit ranking number cannot be read by OCR. Look at the screenshot, confirm the ranking number yourself, then run:

py main.py --image "x[seasonNumber]-screenshots#\filename.jpg" --set-ranking 1 --write --yes

Replace 1 with the actual ranking shown in the screenshot.

For example, Player1 as rank 1 will have his screenshot read with ranking None and an ERROR status. Running the above command with --set-ranking 1 will override the OCR result and write his data to the correct row in the spreadsheet.


Output Table

     #  Player                     Row       Contrib   Season Pts       Merits         Demo   Occupy   Status
────────────────────────────────────────────────────────────────────────────────────────────────────────
   116  Chris                       120    1,234,567    5,678,901    2,345,678    1,234,567      987   OK
   131  Jenny                       135    9,876,543   12,345,678    4,567,890      876,543    1,234   WARN: ...
     7  Bungle                      ?            —            —            —            —        —   ERROR: Ranking not found — needs manual entry (player: Bungle)
Column Meaning
# Ranking extracted from screenshot (col B lookup key)
Player Player name with guild tag stripped
Row Excel row number the data will be written to (? = not found)
Values Extracted integers ( = not found/not written)
Status OK / WARN / LOW CONF / ERROR (see below)

Status meanings

Status Description Written?
OK All values extracted with high confidence Yes
WARN A value was missing or an optional field defaulted to zero Yes
LOW CONF OCR read a value but confidence score was below 75% Yes
ERROR Ranking could not be determined — cannot find correct Excel row No

LOW CONF values are written but should be spot-checked against the screenshot. In most cases they are correct but just below the confidence threshold. If a LOW CONF value is wrong, it can be corrected manually in Excel after checking.


What Gets Written to Excel

Excel Column Field Notes
A Player name Guild tag stripped
B Ranking Also used to find the correct row
C Contribution
D Season Points
G Merits
K Demolition
O Occupy

Columns E, F, H, I, J, L, M, N, P–Y are never touched. These contain formulas and manually-entered SS (Screenshot-verified) values.

The spreadsheet must be closed in Excel before running with --write.


File Layout

screenreader/
├── main.py                         ← entry point (run this)
├── extractor.py                    ← OCR logic
├── writer.py                       ← Excel write logic
├── requirements.txt
├── eden-x[seasonNumber]-rewards-working.xlsx   ← spreadsheet (must be in this folder)
└── x[seasonNumber]-screenshots#/               ← drop .jpg screenshots here

Adjusting OCR Mapping for Different Screenshot Sizes

The OCR works by reading text positions as fractions of the image dimensions (0.0 = left/top, 1.0 = right/bottom). This means the mapping is resolution-independent — it works whether the screenshot is 1080p or 4K.

However, if screenshots come from a different device or game UI layout (e.g. a different aspect ratio, zoomed-in UI, or a different language), the positions of the key text regions may have shifted. All tunable constants are at the top of extractor.py.

Constants to adjust

# extractor.py — lines ~50–70

# ─── Header block (Ranking / Contribution info at the top of the screenshot) ─
HEADER_Y_MIN = 0.13    # Y fraction where the header block starts
HEADER_Y_MAX = 0.255   # Y fraction where the header block ends
#   Ranking label sits at ~Y 0.214, Contribution at ~Y 0.192
#   Must stay below 0.26 to exclude the 'Contribution Type' table header row

HEADER_VAL_X_MIN = 0.58   # Values in the header are right-aligned from here

# ─── Amount column in the contribution table ──────────────────────────────────
AMOUNT_X_MIN = 0.28   # Left edge of the Amount column
AMOUNT_X_MAX = 0.65   # Right edge (Convert Contribution column starts at ~0.75)
#   The table has 3 columns: Contribution Type | Amount | Convert Contribution
#   Only Amount is extracted. X range must exclude the rightmost column.

# ─── OCR grouping tolerance ───────────────────────────────────────────────────
LINE_Y_TOL = 12        # pixels — items within this vertical distance are
                       # grouped into the same text line

# ─── Confidence threshold ─────────────────────────────────────────────────────
LOW_CONF_THRESHOLD = 0.75   # OCR confidence below this → flagged as LOW CONF

How to calibrate for a new screenshot layout

  1. Pick one screenshot that represents the new layout. Make sure all screenshots are the same layout and resolution for consistent results. Ideally same device and same in-game UI settings.

  2. Run the diagnostic script to see where OCR is finding each text item:

py temp_check.py "x[seasonNumber]-screenshots#\your_image.jpg"

This prints every OCR result with its normalised X/Y position so you can see exactly where each label and value appears.

  1. Identify the Y range that contains only the Ranking and Contribution header lines — update HEADER_Y_MIN and HEADER_Y_MAX to bracket them.

  2. Identify the X range that covers only the Amount column — update AMOUNT_X_MIN and AMOUNT_X_MAX. The key constraint is that the right edge must be left of the "Convert Contribution" column.

  3. Run py main.py again to verify the values are now extracted correctly.

Typical problems and fixes

Symptom Likely cause Fix
Ranking always None Header block out of Y range Widen HEADER_Y_MIN/HEADER_Y_MAX
Contribution picks up table row values Header Y range too wide Tighten HEADER_Y_MAX to exclude table rows
Amount shows "Convert Contribution" number AMOUNT_X_MAX too large Reduce AMOUNT_X_MAX below ~0.65
Values cut off (missing digits) AMOUNT_X_MIN too large Reduce AMOUNT_X_MIN
Lines not grouping correctly Screenshots are lower resolution Increase LINE_Y_TOL (try 16–20)
Too many LOW CONF flags Expected for this set of screenshots Lower LOW_CONF_THRESHOLD to e.g. 0.60

Known Limitation — Top-Ranked Players (Rankings 1–9)

EasyOCR does not reliably read single-digit ranking numbers at full image scale. The root cause is that rankings 1–9 occupy a very small number of pixels, and the model either misses them entirely or reads the wrong digit.

A crop-and-re-OCR fallback was tested but produced incorrect values (e.g. "1" was read as "3", "7" as "4"). Since a wrong ranking would write data to the wrong player's row, the fallback was removed in favour of accuracy.

Resolution: Use --set-ranking to supply the correct ranking manually for each affected image. There are typically ~9 such images per season (ranks 1–9). The player name is always shown in the ERROR output so you know which screenshot to reprocess.


Season Changeover

At the start of each new season:

  1. Update the season multipliers in Excel row 2 (columns Z–AC) if they change.
  2. Drop the new season's .jpg screenshots into x[seasonNumber]-screenshots#/.
  3. Run py main.py for a preview, then py main.py --write to commit.
  4. Handle any ERRORs with --set-ranking as described above.
  5. The Excel formulas in the protected columns recalculate automatically.

Troubleshooting

"Permission denied" when writing
The spreadsheet is open in Excel. Close it first, then retry.

"Sheet 'Points Per Person' not found"
The spreadsheet has been renamed or the sheet tab has been renamed. Update SHEET_NAME in writer.py to match.

"No .jpg files found"
Check that screenshots are in the x[seasonNumber]-screenshots#/ subfolder (note the # in the folder name) and are .jpg files (not .png or .jpeg).

OCR model download fails
EasyOCR needs internet access the first time it runs. Once the model is cached locally it works offline.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages