Перейти к основному содержимому

Уровни и карты EternalTD

«Уровень» в EternalTD — это YAML-конфигурация в plugins/EternalTD/levels/ в паре с папкой шаблона мира в plugins/EternalTD/worlds/. Когда игрок присоединяется, EternalTD клонирует шаблонный мир в контейнер миров сервера и запускает сессию в этой клонированной копии.

Поля конфигурации уровня

ПолеТипПо умолчаниюПримечания
isEnabledbooltrueОтключённые уровни пропускаются при загрузке
levelNamestringnullОтображаемое имя, показываемое в сообщениях, таблицах и меню NPC
levelDescriptionсписок строк[]Строки, показываемые в меню NPC. Поддерживает плейсхолдеры $highscoreWave и $highscorePlayer
worldNamestringnullИмя папки шаблона в plugins/EternalTD/worlds/
startLocationсписок строкnullСписок сериализованных локаций, где спавнятся мобы
endLocationсписок строкnullСписок сериализованных локаций, к которым идут мобы («красные» плитки)
levelLocationsсписок строкnullКаждый проходимый квадрат сетки на уровне, генерируется автоматически при регистрации выбора этажа
wavesConfigFilestringобязательноИмя файла связанной конфигурации волны (waves/<name>.yml)
waveCountint-1Кэшированное количество волн, в настоящее время информационное
highscoreWaveint0Лучшая волна, достигнутая на этом уровне
highscorePlayerNamestring"no one"Отображаемое имя игрока, установившего рекорд
environmentenumNORMALОкружение мира, используемое при загрузке клонированного мира

Размер сетки, используемый повсюду, — 3 блока на логический квадрат (константа GRID_SIZE в коде).

Формат строки локации

Локации в EternalTD сериализуются как строки, разделённые запятыми, вида:

worldName,x,y,z,yaw,pitch

Обычно вы не пишете их вручную — /etd selectfloor плюс команды регистрации вычисляют и сохраняют их за вас.

Жизненный цикл мира

Когда игрок присоединяется к уровню:

  1. EternalTD ищет папку шаблона по worldName в plugins/EternalTD/worlds/.
  2. Он выбирает следующий свободный числовой суффикс (<worldName>_0, <worldName>_1, ...) и записывает клон в контейнер миров сервера, предварительно очищая любые устаревшие копии в старой или современной структуре.
  3. Клонированный мир загружается как временный пустой мир через TemporaryWorldManager из MagmaCore, поэтому миграция Paper 26.1+ изолируется.
  4. Игрок телепортируется в новый мир; внутренний InstanceProtector применяет правила защиты EternalTD.

Когда сессия заканчивается:

  • Любые оставшиеся игроки в клонированном мире телепортируются обратно в точку появления из config.yml или кикаются, если точка появления не настроена.
  • Клонированный мир выгружается и удаляется с диска (TemporaryWorldManager.permanentlyDeleteWorld).

Правила защиты инстанса

Пока уровень активен, в клонированном мире применяются следующие правила:

  • Взрывы отключены
  • Течение жидкостей отключено
  • Элитры отключены
  • Переключение полёта запрещено
  • Дружественный огонь запрещён
  • Стандартный спавн мобов запрещён

Рабочий процесс создания карт

Текущий процесс создания карт использует игровой инструментарий:

  1. Поместите папку шаблона мира в plugins/EternalTD/worlds/<worldName>/.
  2. Создайте или загрузите соответствующий YAML уровня в plugins/EternalTD/levels/.
  3. Выполните /etd reload и присоединитесь к миру уровня вручную (или откройте его в одиночной игре для настройки).
  4. Используйте /etd selectfloor и кликните правой/левой кнопкой по двум углам, чтобы отметить игровую область, или используйте /etd selectfloorcoordinates <x1> <y1> <z1> <x2> <y2> <z2>, чтобы задать их напрямую.
  5. Выполните /etd showselection <level>, чтобы убедиться, что выбор выглядит правильно.
  6. Выполните /etd register <level>, чтобы очистить выбор. Обратите внимание, что в текущей сборке ни register, ни showselection фактически не сохраняют область этажа — помощник, который должен сохранять levelLocations (LevelsConfigFields#addLevelLocations), определён, но ни одна команда его не вызывает. На данный момент levelLocations приходится вручную записывать в YAML уровня, если они ещё не заполнены загруженным пакетом.
  7. Встаньте на стартовую плитку спавна и выполните /etd register <level> start. Повторите для каждой стартовой плитки (эта команда действительно сохраняется в startLocation).
  8. Встаньте на конечную плитку и выполните /etd register <level> end. Повторите для каждой конечной плитки (эта команда действительно сохраняется в endLocation).
  9. Перезагрузите снова и протестируйте уровень, присоединившись к нему через меню NPC или /etd join <level>.

Команды выбора генерируют квадраты сетки по формуле:

size = abs(corner1 - corner2 + 1) / 3

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

Проверка пути

EternalTD выполняет проверку поиска пути A* всякий раз, когда устанавливается башня. Если установка башни оставит любую стартовую плитку без проходимого пути к любой конечной плитке, установка отклоняется, и золото не тратится.

Воздушные враги используют отдельный путь, который полностью игнорирует башни и вместо этого следует воздушному смещению (4 блока над настроенным путём).

NPC и меню уровней

Конфигурации NPC в plugins/EternalTD/npcs/ связывают NPC-жителей с одним или несколькими уровнями. Клик правой кнопкой мыши по NPC открывает инвентарь из 9 слотов, в котором каждый уровень показан как панель из зелёного окрашенного стекла с названием и описанием уровня.

ПолеТипПо умолчаниюПримечания
isEnabledbooltrueОтключённые NPC пропускаются
levelIDsсписок строкобязательноИмена файлов уровней, предлагаемых этим NPC
locationstringnullЛокация спавна в стандартном формате worldName,x,y,z,yaw,pitch
namestring"Default Name"Отображаемое имя NPC
difficultystring"Difficulty: Not Set"Метка сложности, показываемая над NPC
disguisestringnullДескриптор LibsDisguises (например, custom:etd_tutorial_npc)
customDisguiseDatastringnullДополнительные данные команды LibsDisguises — обычно длинная строка скина игрока

Житель появляется неуязвимым, с отключённым AI, постоянным и помеченным namespace-ключом NPC EternalTD. Если установлен LibsDisguises и заданы оба поля disguise и customDisguiseData, житель маскируется при спавне.

Плавающая стойка для брони с меткой difficulty спавнится в 2.3 блоках над NPC.

Поведение точки появления

DefaultConfig управляет тем, как игроки обрабатываются в мире-хабе:

  • setupDone — флаг, отслеживающий, было ли завершено руководство первоначальной настройки.
  • spawnLocations — по умолчанию etd_spawn,0,65,0,0,0. Используется только когда существует мир etd_spawn.
  • manageSpawn — по умолчанию true. Когда включено, присоединяющиеся игроки телепортируются в точку появления через 1 тик после входа.
  • playerGuide — текст игрового руководства.

Когда manageSpawn равно true и мир точки появления загружен, каждый игрок, присоединяющийся к серверу, телепортируется в spawnLocations.