Я потратил много времени на рефакторинг хранилища предметов. Грустно видеть, что результаты большей части тяжелой работы — это просто увидеть эту картошку на полу.
Рефакторинг
Мне нужно было, чтобы сервер мог хранить все незакрепленные элементы в чанке, однако, как оказалось, для этого потребовался небольшой рефакторинг. Причина этого в том, что куски теперь должны хранить несколько разных типов «вещей», и было чище, чтобы код обрабатывал их отдельно:
Объекты
Сущности лишь слабо привязаны к чанку. Сущности - это NPC и другие игровые персонажи; это вещи, которые могут перемещаться по миру и контролируются либо узлом сущности, либо узлом игрока.
Сущности существуют на картах TMX, когда я создаю мир, но они существуют только как маркер для меня, чтобы определить, какие сущности должны быть созданы в мире и где они начинаются. Сущности могут свободно перемещаться по миру, хотя у NPC, как правило, нет никакой логики движения, поэтому они остаются на одном месте, а у мобов может быть некоторая логика в их поведении, заставляющая их возвращаться в свои исходные местоположения, если они не преследуют игрока.
Когда карта обрабатывается, эти маркеры сущностей удаляются из данных карты и перестают быть частью данных фрагмента, которые поступают в базу данных, а вставляются в другую часть базы данных как самостоятельные вещи.
Клиент игрока не знает о существовании объекта до тех пор, пока объект не окажется достаточно близко к игроку, чтобы он начал получать обновления местоположения для этого объекта. В этот момент клиент игрока может начать отображать объект игроку.
Статические объекты
Как было сказано в предыдущем посте, статические объекты существуют в фиксированных позициях в чанке. Они никогда не двигаются и существуют только для обеспечения интерактивности на карте. Это, как правило, такие вещи, как указатели, а иногда и контейнеры или другие триггеры. Статические объекты остаются в данных чанка и загружаются и выгружаются вместе с чанком. Они статичны на протяжении всей игры.
(Хотя сам статический объект может никогда не измениться, они могут указывать на диалоги, в которых может быть какое-то заскриптованное поведение. Таким образом, статический объект может дать каждому игроку предмет, но помните, что они уже раздали предмет и поэтому выиграли. не давать игроку более одного предмета)
Незакрепленные предметы
Это тот, с которым у меня были проблемы. Свободные элементы отличаются как от сущностей, так и от статических объектов.
Они чем-то похожи на статические объекты, потому что они существуют как часть чанка, поэтому их следует загружать/выгружать вместе с чанком, и они, конечно же, не публикуют никаких обновлений позиции (свободные элементы не просто бегают по своим местам). своя).
Но в отличие от Статических Объектов (и более похожих на Сущности), Свободные Элементы могут изменяться. Новые свободные предметы создаются в чанке, если игрок роняет предмет. Свободные предметы могут быть удалены из чанка, если игрок их подбирает.
В конце концов, мне нужно было реорганизовать хранилище фрагментов, чтобы хранить незакрепленные элементы как нечто среднее между статическим объектом и сущностью. Короче говоря, этот рефакторинг занял довольно много времени.
Собирание незакрепленных вещей
Проведя рефакторинг, я смог быстро добавить возможность собирать незакрепленные предметы из окружающей среды.
В этом примере я беру картошку.
Хотя это действие может быть простым, процесс, который потребовался для его достижения, был довольно обширным. Последовательность действий выглядит следующим образом:
- Прежде всего, чтобы поместить туда эту картошку, мне понадобился новый маркер свободных предметов в Tiled.
- Парсер Tiled должен был распознать это и вставить соответствующие записи в базу данных, чтобы создать свободный элемент.
- Когда игрок перемещается по карте, узел игрока отправляет данные фрагмента клиентам игрока. Эти данные должны включать все незакрепленные элементы в этом фрагменте.
- Клиент игрока должен иметь возможность получать этот список незакрепленных предметов и закладывать объекты загрузчика предметов.
- Затем объекты загрузчика элементов должны запрашивать тип объекта у сервера. Я не храню всю информацию об элементе внутри чанка, а храню только те элементы, которые находятся в чанке, загрузчик должен получить остальную информацию из базы данных.
- Узел игрока должен иметь возможность искать элемент в части базы данных Loose Items и возвращать тип и спрайт этого элемента. Эта система работает так же, как загружаются данные Entity.
- Клиент игрока должен иметь возможность получить эту информацию, а затем нарисовать реальный предмет.
- Когда игрок пытается забрать предмет, клиент игрока должен отправить этот запрос на получение на узел игрока для проверки.
- Узел игрока должен проверить, существует ли еще этот предмет (на случай, если два игрока попытаются схватить один и тот же предмет одновременно), и запретить его поднятие, если он уже исчез.
- Если получение предмета разрешено, узел игрока должен затем проверить, достаточно ли места в инвентаре игрока, чтобы подобрать предмет. Если нет запрета на пикап.
- Узел игрока также должен проверить, есть ли существующий предмет того же типа и качества, и сложить их. Если существующего предмета нет, предмет вместо этого помещается в пустой слот.
- Затем узел игрока должен уведомить все другие узлы игроков о том, что этот элемент не был удален из фрагмента, чтобы клиенты игрока могли прекратить показывать этот элемент игроку.
- Затем узел игрока должен уведомить игрока о его новом измененном инвентаре.
Простой акт сбора картошки включал в себя довольно сложную последовательность событий, которая заняла у меня гораздо больше времени, чем я ожидал.
Но теперь, когда это сделано, большая часть кода и архитектуры, необходимых для этого, поддерживает другие функции, связанные с предметами, такие как мобы, сбрасывающие предметы, или NPC, дающие предметы.
Контрольные суммы в плиточном загрузчике
Теперь с картой большего размера обработка карты и загрузка данных занимает несколько секунд. Генерируется несколько сотен записей базы данных, охватывающих все фрагменты, объекты и незакрепленные элементы в мире.
Поскольку большая часть существующего контента не меняется, я добавил систему контрольных сумм, чтобы данные, которые не изменились между загрузками карты, не приходилось загружать.
Сводка задач дня 18
Из-за вышеупомянутой задачи рефакторинга сегодня я выполнил только одну задачу, которая позволяла среде давать элементы.
Но это дало мне представление о том, как должна работать система предметов, и поэтому я лучше понимаю, какая работа остается для таких задач, как RPC предметов и выпадение предметов. Итак, несмотря на то, что сегодня я выполнил только одно задание, я не чувствую значительного отставания.
Завтра я поработаю над NPC, которые дают и берут предметы. Это может занять некоторое время, так как для этого потребуется добавить новые функции в диалоговую систему.