Девлог 1.0 | Как одна удобная фича сломала мне сервер и базу данных.

Девлог 1.0 | Как одна удобная фича сломала мне сервер и базу данных.

Привет! Продолжаем домучивать боевое лобби. Сегодня я хочу рассказать классическую историю о том, как благие намерения и забота об игровом UX (пользовательском опыте) могут привести к бессонной ночи, переписыванию архитектуры базы данных и борьбе с синхронизацией.

Часть 1. UX против ленивых разработчиков

Замечали, как в большинстве RPG устроена система смены экипировки? Чтобы переодеть персонажа, поменять снаряжение или руны, вас почти всегда заставляют идти в строго определенную локацию — на склад, итд.

Почему разработчики так делают? Им так банально удобнее. Одна конкретная зона отвечает за строго определенные запросы к серверу. Игрок зашел в таверну, спокойно переодел героев, пакеты улетели на сервер, данные сохранились. Безопасно, изолированно, предсказуемо.

Но для игрока это туповато из лишних кликов, экранов и загрузок. Я решил дать игроку гибкость. Зачем заставлять человека бегать в трактир перед каждым данжем, если можно дать ему возможность переодеться прямо в боевом лобби, за миг до старта? Функция написана, механика добавлена. И тут же моя забота об игроках превратилась в технический пи**ц.

Часть 2. Как сервер дал байтил, а Unity стёрла память.

Как только фича вышла в тест, на меня посыпалась куча багов с синхронизацией сервера. Дело в том, что на сервере стоит базовая защита от спама кликов (DDOS и пакетный флуд). Если отправлять запросы часто, сервер их просто отклоняет с ошибкой. Но опытные геймеры переодевают персонажей мгновенно — они помнят нужные сеты наизусть и кликают как киберспортсмены. Защиту сервера отключать нельзя. Логичное решение — сделать отправку данных отложенной. Игрок кликает, мы собираем все изменения в один пакет и отправляем его через небольшой таймаут. И тут наступил на вторую мину.

Представьте стандартный сценарий: быстрый игрок залетает в боевое лобби, за пару секунд перекидывает шмотки и мгновенно прожимает кнопку «В БОЙ!». В этот самый момент сцена боевого лобби в Unity полностью уничтожается и выгружается из памяти, чтобы уступить место тяжелой боевой сцене. Итог? Наш отложенный пакет данных просто не успевает отправиться. Сцена лобби уничтожена, скрипт прерван, отправка сбросилась. Игрок загружается на поле боя абсолютно голым, потому что сервер ничего не получил.

Сейчас моя основная задача — прописать все возможные сценарии поведения игрока и победить эту синхронизацию. Я перебираю обходные пути: от реализации «тихих» фоновых запросов, независимых от текущей сцены, до временного кеширования данных в глобальных синглтонах, которые переживают смену локаций. Сервер должен сохранять данные корректно при любых условиях.

Часть 3. Архитектурная мина из прошлого

Пока я возился с синхронизацией лобби, всплыл еще один косяк, на исправление которого ушла добрая половина ночи. Пришлось полностью переписать систему экипировки.

Когда я только начинал проектировать предметы в игре, первыми я написал «бустеры». Бустер — это классический стакающийся ресурс (как расходники или золото). У него есть фиксированные статы, и он работает по принципу пачки: если у тебя есть 10 одинаковых бустеров, они занимают один слот с цифрой «10». Я решил переиспользовать эту готовую систему и для экипировки, забыв об одной фундаментальной ошибке. Экипировка в RPG не может быть просто «типом предмета». Каждая шмотка при создании или дропе обязана иметь свой уникальный ID (Instance ID). Даже если у вас есть два одинаковых меча одинаковой редкости, которые по счастливой случайности зароллили абсолютно идентичные характеристики — это всё равно два разных предмета.

Если бы они стакались в пачки как бустеры, игрок физически не смог бы открыть и посмотреть статы конкретного меча на складе. Мне пришлось кардинально перелопатить всю архитектуру инвентаря и разделить предметы на категории: ресурсы/расходники, которые могут стакаться, и уникальная экипировка, где каждый предмет занимает свой слот на складе.

Всё наконец-то структурировано. Вместо вывода вот так одна маленькая и безобидная идея «а давайте разрешим менять шмот в лобби» заставила переписать половину сетевой логики и пересобрать базу данных предметов. Зато теперь система гибкая, честная и работает на благо игрока, а не ради удобства ленивого программиста.

Сообщества разработки игры: Tg Vk

2