Розробка чатів та соціальних модулів ігор
Мультиплеєрний чат — це не UI-віджет поверх гри. Це синхронізований канал станів між клієнтами, який працює на тих же серверах, що й ігрова логіка, та повинен витримувати пікові навантаження без деградації RTT. Коли розробники вперше сталкиваються з завданням «додати чат», вони нерідко прикручують WebSocket-обгортку поверх готової Photon-сесії — та через місяць отримують race condition між подіями чату та подіями ігрового стейту, тому що обидва потоки йдуть через один RaiseEvent channel без пріоритизації.
Де звичайно ломається перша реалізація
Найчастіша помилка — використовувати один транспортний канал для ігрових подій та сообщень чату. У Photon Realtime кожен канал (channel) має FIFO-гарантію всередині себе, але не між каналами. Якщо ігрові RaiseEvent з кодами руху гравця та текстові сообщення йдуть через channel 0, при всплеску активності у чаті затримка позицій зростає до 200–300 мс навіть при хорошому пінгу — просто через чергу. Рішення очевидне: виділити окремий unreliable-канал для чату з низьким пріоритетом та reliable-канал для системних сообщень (kick, ban, invite).
Друга проблема — зберігання історії. Багато команд зберігають історію чату прямо в комнаті Photon через CustomRoomProperties, що працює до тих пір, поки не перевищується ліміт 1 КБ на властивість. Після цього сообщення просто втрачаються без помилки на клієнті. Правильний підхід: виносити історію на окремий мікросервіс з PostgreSQL або Redis Streams, а в комнаті тримати тільки вказівник на останній прочитаний offset.
Третя біль — модерація у реальному часі. Наївна фільтрація через RegExp на клієнті обходиться за секунди. Серверна валідація через webhook у Photon WebHooks v2 додає latency до кожного сообщення. Рабочий компроміс: асинхронна постмодерація з мгновенним показом сообщення відправнику та затримкою доставки решті через буфер 50–100 мс, за які успіває відпрацювати ML-фільтр.
Як будуємо соціальний шар поверх ігрової сесії
Чат — це видима частина. Під ним обычно потрібні: список друзів, інвайти, система гільдій/кланів, статуси онлайн/оффлайн, повідомлення. Photon надає Photon Chat як окремий SDK з власними серверами — вирішує базові завдання (публічні канали, приватні сообщення), але не розуміє кастомних ролей та прав доступу. Для ігор з гільдіями це обмеження критично.
Типова архітектура, яку використовуємо для mid-core проектів: Photon Chat для real-time доставки + власний 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.
Інструменти та інтеграції
Для Unity-проектів основний стек: Photon Chat SDK, Photon Realtime для ігрових подій, Mirror Networking або Netcode for GameObjects як альтернативи для p2p-схем. Серверна частина чату — Photon WebHooks v2 для хуків на события + кастомний мікросервіс для бізнес-логіки.
Для кроссплатформенних проектів (PC + Mobile + Console) важна підтримка OpenID Connect для єдиної авторизації. Соціальний граф (друзі, блокування) звичайно реалізуємо через окрему таблицю з self-referencing FK та індексом на (user_id, friend_id, status) — без нього запит «онлайн ли кто-то з моїх 500+ друзів» дає full scan.
Push-повідомлення поза грою: 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, які потім знаходять тільки при аудиті.





