timotheeg / nestrischamps

A web-based OCR and restreamer system for NES Classic Tetris players
MIT License
45 stars 11 forks source link

Derive Lines and Piece Stats from local computation instead of OCR #135

Closed timotheeg closed 1 year ago

timotheeg commented 1 year ago

Context

NestTrisChamps currently "reads" the value of lines and piece counters on the right., This is done by reading 3 digits per field, and in the case of lines, NestrisChamps assumes the line count will be below 500 for the majority of players, so it limits the detection of the first piece stats digits to be in (0, 1, 2, 3, 4)

As it turns out, Nestris players are now attempting to reach the point where the game breaks, like EricICX in his 6.4M game. That game had over 1400 lines, and several piece types above 500.

To capture values like these, NestrisChamps OCR would need to be upgraded to account for more characters (read the piece stats up to 600 or more, read lines, beyond 1600. Reading a greater character range takes more CPU cycle, and this only benefits a few top-level player at the detriment of the vast majority of NestrisChamps users.

An alternative to increasing the range of OCR is to realize that both lines and pieces stats are values that increases continuously during a game. lines may increase by 1, 2, 3, 4, and piece stats should increase only one at a time.

It is therefore possible to derive the values by computation rather than OCR. By reading and comparing only the unit digit of the values, and comparing with the previously read value, a calculation to derive the new value in an ever increasing way is easy.

By doing this, OCR of the the full values can be done only at the beginning of a game, and for manageable ranges, say

This PR implements the optimizations mentioned above:

  1. reduce the OCR range of the hundreds and tens digits for lines and piece stats, to just 0, 1, 2
  2. produces final value from computation by inspecting changes to the units digit alone

Risk and drawbacks

For example, say nestrischamps currently stores lines as 023, if the player jumps to say lines 119, nestrischamps will notice the unit value changes, but within the same tens cycle, and the computed result will display 039, rather than 119.

For normal games captured from a continuous video stream, that will not be a problem, but during calibration, players might be confused by the incorrect values.

timotheeg commented 1 year ago

One way to address the calibration display concern might be to have a 2-stage extraction of the lines and piece stats.

NestrisChamps users are expected to calibrate with a game at level 0, where lines and pieces stats will be very low (or or 1). deriving liens and pieces stats by computation is only necessary for game-breaking kind of games.

I'm thinking I will amend the code to:

The process resets at every game.

At calibration, even from a seekable video, we can assume a player will stay below level 29 (kill screen). With that assumption, lines will be below 230, and piece counters will mostly be below 100, so the behaviour described above should work fine. (See example values from EricICX's game for reference: image

Perhaps if we want to maintain read-from-ocr for most normal games all the way to kill screen, maybe the below would be even better:

Within a given game

Note that implementing the above will be cheaper than current nestrischamps which has a broader (and therefore more expensive) OCR range of 000 to 999 for lines, and 000 to 499 for piece counters.