Skip to content

[dev] Структура проекта (Russian)

Hunternif edited this page Feb 24, 2017 · 5 revisions

Java packages

hunternif.mc

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

В CommonProxy загружаются из сохраненных конфигов id для структур, которые могли модифицировать разве что какие-то сторонние моды.

В ClientProxy загружаются конфиги с id для текстур тайлов и маркеров. Тут же им задаются дефолтные значения. Где-то здесь кроется баг https://github.com/Hunternif/AntiqueAtlas/issues/93. Всю эту систему хочется переделать, наметки описаны тут: https://github.com/Hunternif/AntiqueAtlas/issues/16

SettingsConfig хранит глобальные настройки для мода, которые можно редактировать в файле. Когда-нибудь нужно сделать их в GUI

.api

API для стронних модов. Здесь должны быть все основные функции, которые Атлас потенциально может выполнять для других модов: ставить кастомные текстуры, модифицировать карты, добавлять объекты, маркеры и т.п. Интерфейсы и реализации разделены, чтобы 1) в интерфейсах можно было просто прочитать описание методов в javadoc, без лишней информации; и 2) чтобы можно было выделить интерфейс в отдельную, "легкую", чисто-api версию мода, чтобы другие моды могли с ней компилироваться. (Не уверен, нужно ли это, но некоторые другие моды вроде так делают). См. API.

.client

Все, что является чисто клиентской частью: загрузка и отбражение текстур, GUI. Основные классы здесь вроде все продокументированы. TextureSet - не самое удачное название, но эта штука отвечает за текстурирование тайла одного заданного типа. "Set", потому что она содержит в себе несколько файлов текстур, которые выбираются в случайном порядке для каждого отдельно взятого тайла на карте, чтоб картинка получалась не слишком однородной. См. Editing-Textures.

.client.gui

В client.gui.core лежит нечто типа самопальной универсальной библиотеки GUI-компонент для майнкрафта. Можно их допиливать, но смысл в том, чтобы они были универсальными.

В идеале на каждый новый элемент интерфейса стоит выделять отдельный класс, и потом собирать их как конструктор.

Класс GuiAtlas - главный компонент для отображения атласа. Этот класс слишком большой и сложный, его точно нужно отрефакторить. Но не срочно, ибо работает.

.core

Все, что связано с хранением тайловой информации атласов. Один тайл обычно соответствует какой-то биоме и хранит ее biomeId. Основная структура AtlasData, разбита на DimensionData по измерениям типа "Overworld", "Nether", "End". Kenkron дорабатывал эту структуру, мне кажется довольно разумно: https://github.com/Hunternif/AntiqueAtlas/pull/105

Классы BiomeDetector* сканируют чанк (16х16 блоков) и выдают тип тайла, который наиболее подходит для его отображения. Тут отдается приоритет некоторым биомам или даже отдельным блокам, например, чтобы на карте были видны всякие мелкие речки и прудики.

.ext

Все, что связано с отображением особых структур: поселений NPC, адских крепостей и т.п. Структуры отображаются тайлами, вместо биом, и используют отрицательные значения biomeId, т.е. это "псевдобиомы". Обычно для каждой структуры добавлен класс "watcher", котрый следит за событиями в мире, и в какой-нибудь подходящий момент добавляет тайл/маркер на карту (или на все карты у всех игроков). Здесь нужно учитывать, что некоторые атласы старых версий уже существовали до появления этой структуры. Хотя если каждый раз заново перезаписывать тайл поверх старго , то в принципе ничего не сломается. (Не помню, возможно, сейчас так и происходит.) TheCodeWarrior занимался неким универсальным StructureWatcher для сторонних модов, но пока хз, работат ли оно.

.item

Атласы-книжки в виде майнкрафтовских предметов и крафт-рецепты к ним. Ничего интересного.

.marker

Все, что связано с маркерами. См. комментарии к классам. TheCodeWarrior сделал какие-то навороченные универсальные типы маркеров, см. hunternif.mc.registry.MarkerType

.network

Пакеты для общения клиентов и сервера. В client идут пакеты, которые отправляются от сервера клиентам, в server - от клиента к серверу, в bidirectional - в обе стороны. Действия, за которые отвечают пакеты client, казалось бы, исходят от игрока на клиенте, но почти все эти действия типа использования предметов, нажатия клавиш, кнопок в GUI идут на сервер по другим стандартным каналам, и в любом случае сервер должен провалидировать каждое действие (например, чтобы один игрок на хакнутом клиенте не мог влиять на чужой атлас) и рассылать обновления на все подключенные клиенты. В идеале в пакете не должно быть логики, а только вызов API.

.registry

Новый способ учета всяких сущностей, который ввели, кажется, в 1.9. Я еще толком не разобрался, но звучит довольно разумно, и скорее всего, имеет смысл перевести учет текстур-сетов, их id и т.п. на эту систему. Об этом ниже.

.util

Разные утилитные классы. Отдельного внимания заслуживает класс ExportImageUtil - он отвечает за экспорт всего атласа в PNG-картинку. Тут по сути частично дублируется рендеринг карты на экране из GuiAtlas. Этот класс довольно большой, хотелось бы его отрефакторить. Также TheCodeWarrior реализовал экспорт очень больших картинок по кусочкам, и я нифига не понял, как это работает, но спасибо ему большое.

kenkron.antiqueatlasoverlay

Маленькая карта, которая отображается в правом верхнем углу, когда GuiAtlas закрыт.

Синхронизация id между клиентом и сервером

Информация о том, какой биом находится в заданном тайле каждого Атласа, хранится с помощью численного id этой биомы, которых всего в оригинальном майнкрафте может быть 256. Возможно, эта информация не верна или устарела. При этом каждый мод может для своих кастомных биом может задавать hard-coded id и сохранять его в конфиге, где игрок потом может его еще и отредактировать вручную. В случае конфликта id биом из разных модов Forge перекидывает биому на свободный id и сохраняет его в конфиге. (Не верю, что все существующее многообразие модов умещается в 256 биом. Что же Forge делает, если их больше 256?)

Для нас это означает, что на серверах и клиентах с по-разному настроенными модами одни и те же числа biomeId могут означать разные биомы. То же самое справедливо для структур, т.к. они используют те же численные biomeId. Поэтому необходимо при подключении клиента к серверу производить синхронизацию - запрашивать у сервера его текущую схему соответствия (псевдо-)biomeId и текстур-сетов. Это делается с помощью TileNameIDPacket.

Более того, даже на локальном клиенте после установки новых модов может измениться конфигурация biomeId, т.е. атласы в старых и в новых мирах должны использовать разные конфиги. Сейчас это не сделано, локально хранится только один конфиг на весь мод, и изменения в нем влияют на все миры одинаково.

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

Система получается немного запутанная. Возможно, использование Registry поможет сделать ее более прозрачной.

Сюда же нужно включить поддержку текстур-паков и кастомных маркеров, чтобы их можно было легко подключать и отключать, как ресурс-паки. Текстур-паки могут заменять существующие конфиги текстур-сетов или дополнять их для поддержки кастомных биом других модов. Например, Golrith's pack, который заменяет стандартные коричневые тайлы на цветные. Сейчас это реализовано через редактирование текстовых файлов конфигов, довольно криво: см. Editing-Textures, Adding-Custom-Markers.