Giter Club home page Giter Club logo

nestrischamps's Introduction

NESTrisChamps

NESTrisChamps is a browser-based game capture and rendering system for NES classic Tetris.

It is available online under the domain nestrischamps.io

NESTrisChamps is composed of 3 main parts:

  • A browser based capture system
    • Supports both capture devices and screen capture
    • Supports 2 roms: Classic Tetris, and Das Trainer
  • A server to which captured game data is sent, and which rebroadcasts data
  • A system of renderers to redraw game play from scratch
    • Crisp, pixel-perfect rendering
    • Many stats computed in real time
      • For reviewing one's own game footage after the fact
      • For audience to understand more about the game in real time
      • For match commentators to make better commentary in real time

Basically, when we have Tetris game data (as opposed to images), the tetris game can be re-rendered with custom layouts, and various statistics can be computed. When multiple player data are used, a competition UI can be built with score differential and other comparative stats.

NEsTrisChamps provides many rendering layouts implemented in HTML+CSS+JavaScript at 720p resolution. This allows the templates to be dropped easily in OBS or StreamLabs OBS as a Browser Sources, and then adding player video stream or other sources like Twitch Chat on top of it.

To get started, visit the online docs here: https://nestrischamps.io/docs

Sample Screenshots

Das Trainer Stats Layout

Full UI

Documentation for sections of that UI is here

1 game demo video here

CTJC Competition Layout

Full UI

Includes score differentials, difference in number of tetrises, tetris rate computation, running tetris rate, and pace.

UI "inspired" from, and improving on, CTJC's layout.

1 game demo video here

Invisible Tetris Renderer

Full UI

Here's a demo of my playing from the renderer itself (it's harder than it looks because rendering runs 2 frame behind)

The 2 semi finals and the final match of CTWC 2019's Invisible Tetris Competition have also been rendered with this renderer for demo, as seen from the links below:

Getting started

NESTrisChamps is only tested in Chrome, Chromium, and Firefox. It is unlikely I will support MS Edge unless someone contribute PRs.

Read the documentation.

NEStrisChamps online

  1. In a window load your producer page https://nestrischamps.io/room/producer
  2. Calibrate your input. If you're lucky the autocalibration would have done a good job, and only needs minor fine tuning. You still must fine tune to have the capture areas pixel-perfect (refer to the OCR section for details) of the documentation.
  3. Visit your personal renderers page to copy the renderer URL https://nestrischamps.io/renderers. I recommend using the layout simple_1p for a start
  4. Start playing. The renderer should render your game.

Note: Both pages must be in their own windows. The producer cannot be a in background tab, or chrome would throttle its processing, and your capture would be all choppy.

Read this additional calibration guide created by aGameScout.

OBS

Once you have connected your producer and renderer, you are ready to set up OBS or Streamlabs to stream it.

To do that, drop a Browser Source in OBS and use the renderer URL as-is. Make sure the Browser Source dimensions are set to 1280x720.

Also, verify that Browser Source hardware acceleration is set (under Advanced Settings).

Image of Browser SOurce Hardward Acceleration Setting

Local Setup

Warning: Local setup is for developpers and contributors. If you are a casual user, use nestrischamps online instead :)

code style: prettier

Install nodejs

Nestrischamps is a nodejs server application and UI. It can run on node 12 and above, but use 14+ if you can. Installation instruction for your OS are left for you to figure out.

Clone the project locally from git:

git clone https://github.com/timotheeg/nestrischamps.git

Install nodejs dependencies

cd nestrischamps
npm install

Set up a postgres local DB

Install a local Postgres DB (instruction on how to do that is left to you. Check documentation for your OS), and set it up by running the sql setup commands.

Set up your environment variables

Create a file .env at the root of the project checkout folder. The following environment variables are required:

DATABASE_URL=postgres://<UNAME>:<PWD>@<HOST>:<PORT>/<DBNAME>
FF_SAVE_GAME_FRAMES=1

The variable DATABASE_URL should basically contains a connection URI, which should match your DB access.

The variable FF_SAVE_GAME_FRAMES=1 ensures that game files will saved locally (in the folder games. For replay if you want, of for further game analysis later if you are so enclined. If you do not want to save grame frames, remove the variable FF_SAVE_GAME_FRAMES

Install prettier

Prettier is installed when you install nodejs dependencies. To use prettier to format your code, please follow this guide to setup prettier with your code editor.

Run the server

Sets environment variable and start the server

npm run start-linux

Access the App

The app is accessed locally just like the online live version of nestrischamps.

The only thing the local versiopn des not support is Twitch login.

So, load the producer URL: http://localhost:5000/room/producer, and click on the button Login as Player 1 to set your session.

Next, lLoad the renderer URL: http://localhost:5000/renderes, and copy the URL for the layout you want.

Create a Browser source in OBS from that URL (again, just like in nestrischamps online mode).

You're done! From here on, everything should be connected and working!

Invite remote friends

If you know how to set up apps on your router (i.e. port forwarding, you can invite your friends to play on your local server. Make them access the producer URL, and ask them to login as player 2 rather than player 1.

"Hidden" options

Start Timer button

If you use the Stencil renderer to qualify for CTM or other online competitions, to start the timer, load your producer URL with an extra Query String argument like this https://nestrischamps.io/room/producer?timer=1

Screenshot of Start Timer Button

Don't draw background

Many of the layouts have a black background with drak Yelow pieces drawn on them. If you'd rather have a transparent background, use the query string argument ?bg=0 to disable the background

Don't use Half Height

Capture devices are presumed to produce interlaced output, which can create incorrect reads. NESTrisChamps by default uses only one line in 2 to remove interlacing deffect. Some capture device have built-in deinterlacer and smoothener which render a slightly blurry output. While this looks great, it's not well suited for the half-height system of NESTrisChamps.

It is possible to disable the half-height behaviour by adding the following query string argument in the producer page ?disable_half_height=1.

Enable Frame Buffering

By default, nestrischamps broadcasts frames immediately and renders them as soon as they are received. If network is good and latency is more or less consistent, rendering will look good while being the most real time possible. If latency is not consistent however, this can create a stuttering rendering effect, which may not look very good.

It is possible to enable frame buffering in many of the renderers by adding a query string argument ?buffer_time=X , where X is the number in milliseconds of buffering one wishes to have. For a simple try out, use ?buffer_time=1000.

When Frame buffering is active, frames are not rendered as soon as they are received. Instead, there is an initial delay to accumulate frames (in the example above, a 1s delay), and frames are then replayed with the timing interval they were captured at.

Note that, when you share your webcam feed at the same, it means your reaction on webcam will preceed the frames themselves. That may look slightly odd, but it is not a usualy a deal breaker.

Enable Native webcam capture

So far "native" webcam support (e.g. built-in webRTC) is only built into some of the layouts, so by choosing the layouts, you chose whether there'll be webcam support or not. At the moment, the layouts which support webcam natively are ctm_video, ctm_video2, ctm_2matches, stencil_ctwc_sing_21.

Native webcam sharing can also be activated in the layouts classic and das_trainer with the query string argument ?video=1.

Enable Twitch Chat Text To Speech

In the producer window, if you add the query string ?tts=1 you can enable Twitch Chat TTS.

Chatters get assigned a random voice out of the available ones, with no repeats until all voices are exhausted, and then repeat may happen randomly.

Note that you can specify which language you want the voices to be in by adding an additional query string parameter lang=X, where X is a ISO 2-letter language code, e.g. lang=en. Defaults to en if not supplied.

Contribute

To contribute, make sure you first set project to run locally (see previous sections), such you can test your code before opening up PRs.

Many issues and ideas for improvements are listed in the github issues.

The code is sort of messy, and yet, I have some standards hidden in this mess. Until I document them, please ask on the discord server before submitting PRs.

References and Equipment

Related Projects

nestrischamps's People

Contributors

timotheeg avatar zohassadar avatar eamonheffernan avatar therealtomellosoulman avatar alisaifee avatar kirby703 avatar snipem avatar dependabot[bot] avatar

Stargazers

Carl Fink avatar Andrew Holder avatar  avatar David Silverlind avatar  avatar Peter Medus avatar  avatar 晦涩弗里曼 avatar KIRIHARA PD avatar  avatar bozzeta avatar Lexi avatar Nekzuris avatar Abzwingt avatar Rara avatar zeus avatar Nicolas Sauzede avatar Erik Moqvist avatar Resi Respati avatar Ilya Medvedev avatar Angelo avatar Daniel Volz avatar 오로라 avatar Matt Tortolani avatar  avatar Morgan Aldridge avatar Carlos Amorim avatar tubuname avatar Niam Jen Wei avatar Lam Kee Wei avatar  avatar Aaron Kaluszka avatar Vinrobot avatar Kirjava avatar  avatar cazdlt avatar  avatar kuma avatar Zutatensuppe avatar  avatar Bartosz Brzoza avatar Johannes avatar Natasha Koh avatar  avatar Robert Lin avatar

Watchers

James Cloos avatar  avatar  avatar kuma avatar

nestrischamps's Issues

Cumulate Score Beyond maxout

By knowing the lines and start_level, line clears events can be detected beyond maxout even without a Game Genie code, and score can be counted in nestrischamps past 999,999.

Push down point past maxout can't be known obviously, but counting past maxout can be a nice addition.

This is already done to some extent since push down points are computed in the das trainer and classic layouts by comparing how much the score the players should have had after a clear with the actual score he has, and the difference are the push down points.

See the code here, copied below for reference:

onLine(event) {
	const
		num_lines    = event.lines - this.data.lines.count,
		lines_score  = this.getScore(event.level, num_lines),
		actual_score = event.score - this.data.score.current;

	// update total lines and points
	this.data.lines.count = event.lines;
	this.data.points.count = event.score;

	// update drop score
	this.data.points.drops.count += actual_score - lines_score;

Make a script to clean up the DB

There are many games in the DB with invalid or corrupted data. Games which were recorded when users were still calibrating, or recorded from calibration that need fine tuning.

This leads to weird entries like:

  • Game with 2 frames
  • Game with TRT greater than 1, (sometimes Infinity, sometimes NaN)
  • Clear list having dashes when the line count is read incorrectly and therefore, lines - previous_lines can be negative 😑

We should not just blindly delete the game entries, since they can be linked to a game file in S3.

TODO:

  1. Supply script that remove invalid game entries for known pattern, and delete both DB record AND game file
  2. Supply script to crawl over the S3 bucket and delete any file found that is not listed in the DB.

Make deployments more graceful

At the moment, everything is in memory (room, users, sessions), so when the service restarts, everything dies, and while clients try to auto-reconnect, the websocket connections for producers and admin will fail because users need to refresh and relogin.

There are usual suspect things to do to make this better:

  • Serve static assets from different places, so they can be released without affecting the service
  • Store sessions in persistent store, so reconnections can succeed (although room states would still be gone)
  • Store rooms in a redis, and use redis pubsub for message broker

Add palette creation tool

We can assume that a given user of nestrischamps has a static setup: nes+some capture card, or emulator, and the colors within that setup are constants.

TODO:

  • Allow a player to play a game from level 0 to 10
  • Track block colors during a given level
  • Compute colors from block average from color1 and color2 (remember to square then root - reference!)
  • Store the palette (in local storage? Upload to server?)
  • Use the palette in the user OCR.

Note:
Scanning color is actually fast, so there's not much to save on the OCR itself:
image

BUT capturing the colors grows the size of the overall capture (on the left, so that could save some of the time) since the source capture is the most costly thing JS does:
image

Reference palette generation script in NESTrisOCR:
https://github.com/alex-ong/NESTrisOCR/blob/master/scripts/compute_color_palette.py
That script works well, but it requires that a player has prepared field images for each of levels 0 to 9, and is therefore a little tedious)

Allow users to contribute their own layouts

  • document frame format, and player class, and layout requirements.
  • Create some upload system for custom layout and assets

This is to allow people to ad their own branding onto layouts. It's clear that restreamers do like to brand their layouts, and nestrischamps should allow it.

Technically, this is already possible in a way, non-hosted by nestrischamps.

Make a local html file (maybe start by taking one from this repo), load all the js assets like constants.js, player.js, etc., establish a webconnection to nestrischamps like this:

ws://nestrischamps.herokuapp.com/ws/view/ctjc_pace/<SECRET>

You would receive the player frames from the room you host, and you can do whatever you like with the data.

TODO: document this better

Update pace metrics name

  1. Rename current pace metrics from pace to runway
  2. Use the name Projection for the Runway Efficiency Interpolation

Do the change both in variable name in code and in the layout labels

Extract state from app

The App is currently tracking state inmemory:

  • Rooms
  • Users
  • Sessions

This means deployment are very disruptive and kick users out, requiring a fresh login.

Ideally, while a deployment will break websockets, everything should resume transparently.

TODO:

  1. Move sessions data into DB
  2. Extract rooms and users state to DB (possibly to a redis DB?)

Note, with the current load, 1 server can handle all the traffic of nestrischamps. If this ever picks up and nestrischamps needs horizontal scaling, then using a redis instance will likely become a requirement, where rooms will be in redis, and game frame data will transit over redis pubsub.

Make available the CTM/CTWC qualifier layout

It's a layout that assumes user streams the source stream (for cheating prevention) in the famous Stencil.

The Stencil has available space on the bottom-right corner, which can be filled with the Running Tetris graph and the drought counter.

Record all game frames

If cost and processing permits:

  • Record frames for every single game
  • Store games as individual files somewhere (S3 bucket?)
  • store game file url in scores DB

Use Twitch login authorization to read Twitch Chat

The layouts classic and das_trainer have a chat box which is empty atm. The code to display message already exists, but nestrischamps isn't connecting to Twitch to read and forward chat messages.

TODO:

  1. Augment permission scopes with chat:read when logging with Twitch
  2. Use Twitch Chat Client to connect for the user specifically (single channel)
  3. Forward chat messages to the user connections

Change stats from TODAY to PAST 24H

The stats page is a little annoying, It return today's score, but today is defined at UTC timezone, it does not take the player's timezone into account.

TODO:
Change the TODAY stats to PAST 24H stats

This can be achieved purely as a SQL query in postgres without having to introduce timezone for players.

Make a CTM Stencil Layout

Nestrischamps competition layouts are not in use, partly due to some inertia of everybody already being on the Stencil view, both to produce their game and for restreamers having already setup their slice-n-shift restreaming layouts.

A user mentioned he doesn't like streaming o nStencil any more, because he had aa really good game in competition, but since it wasn't tracked on nestrischamps, it doens't all the extra stats he wants.

To break one barrier to entry, nestrischamps should offer a Stencil layout, players using it would have streams which are compatible with the slice-n-shift restreamer setups ,and if 2 players are on nestrischamps, a game host could switch to using a nestrischamps competition layout easily.

Note: To make this work nicely, issue #55 should be done as well.

Turn off "Show parts" automatically

Show parts is great to see when calibrating, but when the calibration is good, it's unecessary to waste resources drawing all the parts again.

TODO:

  • Automatically turn off "show parts" after the last calibration update

On page load, "show parts" can be "on" and switch off after 30s or 60s. During calibration, any changes can push the automatic switch off into the future, until user is no longer tuning their calibration.

Implement rate limit for score reporting

Scores are reported by the renderers, this is not a sane dev practice. Can easily be DDosed and malicious users can report whatever they want easily.

We can probably ignore fake scores, too bad if you want to cheat yourselves, but we should protect the platform and the DB.

A rate a limit of score submission by user should be enough, 1 score per minute maybe? TBD

Support anonymous rooms and by-invite-only rooms

At the moment, all match rooms belong to users, and the URL for a user's match room is deterministic.

So anyone can connect their producer to someone's room with or without their permission.

They can't force their way into the rendering of the room (since players are assigned by the room host), but they can still make life annoying for the host.

TODO:

  • develop a concept of anonymous rooms.
    • anonymous rooms can be created by any users, they become the host and have access to the admin page
    • the room URL can be given to producers to connect to it
    • the room URL is not guessable, so there won't be undesirable visitors

Split the pace metric into transition potential and game potential

The single player layout all show the pace metric atm, but for beginner player, the metric is not very interesting, since beginners (and many intermediate players), do not reach kill screen often (if at all).

On the other hand, most beginners and intermediate players do play at a level that let them transition (e.g. 15-start transitions at 100 lines, 18 start transitions at 130 lines).

For the single player layout therefore, it is more beneficial to show the transition potential for the early part of the game.

Once transition is reached, the same pace "box" can switch to show the game potential (to save screen real estate).

The layouts das_trainer and classic do show the transition scores, so the transition score is retained on screen even after the pace box switches from transition potential to game potential, but other layouts do not. We can consider whether the transition score is something we want to show in the other single player layouts.

Also TBD: should splitting the pace into 2 components be done for competition layouts too? Perhaps, where possible) the pace box should show data like:

  • transition potential (stops changing at transition - duh)
  • game potential (stops changing at killscreen OR keeps increasing to match score)
  • game potential diff
  • game potential tetris diff

Doing that would have the benefit of tracking the actual transition score on screen

Set up a way to test from static video files

OCR is currently done on either device capture or screen capture.

While this is fine to use, a test suite should be able able to play video files and verify the output.

There are plenty of material out-there of for CTM qualifier on Stencil.

TODO:

  1. Find the CTM qualifier from someone Best if it was captured and published at 60fps
  2. Extract 1 or 2 games from it, best if the games can go past maxout, 1.2M would be great, and level 30/31/32
  3. Put the file as web assets somewhere
  4. Find a way to play the file in the video tag
  5. Run the OCR capture from the video file, verify that all is well

Broadcast player stream in his/her own private room when playing in a match room

Context

In traditional restreaming competition, a player streams his own gameplay with webcam with the Stencil layout, while the restreamer captures the stream, cuts it to its own layout needs, and restreams.

With nestrischamps, there is no restreaming any more. There's only hosting a game. Game data from the player goes straight to the restreamer view, saving badnwidth and latency for everyone involved.

BUT this is limiting, player still want to have their own stream at the same time, and while they can stream their webcam, they cannot stream their gameplay on windows (because the input game video feed cannot be shared by both OBS and chrome).

TODO:

When a player is attached to a host's match room, the connection should additionally be attached to his/her own private room.

That way, while the restreamer can use whatever layout they like, the player may feed his own game frame into one of the single player layouts.

Serve static assets from a different systems

The node app's job should be to manage rooms and broker messages. Don't have nodejs waste its time serving static assets.

I dunno know how to do that in heroku. Needs some research and RTFM

Reduce scope of shine optimization, or offer option to disable it

Context

The field is read with a shine optimization. Basically, the algorithm for detecting blocks by their colors in the board is like this:

  1. Check if there is shine on the top-left corner. If no shine it's black
  2. Since there's a shine, it must be color 1, 2, or 3, compute color distance to find the best fit

Unfortunately, when some interlacing artefact is incorrectly detected as shine, then black (no block) can never be matched, and the darkest of color 1, 2, 3 will be picked. For example at 18, the darkest color is red, so a trail of red blocks may follow pieces as they fall on some graphic cards.

The shine detection implementation is out in place for 2 reasons:

  1. It reduces the colors to compare against from 4 to 3 for each of the 200 blocks of the field. And in fact, since the first half of the screen is mostly black, it alows very quick identification of black tiles
  2. It is necessary for retron capture, because levels 7, 17, 27, are display pretty much as black, and so at these leven, by comparing against 4 colors, black is often picked instead of the correct color. By removing testing for black for these levels, color 2 is always picked when there is a shine but the block is very very dark

Example where a white I piecce falling horizontally has a red "trail".
image

Sample of the interlace artifacts that causes the shine to be detected incorrectly:

image

image

TODO:

Options:

  1. Add a toggle to activate or deactivate shine optimization overall. For people not on retron, we can restore comparig against 4 colors for every block.
  2. Enable shine optimization only on level 7, 17, 27, 37 (x7!), such that things still work on retron.

In both cases, the shine optimization to detect black early can still be applied, the only thing that changes is: when there is a shine, do we compare against 3 or 4 colors.

Replace websocket by uWebsocket

uWebSockets seems to be the most performant websocket library for nodejs.

TODO:
replace ws by uws

Looks like uWebSocket cannot be installed with npm, so it might mean migrate the project to using yarn instead, which is fine I guess?

Verify Sanitizer logic

The Sanitizer logic right now is to delay reads from score on one end, and lines on the other. Level is read alongside changes to lines.

The base logic for this is that score can change independently (push down points), but level can only change when lines change.

There is a piece of code that sort of binds score and lines in case changes are not detected correctly, as it was seen in video processing in the project tetris_ctm_summary

image

So basically, when a line change is detected and there was already a pending score read, we should probably read the lines now anyway!

This makes for some clunky logic... and is probably not necessary at all.

Basically, the logic can be cascading with a single trigger. Just as level can never change without a line change, line can never change without a score change. So by inspecting only changes in score, we can have a delay for all of the field.

Just like some line changes have no level changes, some score changes, will have no lines or level changes (push down points), but again, there is a strict cascading order:
score -> lines -> level

And so by focusing only on score the delay logic for reads can be simplified.

Revamp OCR Sanitizer

The Sanitizer reads value after 1 frame delay to allow the values to stabilize (to fix the dreaded interlaced blurred transition frames) This works well for digits read, BUT field scanning itself should be delayed by one frame. That is because:

  1. In Das trainer, field scanning works on palette, but to select the right color reference from the palette, the level must be known, but the level is OCRed in the same frame as the field scanning. So if the level is read incorrectly due to the blurred interlaced frame, then the color detection will be.

  2. In Classic Tetris, the colors are read from reference location, but they too can be subject to transition corruption.

Note: There is a mitigating factors here: when reading from a capture device, the whole capture is halfed, which by itself, already eliminates many transition corruption. And when reading from emulator, we can expect the corruption is not present because the emulator doesn't render with interlaced lines (maybe? 🤷 )

So this issue might not be urgent (I have not seen colors problems in my own capture), but I thought I'd document the tought occured to me.

If we wanted to solve this, one way to go about it might be to store the source image with the delayed frame, and only after reading the level correctly from the "stable" frame, then scan the field and update the previous frame before brodcasting it.

Should be relatively easy because the class OCRSanitizer holds a reference to the instance of TetrisOCR, so it could call this.tetris_ocr.scanField(), provided it has the source image to pass along.

Track game data server side

At the moment, games are reported from the UI, since UI computes all the game stats.

But because we have 2 different types of UI with different code (historical reason), it's a pain to maintain game reporting code.

Also, in match layouts, the layout is owned by one user (the game host), but may host 2 different players, and it's not right to have the game host report the game data from different users, from an security perspective, it implies there's an API where a user may report for another, and I don't like that.

We could add a column "reporter" in the DB, so we could still sort of clean bad entries if we wanted, but basically, I thin the solution is to track the game progression in the server, straight from the producer frames.

On the server, there's one ongoing game for a producer, tracking the minimum amount of stats we want to capture in DB. For reference, at the moment, the score table has this structure:

    Column    |            Type             | Collation | Nullable |              Default
--------------+-----------------------------+-----------+----------+------------------------------------
 id           | integer                     |           | not null | nextval('scores_id_seq'::regclass)
 datetime     | timestamp without time zone |           | not null |
 player_id    | bigint                      |           | not null |
 start_level  | smallint                    |           |          |
 end_level    | smallint                    |           |          |
 score        | integer                     |           |          |
 lines        | smallint                    |           |          |
 tetris_rate  | double precision            |           |          |
 num_droughts | smallint                    |           |          |
 max_drought  | smallint                    |           |          |
 das_avg      | double precision            |           |          |
 duration     | integer                     |           |          | 0
 clears       | character varying(400)      |           |          | ''::character varying
 pieces       | character varying(1200)     |           |          | ''::character varying
 transition   | integer                     |           |          |
Indexes:
    "scores_pkey" PRIMARY KEY, btree (id)

So basically, on the connection, a Game instance should run, and intercept game frames, compute basic stats (e.g. TRT and num droughts) like the UI currently does locally, and record the game into the DB when game over event is detected.

This will allo ALL games to be tracked, even the ones done in competition.

BONUS: the server could store all the frame entries into a binary file in S3 or digital ocean, such that any game could be replayed

Document how users can get the game data themselves

At the moment, the layouts open a websocket, and the game data are sent over that websocket.

Anyone can open the web sockets to get the data, and then pipe that into whatever they want (no need to necessarily use a layout from nestrischamps).

So document how this works.

Alternatively, or in addition, allow people to submit custom layouts, so people can share their cool design and whatever other stats, and metrics they can think of.

Share players video feed directly to the layouts with webRTC

The layouts currently show the twitch avatar in the field.

But for for competition, one might want to see the players video feed. nestrischamps should be about easy setup. a game host should not have to cut player streams, or have to start a side video call on skype or hangout or zoom and then screen cap the video call player feed in OBS.

Proposal:

  • The producer window and the rendering layouts can be webRTC peers
  • When any window starts, it registers itself as a peer and gets a peer ID and send that to the nestrischamps server
  • When admin selects the player, the server instructs the layout it will be expecting a call from a given peer, and instructs the producer window to initiate a call to the rendering layout and submit its video feed

Complexities:

  • Handle call drops, reconnection, admin changing players, etc.
  • Producer page must allow player to select which webcam to pick
  • How to integrate the player feed in the layouts? small areas? Full blown? etc.

Optional Bonus:

  • The game frames themselves could be sent peer to peer (Nice for Say, Singapore players, whose game frame do a full roud trip to the US server even though both players and game host are in Singapore)

Make a bug report system in the OCR page

When OCR is not working all that well, or there are weird things happening in the combination of OCR and renderer, it can be hard to troubleshoot.

instead of requiring for specific details from users, it would be great to have a "submit setup details" button of sorts which would send a few things:

  • The OCR config
  • A raw frame from the source (emulator or capture)
  • The precomputed area overlay
  • The performance report

Add privacy control for player video feeds

For competition layouts which support video feed, nestrischamps should not grab the video feed of webcam without user consent.

TODO:

  • The producer window should have some ui control to allow/disallow player feed

Simple checkbox could do.

Add a site monitoring page

To check the health of the server, and plan capacity, an admin page showing monitoring information should be created.

Something to track:

  • number of active private rooms
  • number of active match rooms
  • number of connections
  • number of ongoing games

System metrics can be tracked on the infra provider (heroku or digital ocean)

Allow producer socket to accept commands

Producers do only one thing now, send game frames over their web socket.

Many producer can connect to a single game room, where room owner can adjust who is player 1 and player 2 from the list of connected users, but at the moment, all producers are sending their game frame and the non-player 1/2 data is being dropped by the app.

Ideally, the app could instruct the producers to produce when needed. If you're a producer but not player 1 and 2, and are on standby, it's not necessary to send game frames at all.

At the very least, a connection-level command could be used to make the connection not send anything.

At a higher level, a producing-level command could let the producer not even do OCR if it's not needed to send anything since no-one is listening.

One more use case for producer to accept commands would be to synchronize a count down between the players.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.