All case studies

Tech Lead, fullstack

ESports Turbo Scout

A Dota 2 tournament website and a referee dashboard with live match events.

Under NDA — happy to walk through the architecture and the code in a call.

The match protocol in the judge panel: Dota 2 events arrive over a websocket and land in a table with game time and score. The button beside it builds the organisers’ Excel file from the same table.
The match protocol in the judge panel: Dota 2 events arrive over a websocket and land in a table with game time and score. The button beside it builds the organisers’ Excel file from the same table.

The referee panel and the ESports Turbo tournament website.

2024 · tech lead and fullstack developer

My role

I owned architecture, the NestJS backend, Next.js panel, data model and deployment. I agreed events with the Lua game-mode developer, reviewed and accepted the GSI contractor’s work, and scheduled releases around broadcasts.

Game data
Collecting match state and events from Dota 2
Referee panel
Events, scores and match log exports
Tournament day
Schedule, teams and match results

The business problem

Referees copied events from the broadcast into a spreadsheet. The log could diverge from the video, and organisers needed an export at the end of the day. Automation had to be introduced during daily tournaments: broadcasts ran from 07:00 to 16:00, with releases after the last match.

Game data

Two sources for one match log

GSI sends state from an observer client, while a custom Lua mode sends specific events, scores and the timer. The backend links both streams to the match.

  1. GSI

    Map state from the observer client.

  2. Lua

    Individual events from the custom mode.

  3. NestJS

    Processing and association with a match ID.

  4. Panel

    Events and scores in the referee workspace.

Match lifecycle

The backend recognises the beginning and end through game states. A new match closes the previous one. Logs are cleared a minute after victory.

Game time in the log

Events carry a match ID, game time, score and game state. The table and export use the same data.

Referee panel

A workspace instead of a manual log

One page brings together events in Russian, scores, a timer and space for the broadcast. The referee checks the match and exports a file for organisers from the same table.

Score cards, game time and the LIVE marker update from the shared match entity, with item purchases per player listed underneath for both sides.
Score cards, game time and the LIVE marker update from the shared match entity, with item purchases per player listed underneath for both sides.

16 event types

First blood, kill races, towers and barracks, Roshan, the Tormentor, mega creeps and runes: the log’s scope was agreed with the tournament operator.

Excel export

The client builds a file containing event time, match, game time, score, state and team names. The day’s results do not need to be copied again.

Engineering details
  • Broadcast delay

    A local resender holds GSI packets for a configured number of seconds, allowing the log to align with a delayed broadcast.

  • Separate environments

    The panel requires authentication, and staging is separate from production. Changes can be checked while the production environment serves a tournament.

Tournament day

Tournament schedule and match results

In the panel, the referee selects a date and opens the match log from the schedule. The public site shows group matches, finals, teams and standings.

Results from completed matches

The frontend calculates points and game differences from completed matches.

The tournament day’s schedule: the judge picks a date in the calendar and goes from a match row straight into the protocol.
The tournament day’s schedule: the judge picks a date in the calendar and goes from a match row straight into the protocol.
A tournament day on the public site: group-stage and final matches, team rosters and the group table. Points and game difference are calculated on the frontend from finished matches.
A tournament day on the public site: group-stage and final matches, team rosters and the group table. Points and game difference are calculated on the frontend from finished matches.
More screens (1)
The league’s public site: the daily Dota 2 Turbo tournaments the protocol is wired into, plus the planned 1×1 and CS2 formats.
The league’s public site: the daily Dota 2 Turbo tournaments the protocol is wired into, plus the planned 1×1 and CS2 formats.

Outcome

Match events in the referee panel and Excel

I built the backend and referee panel that turn Dota 2 events into a match log and Excel export. I agreed data formats with the integration developers and released updates between broadcasts.

2
independent data sources: GSI and the custom game mode — if one drops out, the protocol runs on the other
16
types of match event in the protocol

Stack

  • Next.js
  • TypeScript
  • NestJS
  • TypeORM
  • PostgreSQL
  • WebSocket
  • Dota 2 GSI
  • Strapi
  • MongoDB
  • Docker