Age of empires 2 редактор сценариев
Познав основы и теорию расписанные в этой статье мы готовы перейти к практике. Давайте на примере разберем создание карты с начала и до конца. В качестве эксперимента мы создадим карту для ФФА, которая получит название FFA Ring.
СОЗДАЕМ ФАЙЛ
Открываем Блокнот и создаем текстовый документ с расширением FFA Ring.rms. Сохраняем его в папку путь_к_игре\steamapps\common\Age2HD\resources\_common\random-map-scripts
Запускаем игру, открывает редактор сценариев и загружаем нашу карту в него. Генерируем. Получили пустую зеленую площадки. Это наша холст, на котором нам предстоит нарисовать карту для ФФА.
PLAYER_SETUP
Первым делом вписываем нашу карту пользовательские установки и комментарии по желанию:
<PLAYER_SETUP>
random_placement
ai_info_map_type ARENA 0 0 0
LAND_GENERATION
Второй этап. Создание основных зон (земель). Чтобы добавить в карту разнообразия, мы будем использовать встроенный рандомизатор. Зададим два варианта развития событий: лесная карта и тропическая. И пропишем разные условия:
if FOREST_MAP
base_terrain FOREST
else
base_terrain JUNGLE
endif
Мы видим, что Лесная и Тропическая карта будут генерироваться в соотношении 50 на 50. Дальше оператором if мы задаем, что если Лесная карта – то основным ландшафтом у нас будет Лес (FOREST), а если тропическая – то пальмовые джунгли (JUNGLE)
Отлично. Готово. Теперь нам нужно создать некое подобие ринга в центре и базы игроков.
Начнем с ринга в центре. Однозначно, что лес в центре нас не устраивает, поэтому мы создаем ринг используя по аналогии Траву (для Лесной карты) или Песок (для тропической)
if TINY_MAP
base_size 16
elseif SMALL_MAP
base_size 16
elseif MEDIUM_MAP
base_size 18
elseif LARGE_MAP
base_size 20
else
base_size 22
endif
right_border 32
top_border 32
bottom_border 32
left_border 32
Как видим, мы задаем размер ринга в ручную, в зависимости от размера карты. Границы ринга мы сдвигаем от края карты на 32%.
Вот что в итоге мы получаем:
Следующим этапом добавляем земли игроков. Так же точно, прописываем разные ландшафты для Лесной/Тропической карты. Размер базы игроков в зависимости от размера карты. От края карта отступаем по вкусу, я поставил 6%, чтобы игроки имели небольшую полоску бэкового леса.
if TINY_MAP
base_size 14
bottom_border 3
top_border 3
left_border 3
right_border 3
land_percent 50
elseif SMALL_MAP
base_size 14
bottom_border 4
top_border 4
left_border 4
right_border 4
land_percent 50
elseif MEDIUM_MAP
base_size 12
bottom_border 5
top_border 5
left_border 5
right_border 5
land_percent 55
elseif LARGE_MAP
base_size 12
bottom_border 6
top_border 6
left_border 6
right_border 6
land_percent 60
elseif HUGE_MAP
base_size 12
bottom_border 6
top_border 6
left_border 6
right_border 6
land_percent 65
else
base_size 12
bottom_border 6
top_border 6
left_border 6
right_border 6
land_percent 70
endif
other_zone_avoidance_distance 12
clumping_factor 15
>
clumping_factor 15 – опять же цифра 15 для создания максимально квадратной базы игрока
Еще раз проверяем:
Неплохо. Хотя очевидно, что некоторые игроки генерируются закрытые полосой из леса от ринга. Позже, мы это, разумеется, исправим.
В принципе, по ландшафту нас все устраивает.
Но база игрока выглядит совсем пустой и одинокой. Давайте добавим туда небольшие островки леса. Для этого мы переходим к следующему параметру
TERRAIN_GENERATION
if FOREST_MAP
create_terrain PINE_FOREST
base_terrain GRASS2
else
create_terrain PALM_DESERT
base_terrain DESERT
endif
land_percent 4
number_of_clumps 20
clumping_factor 25
spacing_to_other_terrain_types 3
set_avoid_player_start_areas
set_scale_by_groups
>
Как видим, мы снова прописываем оператор if и создаем Сосновый лес на базе игрока (если Лесная карта), либо Пальмовый лес (если у нас Тропическая карта).
land_percent 4 – задаем процент занимаемой территории
number_of_clumps 20 – устанавливаем общее количество скоплений
clumping_factor 25 – задаем форму скоплений (по умолчанию 20). Чем выше цифра, тем более квадратные скопления.
spacing_to_other_terrain_types 3 – расстояние до других элементов ландшафта (чтобы наши островки бонусного леса не сливались с другим лесом)
set_avoid_player_start_areas – применяем этот параметр, чтобы наши островки леса не заспамились прямо на нашем ТЦ
set_scale_by_groups – ставим масштаб скоплений в зависимости от размера карты
OBJECTS_GENERATION
Теперь мы добавляем объекты по вкусу. Ниже, я думаю вы уже в состоянии понять, что и почему мы создаем. Обращу внимание на несколько моментов.
В каждой карте необходимо прописывать условия для Цареубийства и не забыть добавить на карту как минимум короля (оператор: if REGICIDE).
Все остальное по большому счету является стандартным.
create_object TOWN_CENTER
set_place_for_every_player
min_distance_to_players 0
max_distance_to_players 0
>
create_object VILLAGER
set_place_for_every_player
min_distance_to_players 6
max_distance_to_players 6
>
create_object SCOUT
number_of_objects 1
set_place_for_every_player
min_distance_to_players 7
max_distance_to_players 9
>
create_object FORAGE
number_of_objects 6
group_placement_radius 3
set_tight_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 10
max_distance_to_players 12
min_distance_group_placement 6
max_distance_to_other_zones 12
>
create_object PALISADE_WALL
set_place_for_every_player
min_distance_to_players 16
max_distance_to_players 20
>
/* SPECIAL STUFF FOR REGICIDE */
if REGICIDE
create_object VILLAGER
number_of_objects 7
set_place_for_every_player
min_distance_to_players 6
max_distance_to_players 6
>
create_object KING
set_place_for_every_player
min_distance_to_players 6
max_distance_to_players 6
>
create_object DEER
number_of_objects 3
number_of_groups 1
set_loose_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 16
max_distance_to_players 20
>
create_object BOAR
number_of_objects 2
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 16
max_distance_to_players 22
temp_min_distance_group_placement 20
>
if RDEER
create_object DEER
number_of_objects 3
number_of_groups 1
set_loose_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 18
max_distance_to_players 22
>
else
create_object FORAGE
number_of_objects 4
number_of_groups 1
group_placement_radius 3
set_tight_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 16
max_distance_to_players 20
min_distance_group_placement 6
>
endif
/* NEAR GOLD */
create_object GOLD
number_of_objects 7
set_tight_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 12
max_distance_to_players 16
min_distance_group_placement 8
max_distance_to_other_zones 12
if FOREST_MAP
terrain_to_place_on GRASS2
else
terrain_to_place_on DESERT
endif
>
/* MEDIUM GOLD */
create_object GOLD
number_of_objects 5
number_of_groups 2
set_tight_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 20
max_distance_to_players 26
min_distance_group_placement 7
temp_min_distance_group_placement 25
max_distance_to_other_zones 10
if FOREST_MAP
terrain_to_place_on GRASS2
else
terrain_to_place_on DESERT
endif
>
/* NEAR STONE */
create_object STONE
number_of_objects 5
group_placement_radius 2
set_tight_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 14
max_distance_to_players 18
min_distance_group_placement 7
max_distance_to_other_zones 10
if FOREST_MAP
terrain_to_place_on GRASS2
else
terrain_to_place_on DESERT
endif
>
if FOREST_MAP
create_object FOREST_TREE
else
create_object PALM_FOREST_TREE /* отдельно стоящие деревья */
endif
number_of_objects 2
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 4
max_distance_to_players 4
temp_min_distance_group_placement 6
>
if FOREST_MAP
create_object FOREST_TREE
else
create_object PALM_FOREST_TREE /* отдельно стоящие деревья */
endif
number_of_objects 2
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 5
max_distance_to_players 7
temp_min_distance_group_placement 6
>
create_object SHEEP
number_of_objects 4
number_of_groups 1
set_loose_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 6
max_distance_to_players 6
min_distance_group_placement 10
>
create_object SHEEP
number_of_objects 2
number_of_groups 2
set_loose_grouping
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 13
max_distance_to_players 18
min_distance_group_placement 2
temp_min_distance_group_placement 20
>
Отлично. Базы игрока на месте. Ресурсы есть. Жизнь кипит.
OBJECTS_GENERATION (Конфигурация Ринга)
Нужно добавить изюминки на наш ринг. Сделаем это таким образом: добавим на центр Золото, Камень и Волков. А также добавим Реликвий.
Обратите внимание, что поскольку ландшафт ринга у нас имеет название GRASS (DIRT), то мы должны использовать соответствующую инструкцию terrain_to_place_on GRASS ( terrain_to_place_on DIRT3). Чтобы наше дополнительное золото не с генерировалось где-нибудь на задворках базы игрока.
create_object GOLD
if FOREST_MAP
terrain_to_place_on GRASS
else
terrain_to_place_on DIRT3
endif
number_of_objects 4
number_of_groups 16
group_variance 1
set_tight_grouping
set_gaia_object_only
temp_min_distance_group_placement 5
>
create_object STONE
if FOREST_MAP
terrain_to_place_on GRASS
else
terrain_to_place_on DIRT3
endif
number_of_objects 4
number_of_groups 8
group_variance 1
set_tight_grouping
set_gaia_object_only
temp_min_distance_group_placement 5
resource_delta 3200
>
create_object WOLF
if FOREST_MAP
terrain_to_place_on GRASS
else
terrain_to_place_on DIRT3
endif
number_of_groups 32
number_of_objects 1
set_scaling_to_map_size
set_gaia_object_only
min_distance_group_placement 12
>
/* RELICS */
create_object RELIC
number_of_objects 1
set_gaia_object_only
set_place_for_every_player
min_distance_to_players 15
min_distance_group_placement 20
>
CONNECTION_GENERATION
create_connect_all_lands
replace_terrain JUNGLE DIRT
replace_terrain DESERT DESERT
replace_terrain FOREST GRASS2
replace_terrain GRASS2 GRASS2
terrain_cost JUNGLE 40
terrain_cost DESERT 3
terrain_cost FOREST 40
terrain_cost GRASS2 3
terrain_size DESERT 0 0
terrain_size GRASS2 0 0
terrain_size JUNGLE 9 1
terrain_size FOREST 9 1
>
Обратите внимание, что поскольку у нас задействованы как джунгли, так и лес, то и параметры соединения мы прописываем как для тех, так и для других.
Отлично! Теперь все игроки имеют доступ на ринг! Наша карта готова к тестам и играм.
О том, как загрузить вашу карту в мастерскую Стим вы можете прочитать здесь.
Первая часть статьи, посвященная созданию rms-карт в Age of Empires II здесь.
Среди прочих замечательных возможностей, доступных в редакторе, самой потрясающей является функция определения триггеров. Они приводят к выполнению действия на основании условий. Мне показалось очевидным, что начинать стоит отсюда, потому что здесь осуществляется задание правил. При этом возник вопрос: какие типы триггеров мне нужно искать конкретно? Разумеется, те, которые удовлетворяют требованиям машины Тьюринга! Это значит, что условия и действия этих триггеров должны позволить реализовать следующее:
1. Считывать и записывать символы
2. Менять позицию в моём «пространстве памяти»
3. Иметь «ленту» или «память»
4. Иметь пул используемых символов
Кроме того, мне нужно иметь возможность записывать какие-нибудь правила. Здесь также будет очень полезен доступ к логике высказываний. С этого я и начал свои исследования (то есть с поисков в Гугле), и через полчаса получил все нужные мне ответы.
Достаточно удовлетворяют требованиям следующие объекты, условия и эффекты:
Пул символов: любое число игровых юнитов
Пул памяти: все типы юнитов, доступных в игре (см. примечание в конце поста)
Изменение позиции в памяти: Create Object
Запись в позицию памяти: Create Object, Task Object, Kill Object
Чтение из позиции памяти: Own Objects, Own Fewer Objects
Вот пример использования типов игровых юнитов в качестве «ячеек» памяти:
В этом примере память выглядит так: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Но мы можем очень просто изменить память с помощью триггеров, чтобы она выглядела так:
То есть: 8, 1, 8, 1, 1, 8, 1, 1, 1, 1
В следующем разделе триггеры представлены как способ запуска «программы» и отображения очень странного потока данных. Триггеры можно настроить на автоматическое срабатывание при запуске игры, а также на постоянное срабатывание для организации бесконечного цикла. Это основная движущая сила программы, которая позволяет структурировать такие «программы» двумя способами:
Все три триггера (T) срабатывают одновременно и сконфигурированы таким образом, что условия (С) заставляют их срабатывать в нужное время.
T1 «управляет» программой, являясь единственным триггером, начинающим работать при запуске игры и выполняющим бесконечный цикл. Он передаёт выполнение триггеру T2, а затем T2 запускает T3 и T4, но они сами между собой решают, кто из них должен выполняться (похоже на то, как ведут себя триггеры при параллельном выполнении, или на то, что ниже делает XOR).
Мне кажется, что это более практичный способ структурирования таких программ, и он эффективнее, потому что содержит меньше инструкций.
Имеет ли редактор сценариев какую-то возможность для реализации логики выражений? Да. У нас есть доступ к условиям, то есть мы можем создать if -> then, а это в сочетании с Own Objects и Own Fewer Objects, позволяет получать доступ к памяти и выполнять сравнения.
Мы можем объединить два выражения/условия, поэтому можно просто реализовать операции «AND»:
Также с помощью триггеров можно реализовать частичное «OR». Проблема с ним в том, что если обе ветви истинны, то будут выполнены оба триггера. Поэтому более полезным оператором будет «XOR»:
Оба триггера срабатывают одновременно, но выполняется только одна ветка эффектов, потому что условие Condition 1 должно быть истинным в одной, но ложным в другой, и наоборот для условия Condition 2.
Также с помощью Own Fewer Objects, Create Object, Task Object и Kill Object можно легко реализовать сложение и вычитание:
Пример того, как это может выглядеть в игре:
Нам необходим Task Object, потому что игра не будет создавать больше одного объекта в одной точке, поэтому мы заставляем его переместиться.
Результат этой операции можно найти в счётчике юнитов в верхней части экрана.
Более сложный, но полезный набор триггеров и условий позволяет выполнять операции проверки на равенство, в том числе «равно», «меньше или равно», «больше или равно». Однако для их правильной работы нам нужно ввести специальный символ «останова» — короля (King):
Конфигурация для «больше ли 23, чем 9» будет иметь вид:
Эта система будет постоянно создавать солдат, пока их не станет 23. Если у нас их окажется 9 или больше, это будет означать, что 23 больше, чем 9 и для обозначения этого мы создаём короля (King). В процессе создания сценариев можно изменить юнита «останова» на любого другого, или создать любое нужное их количество.
В целом это не особо полезно, но всё равно здорово!
К сожалению, мне не удалось найти простого способа записывать видео, но если кому-то это удастся, то я добавлю их сюда.
Файлы _publish-info.txt и _preview-icon.jpg:
В _publish-info.txt мы пишем:
Visibility=PUBLIC
Description=Описание карты
SETTINGS:
Какие то особенности карты. Конфигурации. Настройки.
NOTES:
Тут пишем все что угодно или можно не писать ничего.
2. Теперь мы готовы загружать материалы в Стим. Запускаем игру. В главном меню выбираем: Мастерская Steam.
Теперь у нас в списке модов появился и наш мод (еще не опубликованный). Выбираем его и нажимаем внизу кнопочку Опубликовать.
В появившемся окошке удаляем майкрософтовское описание и пишем свое, подобно тому, что писали в _publish-info.txt (именно это описание загрузиться в мастерскую стима). Жмем Готово.
3. Если мы все сделали верно – то увидим вот такое окошко загрузки нашего мода в мастерскую:
5. Наслаждаемся результатом. Наша карта опубликована в Мастерской и доступна к подписке игрокам со всего мира
Триггеры создаются во вкладке «триггеры». Триггер задает действие и условие при котором действие совершится. Например, нам надо чтобы у русских с начала игры были открыты все улучшения 5 эпохи (постимпериализм). Для этого в разделе “условия” задается always (всегда). В этом случае действие совершится сразу после начала сценария. В разделе “эффекты” (сами действия), выбираем set tech status (выбрать статус технологии), там открывается список всех возможных улучшений. Выбираем postimperial Russians и игрока. Всё, триггер готов. Теперь после запуска сценария все улучшения русских будут открыты игроку.
Читайте также: