Створення платформи матчів CS2 для нашої компанії друзів
У нас є невелика спільнота CS2 — лише жменька друзів, які регулярно грають разом, — і стандартний матчмейкінг ніколи по-справжньому не відповідав тому, як ми хотіли грати. Тому я побудував повний стек навколо цього: плагін для сервера CS2, вебплатформу та мобільний застосунок, які всі спілкуються з одним бекендом. Три проєкти, одна екосистема.
Три складові
Плагін сервера CS2 (C# / .NET 8) — Побудований на , цей плагін працює всередині виділеного сервера CS2. Він керує змагальним процесом матчу: розминкою, системою .ready, ножовими раундами, технічними паузами, серіями з кількох карт, зміною сторін у перерві та запасним «AIM-режимом», коли матч не активний. Він отримує конфігурації матчу за URL, який надає вебсервер, і передає кожну важливу подію — вбивства зі зброєю та позицією, результати раундів, чат, зміни життєвого циклу — у MySQL.
Вебплатформа (Laravel 13 + Vue 3 + Tailwind v4) — мозок усієї системи. Гравці входять через Steam і Discord (Laravel Socialite), створюють лобі, проводять вето карт і дивляться матчі наживо. На фронтенді — жодного HTTP-полінгу: кожна зміна стану — статус лобі, прогрес запуску сервера, бан карти, живе табло — надсилається в реальному часі через WebSockets за допомогою Laravel Reverb і Laravel Echo. Планувальник надсилає оновлення рахунку раз на хвилину, обробники черг займаються трансляціями, а Sanctum захищає мобільне API. Історія матчів, статистика гравців і деталі раундів — усе це відображається з тих самих даних, які плагін записує до MySQL.
Мобільний застосунок (Kotlin Multiplatform + Compose Multiplatform) — одна кодова база на Kotlin для Android та iOS. Він спілкується з бекендом Laravel через те саме API, захищене Sanctum, і підписується на ті самі канали Reverb, що й сайт, тому бан карти, який стається на чийомусь ноутбуці, миттєво з'являється у телефоні товариша по команді. Пуш-сповіщення надсилаються через FCM (Android) і APNs (iOS) для таких подій, як початок вето, готовність матчу та переходи життєвого циклу — це обробляють laravel-notification-channels/fcm і …/apn на боці сервера.
Як це все з'єднано
Плагін завантажує конфігурацію з бекенду Laravel, коли починається матч, записує кожну подію назад у MySQL, і та сама база даних живить як вебінтерфейс, так і мобільний застосунок — обидва підписані на однакові канали Reverb, тому всі клієнти залишаються синхронізованими без потреби щось оновлювати вручну.
Технологічний стек коротко
| Шар | Технологія |
|---|---|
| Плагін ігрового сервера | C#, .NET 8, CounterStrikeSharp, MySqlConnector |
| Бекенд | PHP 8.5, Laravel 13, Reverb, Sanctum, Socialite (Steam + Discord) |
| Фронтенд | Vue 3, Tailwind v4, Vite, Laravel Echo, Chart.js, vue-i18n (EN/UK/PL/BE) |
| Мобільний застосунок | Kotlin Multiplatform, Compose Multiplatform, FCM, APNs |
| Реальний час | Reverb (WebSockets) → Echo у вебі + KMP-клієнт |
| Тестування | Pest 4 (PHP), Pint для форматування |
Навіщо це створювати
Чесно? Це просто для розваги і для людей, з якими я граю. Але це перетворилося на гарну вправу від початку до кінця — нативне розширення для ігрового сервера, вебзастосунок реального часу і кросплатформений мобільний клієнт, які всі мають єдине джерело правди. Кожен матч, який ми граємо, також одночасно тестує кожен шар стеку, а це найкращий тип зворотного зв'язку.