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

Рефакторинг

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

Объекты

Сущности лишь слабо привязаны к чанку. Сущности - это NPC и другие игровые персонажи; это вещи, которые могут перемещаться по миру и контролируются либо узлом сущности, либо узлом игрока.

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

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

Клиент игрока не знает о существовании объекта до тех пор, пока объект не окажется достаточно близко к игроку, чтобы он начал получать обновления местоположения для этого объекта. В этот момент клиент игрока может начать отображать объект игроку.

Статические объекты

Как было сказано в предыдущем посте, статические объекты существуют в фиксированных позициях в чанке. Они никогда не двигаются и существуют только для обеспечения интерактивности на карте. Это, как правило, такие вещи, как указатели, а иногда и контейнеры или другие триггеры. Статические объекты остаются в данных чанка и загружаются и выгружаются вместе с чанком. Они статичны на протяжении всей игры.

(Хотя сам статический объект может никогда не измениться, они могут указывать на диалоги, в которых может быть какое-то заскриптованное поведение. Таким образом, статический объект может дать каждому игроку предмет, но помните, что они уже раздали предмет и поэтому выиграли. не давать игроку более одного предмета)

Незакрепленные предметы

Это тот, с которым у меня были проблемы. Свободные элементы отличаются как от сущностей, так и от статических объектов.

Они чем-то похожи на статические объекты, потому что они существуют как часть чанка, поэтому их следует загружать/выгружать вместе с чанком, и они, конечно же, не публикуют никаких обновлений позиции (свободные элементы не просто бегают по своим местам). своя).

Но в отличие от Статических Объектов (и более похожих на Сущности), Свободные Элементы могут изменяться. Новые свободные предметы создаются в чанке, если игрок роняет предмет. Свободные предметы могут быть удалены из чанка, если игрок их подбирает.

В конце концов, мне нужно было реорганизовать хранилище фрагментов, чтобы хранить незакрепленные элементы как нечто среднее между статическим объектом и сущностью. Короче говоря, этот рефакторинг занял довольно много времени.

Собирание незакрепленных вещей

Проведя рефакторинг, я смог быстро добавить возможность собирать незакрепленные предметы из окружающей среды.

В этом примере я беру картошку.

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

  1. Прежде всего, чтобы поместить туда эту картошку, мне понадобился новый маркер свободных предметов в Tiled.
  2. Парсер Tiled должен был распознать это и вставить соответствующие записи в базу данных, чтобы создать свободный элемент.
  3. Когда игрок перемещается по карте, узел игрока отправляет данные фрагмента клиентам игрока. Эти данные должны включать все незакрепленные элементы в этом фрагменте.
  4. Клиент игрока должен иметь возможность получать этот список незакрепленных предметов и закладывать объекты загрузчика предметов.
  5. Затем объекты загрузчика элементов должны запрашивать тип объекта у сервера. Я не храню всю информацию об элементе внутри чанка, а храню только те элементы, которые находятся в чанке, загрузчик должен получить остальную информацию из базы данных.
  6. Узел игрока должен иметь возможность искать элемент в части базы данных Loose Items и возвращать тип и спрайт этого элемента. Эта система работает так же, как загружаются данные Entity.
  7. Клиент игрока должен иметь возможность получить эту информацию, а затем нарисовать реальный предмет.
  8. Когда игрок пытается забрать предмет, клиент игрока должен отправить этот запрос на получение на узел игрока для проверки.
  9. Узел игрока должен проверить, существует ли еще этот предмет (на случай, если два игрока попытаются схватить один и тот же предмет одновременно), и запретить его поднятие, если он уже исчез.
  10. Если получение предмета разрешено, узел игрока должен затем проверить, достаточно ли места в инвентаре игрока, чтобы подобрать предмет. Если нет запрета на пикап.
  11. Узел игрока также должен проверить, есть ли существующий предмет того же типа и качества, и сложить их. Если существующего предмета нет, предмет вместо этого помещается в пустой слот.
  12. Затем узел игрока должен уведомить все другие узлы игроков о том, что этот элемент не был удален из фрагмента, чтобы клиенты игрока могли прекратить показывать этот элемент игроку.
  13. Затем узел игрока должен уведомить игрока о его новом измененном инвентаре.

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

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

Контрольные суммы в плиточном загрузчике

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

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

Сводка задач дня 18

Из-за вышеупомянутой задачи рефакторинга сегодня я выполнил только одну задачу, которая позволяла среде давать элементы.

Но это дало мне представление о том, как должна работать система предметов, и поэтому я лучше понимаю, какая работа остается для таких задач, как RPC предметов и выпадение предметов. Итак, несмотря на то, что сегодня я выполнил только одно задание, я не чувствую значительного отставания.

Завтра я поработаю над NPC, которые дают и берут предметы. Это может занять некоторое время, так как для этого потребуется добавить новые функции в диалоговую систему.