Дневник разработчиков Stellaris №135 — Изменение скриптов и создание модов в версии 2.2
Приветствую!
Сегодня мы поговорим об изменениях скриптов в обновлении 2.2 «Ле Гуин». Мы собираемся углубиться в детали, так что не стесняйтесь пропустить этот дневник и вскочить на хайп-трейн в Твиттере, если вам не интересны вопросы создания модов.
Я не смогу охватить все изменения версии 2.2 в этом дневнике, но расскажу об основных, чтобы вы смогли начать раздумывать, как же вам обновить ваш мод!
Сперва рассмотрим различные мелочи:
- Последовательный синтаксис if/else_if/else теперь применим как для триггеров, так и для эффектов. Проверьте, чтобы ваш мод соответствовал изменениям: старый синтаксис может быть пропущен при записи ошибок в лог, но может вызвать непредусмотренное поведение.
- Триггеры и эффекты со вшитыми в код ссылками на ресурсы были частично или полностью удалены и заменены альтернативными, которые могут работать с новыми ресурсами, которые вы захотели добавить в скрипт. Например, вместо «energy >= 200» теперь будет «resource_stockpile_compare = { resource = energy value >= 200 }», а также «add_resource = { my_mod_resource = 10 }» и т.д.
- Большая часть новых экономических единиц используют новый набор автосоздаваемых модификаторов; если вы добавляете новый район, то у него будет модификатор на увеличение числа этих районов на планете. Если вы создаёте новую должность, у неё будет модификатор на добавление таких должностей и т.д. Это обретёт смысл, когда вы познакомитесь с системой поближе.
- Вес эффекта «Random_*»! Мы вытащили его из глубочайшей дыры в недрах кода. Кое-кто из вас мог уже разобраться в том, как он работает. Практически всем эффектам с «Random_*» (например, random_playable_country, random_owned_ship и т.д.) можно задать вес, чтобы некоторые из объектов выбирались чаще других (но там всё равно используется основной критерий ограничения). Весам требуется базовое значение и модификаторы, прибавляющие или умножающие.
Пример веса «Random_*»
random_playable_country = {
limit = { # has comms with 16 or more empires
count_country = {
limit = {
is_country_type = default
has_communications = prev
}
count >= 16
}
}
weights = {
base = 1
modifier = { # strongly weighted towards democracies
add = 6
has_authority = auth_democratic
}
modifier = { # twice as likely for players
mult = 2
is_ai = no
}
}
country_event = { id = my_mod.1 }
}
Изменение планет и экономики
Как вам скажет любой контент-дизайнер, лучший способ изучить скрипт — это прочесть скрипт (работа с другими разработчиками Paradox тоже помогает, но не всем повезло). Поэтому я выложу здесь несколько примеров краеугольных камней новой экономики и постквадратной системы планет: планетарные особенности, районы, сооружения, должности, социальные страты и базы данных ресурсов.
Планетарные особенности
common\deposits\
Старая концепция месторождений была переработана в планетарные особенности, хотя в скриптах они всё ещё указаны как deposits. Они более гибки, чем прежние месторождения, теперь, когда они более не привязаны к системе квадратов. Они могут измениться при терраформировании или оказывать глобальные эффекты на планету, а блокировщики могут оказать какие-либо эффекты после очистки игроком.
Пример обычной особенности:
d_rich_mountain = {
is_for_colonizeable = yes
use_for_min_max_adjustments = yes
category = deposit_cat_minerals
use_weights_for_terraforming_swap_types = yes
should_swap_deposit_on_terraforming = yes
terraforming_swap_types = {
d_submerged_ore_veins
}
planet_modifier = {
district_mining_max = 3
}
potential = {
OR = {
is_planet_class = pc_continental
is_planet_class = pc_desert
is_planet_class = pc_alpine
is_planet_class = pc_arctic
is_planet_class = pc_arid
is_planet_class = pc_tundra
is_planet_class = pc_gaia
}
}
drop_weight = {
weight = @low
modifier = {
factor = @planet_type_bonus
is_cold = yes
}
}
}
Пример орбитальной добывающей/исследовательской особенности:
d_minerals_2 = {
resources = {
category = orbital_mining_deposits
produces = {
minerals = 2
}
}
station = shipclass_mining_station
is_for_colonizeable = no
potential = {
OR = {
is_planet_class = pc_asteroid
is_planet_class = pc_molten
is_planet_class = pc_toxic
is_planet_class = pc_frozen
is_planet_class = pc_barren
is_planet_class = pc_barren_cold
is_planet_class = pc_broken
is_planet_class = pc_shattered
}
}
drop_weight = {
weight = 5
modifier = {
factor = 0.5
OR = {
is_planet_class = pc_molten
is_planet_class = pc_toxic
is_planet_class = pc_frozen
}
}
modifier = {
factor = 2.0
is_asteroid = yes
}
}
}
Пример блокировщика:
d_collapsed_burrows = {
icon = d_deep_sinkhole
time = 120
is_for_colonizeable = yes
category = deposit_cat_blockers
potential = { always = no } # added by event
planet_modifier = {
planet_max_districts_add = -1
}
on_cleared = {
create_pop = {
species = owner
}
}
resources = {
category = deposit_blockers
cost = {
energy = 300
}
}
}
Районы
common\districts\
Уже затронутые в предыдущих дневниках, районы по большей части заменяют квадраты. Они, как правило, возводятся игроками, и их количество ограничено планетарными особенностями. Районы создают должности.
Давайте взглянем на базовый добывающий район! Вы можете заметить, что общая структура схожа с вышеприведёнными примерами, и этот шаблон, действительно, будет повторяться для большинства баз данных, обновлённых в 2.2 «Ле Гуин». База данный района задаёт длительность постройки, условия строительства, заменители на других типах планет (например, на мирах машин), сколько и чего требуется для строительства и содержания, постоянные и активируемые модификаторы на планете, на которой район был построен (предоставление различных должностей различным типам империй), а также вес, определяющий приоритетность строительства этого района для ИИ.
Пример района:
district_mining = {
base_buildtime = 240
min_for_deposits_on_planet = 1
max_for_deposits_on_planet = 15
show_on_uncolonized = {
habitable_structure = no
NOR = {
is_planet_class = pc_machine
is_planet_class = pc_hive
is_planet_class = pc_city
}
}
potential = {
habitable_structure = no
NOT = {
is_planet_class = pc_machine
is_planet_class = pc_hive
is_planet_class = pc_city
}
}
allow = {
NOT = { has_modifier = resort_colony }
}
conversion_ratio = 1
convert_to = {
district_mining_uncapped
}
resources = {
category = planet_districts
cost = {
minerals = @base_cost
}
upkeep = {
energy = 1
}
}
planet_modifier = {
planet_housing_add = 2
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = {
has_valid_civic = civic_agrarian_idyll
}
}
modifier = {
planet_housing_add = 1
}
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = { is_hive_empire = yes }
}
modifier = {
job_mining_drone_add = 3
}
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = { is_machine_empire = yes }
}
modifier = {
job_mining_drone_add = 2
}
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = {
is_gestalt = no
is_fallen_empire_spiritualist = no
}
}
modifier = {
job_miner_add = 2
}
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = { is_fallen_empire_spiritualist = yes }
}
modifier = {
job_fe_acolyte_mine_add = 2
}
}
triggered_desc = {
trigger = {
exists = owner
owner = { is_gestalt = yes }
}
text = job_mining_drone_effect_desc
}
triggered_desc = {
trigger = {
exists = owner
owner = {
is_gestalt = no
is_fallen_empire_spiritualist = no
}
}
text = job_miner_effect_desc
}
triggered_desc = {
trigger = {
exists = owner
owner = { is_fallen_empire_spiritualist = yes }
}
text = job_fe_acolyte_mine_effect_desc
}
prerequisites = {
tech_mechanized_mining
}
ai_weight = {
weight = 1
modifier = {
factor = 3
owner = {
has_monthly_income = {
resource = minerals
value < 0
}
}
}
modifier = {
factor = 2
free_housing < 0
}
modifier = {
factor = 3
any_owned_pop = { is_unemployed = yes }
}
# No one to work it anyway
modifier = {
factor = 0
free_housing > 0
NOT = {
any_owned_pop = { is_unemployed = yes }
}
}
}
ai_resource_production = {
minerals = 1
trigger = {
always = yes
}
}
}
Сооружения
common\buildings\
Сооружения в целом похожи на то, к чему вы уже привыкли, однако, их функционал был существенно расширен, как вы могли видеть из вышеприведённых примеров. Благодаря «triggered_planet_modifier» сооружения, в зависимости от ряда факторов, могут влиять на события или эффекты. В приведённом ниже примере с building_foundry_2 одно и то же здание добавляет должности литейщика для обычных империй, должности alloy_drone для коллективного разума и должности фабрикатора для машинного интеллекта в зависимости от того, кто владеет этим зданием. Стоимость строительства, содержание и производство ресурса подпадают под категорию «resources = {}», хотя литейная всего-навсего добавляет должности и сама по себе не производит никаких ресурсов.
Пример сооружения:
building_foundry_2 = {
base_buildtime = 480
can_build = no
category = manufacturing
allow = {
has_upgraded_capital = yes
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = { is_hive_empire = yes }
}
modifier = {
job_alloy_drone_add = 5
}
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = { is_machine_empire = yes }
}
modifier = {
job_fabricator_add = 5
}
}
triggered_planet_modifier = {
potential = {
exists = owner
owner = { is_regular_empire = yes }
}
modifier = {
job_foundry_add = 5
}
}
resources = {
category = planet_buildings
cost = {
minerals = 600
volatile_motes = 50
}
upkeep = {
energy = 4
volatile_motes = 1
}
}
upgrades = {
building_foundry_3
}
prerequisites = {
tech_alloys_1
}
triggered_desc = {
trigger = {
exists = owner
owner = { is_regular_empire = yes }
}
text = job_foundry_effect_desc
}
triggered_desc = {
trigger = {
exists = owner
owner = { is_hive_empire = yes }
}
text = job_alloy_drone_effect_desc
}
triggered_desc = {
trigger = {
exists = owner
owner = { is_machine_empire = yes }
}
text = job_fabricator_effect_desc
}
ai_weight = {
weight = 1
modifier =
{
factor = 4
owner = {
has_monthly_income = {
resource = alloys
value < 15
}
}
}
}
ai_resource_production = {
alloys = 1
trigger = {
always = yes
}
}
}
Должности
common\pop_jobs\
Итак, что насчёт должностей, добавляемых сооружениями? Они заданы в отдельной базе данных должностей, в которой вы опять же увидите базовый синтаксис. Давайте же рассмотрим силовика: он производит 1 пункт единства, дополнительные очки единства, если вы являетесь полицейским государством, а при активном модификаторе «Кампания против преступности» он значительно снижает преступность, однако его содержание возрастает на 2 энергокредита.
Пример должности:
enforcer = {
category = specialist
condition_string = SPECIALIST_JOB_TRIGGER
building_icon = building_precinct_house
clothes_texture_index = 5
possible = {
specialist_job_check_trigger = yes
}
resources = {
category = planet_enforcers
produces = {
unity = 1
}
produces = {
trigger = {
owner = { has_valid_civic = civic_police_state }
}
unity = 1
}
upkeep = {
trigger = {
planet = { has_modifier = anticrime_campaign }
}
energy = 2
}
}
pop_modifier = {
pop_defense_armies_add = 2
}
planet_modifier = {
planet_crime_add = -25
}
triggered_planet_modifier = {
potential = {
owner = { has_non_swapped_tradition = tr_domination_judgment_corps }
}
modifier = {
planet_crime_add = -5
}
}
triggered_planet_modifier = {
potential = {
planet = { has_modifier = anticrime_campaign }
}
modifier = {
planet_crime_add = -10
}
}
weight = {
weight = @specialist_job_weight
modifier = {
factor = 0.2
has_citizenship_rights = no
NOT = { has_trait = trait_mechanical }
}
modifier = {
factor = 2
has_trait = trait_resilient
}
modifier = {
factor = 2
has_trait = trait_very_strong
}
modifier = {
factor = 1.5
has_trait = trait_strong
}
modifier = {
factor = 10
is_enslaved = yes
has_slavery_type = { type = slavery_military }
}
modifier = {
factor = 0.50
has_trait = trait_weak
}
modifier = {
factor = 0.1
can_take_servant_job = yes
}
modifier = {
factor = 1.5
has_job = enforcer
}
}
}
Социальная страта
common\pop_categories\
Страты, или социальные слои, например, специалисты, в число которых входят вышеупомянутые силовики, устроены схожим образом. У них есть распространяемые на весь слой потребление и производство ресурсов, модификаторы, а также настройки, описанные и активируемые текстовыми файлами баз данных. Страта simple_drone для гештальт-сознания, вероятно, является простейшим из примеров в игре:
Пример социальной страты:
simple_drone = {
rank = 0
clothes_texture_index = 2
# This is called whenever a Pop is created, moved to a different planet, or gets a new owner
assign_to_pop = {
exists = owner
owner = { is_gestalt = yes }
}
weight = {
weight = 1
}
pop_modifier = {
pop_housing_usage_base = 1
pop_amenities_usage_no_happiness_base = 1
}
# scope: pop to be resettled
allow_resettlement = {
always = yes
}
resettlement_cost = {
energy = 100
}
unemployment_resources = {
category = unemployment_resources
# Standby Mode Crime event
upkeep = {
trigger = {
planet = {
has_modifier = standby_mode
}
}
energy = 2
}
}
resources = {
category = pop_category_drones
upkeep = {
trigger = {
is_organic_species = yes
}
food = @living_standard_food_normal
}
upkeep = {
trigger = {
is_robotic_species = yes
}
energy = @living_standard_energy_normal
}
}
}
Ресурсы
common\strategic_resources\
Теперь ресурсы полностью описываются через скрипты, а не зашиты в код, так что вы легко сможете добавить что-нибудь своё к базовым игровым энергокредитам, минералам, сплавам и подобному. На этот раз строки в базе данных выглядят иначе; они задают возможность торговли ресурсом на рынке, последствия дефицита ресурса и весовые коэффициенты для ИИ. Стратегические ресурсы также задаются в этой базе данных.
Пример основного ресурса:
food = {
tradable = yes
market_amount = 100
market_price = 100
max = 10000
deficit_modifier = food_deficit #found in static modifiers
ai_weight = {
weight = 1
}
ai_wants = {
base = 300
}
}
Пример стратегического ресурса:
sr_dark_matter = {
tradable = yes
market_amount = 5
market_price = 100
max = 10000
prerequisites = { "tech_mine_dark_matter" }
visibility_prerequisite = { always = yes }
ai_weight = {
weight = 100
}
}
trigger_docs
И наконец, представляю вам полную trigger_docs документацию для версии 2.2 на момент написания дневника. Пожалуйста, учтите, что в ней содержится неоднозначная, а порой даже вводящая в заблуждение информация, и некоторые моменты могут измениться к релизу!
Размещение всей документации по триггерам и эффектам заняло бы слишком много места. Все желающие могут ознакомиться с ней в первоисточнике по ссылке в конце дневника.
Прямо сейчас мы усердно трудимся, добавляя последние штрихи к обновлению 2.2 и дополнению MegaCorp, но мы будем поглядывать за этой темой, хотя ответов на некоторые вопросы вам придётся подождать. На следующей неделе мы выпустим полные списки изменений патча 2.2!
Изменено: Traven, 22 Ноябрь 2018 - 19:47