Budowa platformy meczowej CS2 dla naszej grupy znajomych

Mamy małą społeczność CS2 — zaledwie garstkę znajomych, którzy regularnie razem grają — a standardowy matchmaking nigdy tak naprawdę nie pasował do tego, jak chcieliśmy grać. Więc zbudowałem wokół tego kompletny stos: wtyczkę serwera CS2, platformę webową i aplikację mobilną, wszystkie rozmawiające z tym samym backendem. Trzy projekty, jeden ekosystem.

Trzy elementy

Wtyczka serwera CS2 (C# / .NET 8) — Zbudowana na CounterStrikeSharp, ta wtyczka działa wewnątrz dedykowanego serwera CS2. Obsługuje przebieg meczu rankingowego: rozgrzewkę, system .ready, rundy nożowe, pauzy techniczne, serie wielomapowe, zmianę stron na połowie meczu oraz awaryjny tryb „AIM mode", gdy żaden mecz nie jest aktywny. Pobiera konfigurację meczu z adresu URL podanego przez backend webowy i przesyła każde istotne zdarzenie — zabójstwa wraz z bronią i pozycją, wyniki rund, czat, zmiany cyklu życia — do MySQL.

Platforma webowa (Laravel 13 + Vue 3 + Tailwind v4) — mózg całej operacji. Gracze logują się przez Steam i Discord (Laravel Socialite), tworzą lobby, przeprowadzają veto map i oglądają mecze na żywo. We frontendzie nie ma żadnego pollingu HTTP: każda zmiana stanu — status lobby, postęp uruchamiania serwera, ban mapy, tablica wyników na żywo — jest wysyłana w czasie rzeczywistym przez WebSockets za pomocą Laravel Reverb i Laravel Echo. Scheduler raz na minutę wysyła aktualizacje wyniku, workery kolejek zajmują się transmisjami, a Sanctum chroni mobilne API. Historia meczów, statystyki graczy i szczegóły rund — wszystko to jest renderowane z tych samych danych, które wtyczka zapisuje do MySQL.

Aplikacja mobilna (Kotlin Multiplatform + Compose Multiplatform) — jedna baza kodu w Kotlinie dla Androida i iOS. Komunikuje się z backendem Laravel przez to samo API chronione przez Sanctum i subskrybuje te same kanały Reverb co strona internetowa, więc ban mapy dziejący się na czyimś laptopie pojawia się natychmiast na telefonie kolegi z drużyny. Powiadomienia push są wysyłane przez FCM (Android) i APNs (iOS) dla zdarzeń takich jak rozpoczęcie veto, gotowość meczu i przejścia cyklu życia — obsługiwane przez laravel-notification-channels/fcm i …/apn po stronie serwera.

Jak to wszystko się łączy

Wtyczka ładuje konfigurację z backendu Laravel po rozpoczęciu meczu, zapisuje każde zdarzenie z powrotem do MySQL, a ta sama baza danych zasila zarówno interfejs webowy, jak i aplikację mobilną — obie subskrybują identyczne kanały Reverb, więc wszyscy klienci pozostają zsynchronizowani bez konieczności ręcznego odświeżania czegokolwiek.

Stos technologiczny w skrócie

Warstwa Technologia
Wtyczka serwera gry C#, .NET 8, CounterStrikeSharp, MySqlConnector
Backend PHP 8.5, Laravel 13, Reverb, Sanctum, Socialite (Steam + Discord)
Frontend Vue 3, Tailwind v4, Vite, Laravel Echo, Chart.js, vue-i18n (EN/UK/PL/BE)
Aplikacja mobilna Kotlin Multiplatform, Compose Multiplatform, FCM, APNs
Czas rzeczywisty Reverb (WebSockets) → Echo w przeglądarce + klient KMP
Testy Pest 4 (PHP), Pint do formatowania

Dlaczego to budować

Szczerze? To po prostu dla zabawy i dla ludzi, z którymi gram. Ale przerodziło się to w fajne ćwiczenie end-to-end — natywne rozszerzenie serwera gry, aplikacja webowa działająca w czasie rzeczywistym i wieloplatformowy klient mobilny — wszystkie korzystające z jednego źródła prawdy. Każdy mecz, który gramy, testuje też każdą warstwę stosu jednocześnie, a to najlepszy rodzaj pętli sprzężenia zwrotnego.

Zrzuty ekranu

1 / 5