Слияние
merge / replace
Теперь у GP-Next есть два файловых режима для обычных JSON-патчей:
mergereplace
Если запомнить только одну фразу:
merge: пишите только те части, которые хотите изменитьreplace: вы берете под контроль весь JSON этого типа
Эта страница целиком посвящена различию между этими двумя режимами, их настройке и выбору подходящего варианта.
Поведение по умолчанию
По умолчанию GP-Next обрабатывает обычные JSON-патчи так:
features/objects:mergelevels: фактически полная замена файлаlang: по-прежнему глубоко сливается вMultiLanguage.lyricsworldmap: использует собственную runtime-систему GP-Next, а не правила с этой страницы
Поэтому здесь мы в основном говорим о:
jsons/features/*.jsonjsons/objects/*.json
Что означает merge
merge — это исходный и стандартный подход GP-Next.
Его цель:
- сохранить как можно больше исходного JSON игры
- переопределять только те поля, которые вы явно указали
- делать патчи короче и лучше совместимыми с будущими обновлениями игры
Например, если вы хотите изменить только характеристики одного растения, обычно лучше сначала выбрать merge.
{
"objects": [
{
"aliases": ["peashooter"],
"objclass": "PlantProperties",
"objdata": {
"SunCost": 50,
"Cooldown": 2
}
}
]
}Этот патч не заменяет весь PlantProps. Он меняет только два поля у peashooter.
Что означает replace
replace означает:
- GP-Next перестает применять обычные правила слияния к этому типу
- ваш файл патча напрямую заменяет весь исходный JSON этого типа
Это полезно, когда:
- вы хотите полностью переделать содержимое магазина
- вы хотите явно удалить большой объем ванильных данных
- вы не хотите, чтобы от исходного содержимого этого типа что-то оставалось
То есть replace — это не просто "более сильное переопределение". Это означает: "теперь весь этот тип контролируется моим файлом".
Как это настроить
Файл конфигурации находится здесь:
jsons/config/patching.jsonМинимальный пример:
{
"defaultMode": "merge",
"features": {
"StoreCommodityFeatures": { "mode": "replace" }
},
"objects": {
"PlantProps": { "mode": "replace" }
}
}Это означает:
- типы, которых нет в списке, продолжают использовать
merge StoreCommodityFeaturesцеликом работает в режимеreplacePlantPropsцеликом работает в режимеreplace
Текущая область действия
Сейчас эта конфигурация влияет только на:
featuresobjects
То есть такие файлы, как:
features/PlantFeatures.jsonfeatures/StoreCommodityFeatures.jsonobjects/PlantProps.jsonobjects/ZombieProps.json
можно переключать между merge и replace через patching.json.
А вот эти категории сюда не входят:
levelslangworldmap
Правила конфигурации
Текущие правила простые:
- имена типов записываются внутри
featuresиobjects - типы, которых нет в списке, используют
defaultMode - если
defaultModeне указан, используетсяmerge - пока поддерживаются только
mergeиreplace
Например:
{
"features": {
"StoreCommodityFeatures": { "mode": "replace" }
}
}Это переключает в replace только StoreCommodityFeatures. Все остальное остается в стандартном режиме.
Что GP-Next делает в merge
Features
Файлы Features не сливаются по индексам массива. Они сопоставляются по идентифицирующим полям.
Типичные случаи:
- большинство файлов Features:
CODENAME MintObtainRoute:FamilyStoreCommodityFeatures.Plants / Upgrade:CommodityName
Objects
Файлы Objects обычно ищут записи внутри массива objects по:
aliases[0]
Поэтому, если вы редактируете растение или зомби, обычно указывается его первый alias.
С массивами нужна осторожность
Даже в режиме merge массивы не сливаются поэлементно по индексам.
В GP-Next массивы по-прежнему по умолчанию заменяются целиком.
Это обычно касается таких вещей, как:
- наборы зомби
PLANTSSEEDCHOOSERDEFAULTORDER- некоторые полные списки магазина
Поэтому merge не означает "все автоматически умно допишется". Это в первую очередь означает, что объектные поля сливаются по правилам, а массивы все равно в основном заменяются.
Особый случай StoreCommodityFeatures
StoreCommodityFeatures — это не один массив, а несколько параллельных секций:
PlantsUpgradeGemCoinZen
В обычном merge:
Plants/Upgrade: сливаются поCommodityNameGem/Coin/Zen: обычно заменяются как целые массивы
Если ваша цель — "весь магазин теперь должен работать только по моей версии", replace обычно оказывается понятнее, чем продолжать смешивать свои данные с ванильными.
Когда выбирать merge
merge обычно лучше, когда:
- вы меняете только несколько характеристик растений или зомби
- вы редактируете небольшое число описаний или текстов альманаха
- вы хотите поправить только несколько цен в магазине
- вы хотите лучше сохранить совместимость с будущими обновлениями игры и новыми полями
Коротко:
Если достаточно локального изменения, выбирайте merge.
Когда выбирать replace
replace обычно лучше, когда:
- вы хотите полностью переделать один тип
- вы хотите явно убрать большой объем ванильного содержимого
- вы не хотите, чтобы исходный JSON этого типа продолжал участвовать в результате
- вы готовы самостоятельно поддерживать весь файл этого типа
Коротко:
Используйте replace, когда хотите взять под контроль весь тип.
Быстрый тест для выбора
Спросите себя:
- Я меняю только небольшое число полей?
- Я хочу, чтобы будущие ванильные поля по возможности сохранялись?
- Я хочу избежать поддержки целого файла типа?
Если на большинство вопросов ответ "да", выбирайте merge.
С другой стороны:
- Я готов сам поддерживать полный файл этого типа?
- Я хочу, чтобы старое ванильное содержимое больше не подмешивалось?
- Я осознанно переделываю весь этот тип целиком?
Если на большинство вопросов ответ "да", выбирайте replace.
Рекомендуемый рабочий процесс
- Сначала посмотрите реальную структуру на странице Data
- Начните с самого маленького возможного патча в режиме
merge - Переходите на
replaceтолько если реальная задача — "взять под контроль весь тип" - Перезагрузите и снова проверьте результат на странице Data
