Розробка чатів та соціальних модулів ігор під ключ
Ми розробляємо мультиплеєрні чати та соціальні модулі, які не ламаються під навантаженням і не створюють race condition з ігровою логікою. З нашим 7-річним досвідом у геймдеві та 30+ реалізованими проєктами ми знаємо, як побудувати real-time шар, який витримує пікові онлайни без деградації RTT.
Чому чат на одному каналі — погана ідея?
Найчастіша помилка — використовувати один транспортний канал для ігрових подій і повідомлень чату. У Photon Realtime кожен канал має FIFO-гарантію всередині себе, але не між каналами. Якщо ігрові RaiseEvent з кодами руху гравця та текстові повідомлення йдуть через channel 0, при сплеску активності в чаті затримка позицій зростає до 200–300 мс навіть при хорошому пінгу. Рішення: виділити окремий unreliable-канал для чату з низьким пріоритетом та reliable-канал для системних повідомлень (kick, ban, invite).
Що входить у роботу?
- Архітектурна документація (схема даних, канали, пріоритети)
- Інтеграція Photon Chat або кастомного сервера
- Реалізація історії повідомлень, пагінації, TTL-очищення
- Модерація (ML-фільтр, rate limiting, mute/ban)
- Соціальний граф (друзі, гільдії, запрошення)
- Пуш-сповіщення (FCM, WNS) через асинхронну чергу
- Навантажувальне тестування з ботами на headless Unity
- Вихідний код, README, міграції, навчання команди
Де зазвичай ламається перша реалізація
Друга проблема — зберігання історії. Багато команд зберігають історію чату прямо в кімнаті Photon через CustomRoomProperties, що працює доти, доки не перевищується ліміт 1 КБ на властивість. Після цього повідомлення просто втрачаються без помилки на клієнті. Правильний підхід: виносити історію на окремий мікросервіс з PostgreSQL або Redis Streams, а в кімнаті тримати лише покажчик на останній прочитаний offset.
Третя біль — модерація в реальному часі. Наївна фільтрація через RegExp на клієнті обходиться за секунди. Серверна валідація через webhook у Photon WebHooks v2 додає latency до кожного повідомлення. Робочий компроміс: асинхронна постмодерація з миттєвим показом повідомлення відправнику та затриманою доставкою іншим через буфер 50–100 мс, за які встигає відпрацювати ML-фільтр.
Як вибирати між Photon Chat і кастомним сервером?
| Рішення | Затримка | Масштабованість | Гнучкість | Вартість |
|---|---|---|---|---|
| Photon Chat | <50 мс | Висока (готова інфраструктура) | Низька (тільки базові канали) | Ліцензія + використання |
| Кастомний сервер (Node/Go) | <50 мс | Залежить від реалізації | Повна (ролі, гільдії, аналітика) | Розробка + хостинг |
Якщо ваш проєкт — mid-core з гільдіями, кастомними ролями та модерацією, кастомний сервер окупається за рахунок контролю. Для простих казуальних ігор з одним чатом достатньо Photon Chat.
Як будуємо соціальний шар поверх ігрової сесії
Чат — це видима частина. Під ним зазвичай потрібні: список друзів, інвайти, система гільдій/кланів, статуси онлайн/офлайн, сповіщення. Photon надає Photon Chat як окремий SDK з власними серверами — він вирішує базові завдання (публічні канали, приватні повідомлення), але не вміє в кастомні ролі та права доступу. Для ігор з гільдіями це обмеження критичне.
Типова архітектура, яку використовуємо для mid-core проєктів: Photon Chat для real-time delivery + власний REST API на Laravel/Node для управління структурами (гільдії, ролі, mute/ban), PostgreSQL для персистентності, Redis Pub/Sub для broadcast подій між інстансами API. Unity-клієнт підписується на Photon Chat channel за ID гільдії, а метадані (назва, аватар, учасники) підтягує через REST при вході в лобі.
На одному з проєктів — мобільна battle royale на 100 гравців — ми зіткнулися з тим, що при одночасному вході 80+ гравців у матч-лобі Photon Chat видавав spike підключень, який валив регіон EU-West приблизно раз на тиждень. Виправили через exponential backoff на клієнті (від 500 мс до 8 с, jitter ±200 мс) та lazy subscription: канал команди підключається тільки після підтвердження складу, а не в момент JoinRoom. Знизили навантаження на реєстрацію на 40%.
Які інструменти використовуємо?
Для Unity-проєктів основний стек: Photon Chat SDK, Photon Realtime для ігрових подій, Mirror Networking або Netcode for GameObjects як альтернативи для p2p-схем. Серверна частина чату — Photon WebHooks v2 для хуків на події + кастомний мікросервіс для бізнес-логіки. Докладніше про Photon Chat можна дізнатися в офіційній документації.
Для кроссплатформенних проєктів (PC + Mobile + Console) важлива підтримка OpenID Connect для єдиної авторизації. Соціальний граф (друзі, блокування) зазвичай реалізуємо через окрему таблицю з self-referencing FK та індексом на (user_id, friend_id, status) — без нього запит «чи є хтось із моїх друзів онлайн» при списку 500+ осіб дає full scan.
Пуш-сповіщення про повідомлення поза грою: Firebase Cloud Messaging для Android/iOS, WNS для Windows. Інтеграція через чергу — щоб піковий трафік сповіщень не блокував основний API.
Етапи роботи над модулем
Спочатку розбираємо ТЗ: типи каналів, максимальний онлайн, вимоги до історії, чи потрібна модерація, платформи. На цьому етапі з'ясовуємо, чи достатньо Photon Chat з коробки або потрібен кастомний бекенд.
Потім проєктуємо схему даних: таблиці chat_rooms, chat_messages, chat_members, індекси, політика TTL для старих повідомлень. Паралельно — архітектура real-time шару.
Розробка йде ітераціями: спочатку базовий обмін повідомленнями, потім історія та пагінація, потім ролі та модерація. Кожен етап закривається інтеграційними тестами на реальному Photon-оточенні.
Навантажувальне тестування — окремий етап. Симулюємо піковий онлайн через Photon Load Balancer + власні боти на headless Unity instance.
| Масштаб задачі | Орієнтовні терміни |
|---|---|
| Базовий чат (один канал, без історії) | 1–2 тижні |
| Чат з історією + приватні повідомлення | 3–4 тижні |
| Повний соціальний модуль (друзі, гільдії, сповіщення) | 6–10 тижнів |
| Кастомний сервер + модерація + аналітика | 10–16 тижнів |
Вартість розраховується індивідуально після аналізу вимог та поточної архітектури проєкту. Готові обговорити ваш проєкт? Зв'яжіться з нами — оцінимо терміни та вартість розробки чату під ключ.
Типові помилки при самостійній реалізації
Зберігати user_id відправника тільки на клієнті — сервер повинен підтверджувати ідентичність через токен, інакше будь-який пакет можна підмінити. Не реалізовувати rate limiting на рівні сервера — 10 повідомлень за секунду від одного клієнта кладуть канал. Використовувати синхронний запит до БД на кожне вхідне повідомлення замість батчингу — при 1000 повідомлень/с це 1000 INSERT/с, що вбиває Postgres без connection pool та bulk insert. Забувати про ON DELETE CASCADE в таблицях учасників при видаленні кімнати — залишає orphaned records, які потім знаходять тільки при аудиті.
Замовте розробку чату — отримайте готове рішення з документацією та підтримкою. Ми гарантуємо стабільність під навантаженням і прозорий процес.






