Не секрет, что большинство фанатов серии Mount & Blade не просто знают о существовании модификаций для этих игр, но и активно их используют. В рамках Bannerlord уже давно стандартом и одновременно джентльменским набором стала связка Harmony, UIExtenderEx и ButterLib, расширяющие стандартные возможности движка. Однако, далеко не каждый знает, что на самом деле действие Harmony простирается за пределы Mount & Blade, а кто-то, возможно, встречал её упоминание и в других проектах. Что же, сегодня, настало время рассказать о самом незаметном моде, который тихим сапом оказал своё влияние на игровую индустрию.
Данную библиотеку создал программист Andreas Pardeike, известный в некоторых сообществах под ником Brrainz. Изначально Harmony разрабатывалась специально под RimWorld - игру с крайне активным и не менее требовательным моддерским сообществом. Причина появления Harmony проста: в ранних версиях игры моддеры часто сталкивались с довольно тривиальной проблемой: если два мода хотели изменить один и тот же метод или параметр игры, они либо перезаписывали друг друга, либо создавали конфликты и приводили к багам. Требовалось удобное, безопасное и совместимое решение. Им стал так называемый runtime-патчинг, то есть изменение кода непосредственно в оперативной памяти без правки оригинальных файлов. Так родилась и родилась Harmony - элегантная библиотека, которая позволяла добавлять код до (Prefix) и после (Postfix) стандартного метода или полностью заменять его. Позже добавили ещё один инструмент - Transpiler, для редактирования IL-кода на лету.
Понятное дело, что названия этих методов вряд ли хоть что-то говорят, поэтому приведу пример. Представим условный игровой параметр TakeDamage. Он у нас будет отвечать за то, как персонаж получает урон. На этот параметр пытаются воздействовать сразу два мода: мод A хочет, чтобы броня сильно снижала входящий урон, а мод Б добавляет глубокую систему ранений: если урон проходит сквозь броню, пешка получает кровотечение, переломы и штрафы к скорости. Что должно получиться при установке обоих модов без Harmony? Всё банально: у тебя либо не снижается урон от брони, либо не добавляются сложные повреждения - в зависимости от порядка загрузки. Лишь если оба автора договаривались и объединяли свой код, игроки получали и то, и другое. В общем, мягко говоря, это было неудобно.
Но благодаря Postfix методу Harmony, теперь изменения каждого мода вносятся по очереди прямо в оперативной памяти: сначала исполняется оригинальная функция, затем на неё накладывается один патч, а после и другой. В итоге работают оба мода. Более интересными являются два других метода. Возьмём Prefix: представьте, что в игре есть поле с ловушками, которое надо пройти наугад. Но мы хотим сделать особый читерский мод, который должен показывать персонажам где эти ловушки установлены. В этом случае нам не нужен расчёт оригинальной логики - нам, наоборот, надо, чтобы мод вмешался до неё. В итоге исходное действие ловушек отключается, хотя оригинальный расчёт из файлов игры никуда не делся - он просто перестал исполняться. Но самым интересным является Transpiler: этот "товарищ" позволяет не просто что-то изменить до или после - он меняет начинку самого метода, вычленяя отдельные её формулы. Опять же пример: у нас есть ящик гранат и нам нужно рассчитать какой урон будет нанесён при его взрыве. Prefix позволяет нам изменить количество гранат в ящике или вообще отменить взрыв, postfix - отредактировать фактическую цифру урона или добавить к нему какой-нибудь эффект, а transpiler - это тот случай, когда надо аккуратно поправить формулу, например, изменить модификатор накопительного эффекта от взрыва или порядок детонации. Кстати, если кому интересно, Brrainz отнюдь не мимо проходил, когда всё это придумывал. Он является автором таких довольно известных модов, как Camera+, Visual Exceptions, MOD-E, так что его интерес был вполне личным.
Теперь давайте вернёмся к истории Harmony. Первая публичная версия (1.x) появилась примерно в 2017 году на официальном форуме Ludeon (разработчиков RimWorld). На этот момент это был простой DLL файл, который нужно было включить в дистрибутив мода самостоятельно. Но даже в таком виде Harmony быстро стала стандартом в моддинга. Её хвалили за удобство, стабильность и то, что она позволяла множеству модов мирно сосуществовать вместе. В 2020 году, вместе с выходом RimWorld 1.1, Андреас выпустил релиз Harmony 2, в котором он серьёзно доработал функционал проекта - добавил новые возможности, произвёл исправление багов, ввёл более проработанный стандарт. Кроме того, с выходом новой версии RimWorld, в игре изменилась система загрузки модов, поэтому Harmony перестала включаться в каждый мод отдельно. Вместо этого появился отдельный Harmony-мод, который с этого момента загружается первым и предоставляет общую версию библиотеки всем остальным модам. Это решило проблему дублирования и конфликтов версий.
Но самое интересное другое: библиотека вышла далеко за пределы RimWorld и используется в десятках игр: Cities: Skylines, Stardew Valley, Subnautica, 7 Days to Die, Oxygen Not Included, многих основанных на Unity-проектах и, конечно же, Mount & Blade II: Bannerlord. Фишка в том, что Harmony способен работать почти с любым C#, .NET или Mono-приложением. Это, опять же, магия программирования. Дело в том, что когда какой-то автор пишет код своего проекта на C#, компилятор превращает его не сразу в машинный код для компьютера, а в специальный промежуточный код — CIL (или просто IL — Intermediate Language). CIL можно назвать «универсальным черновиком», который понимают разные среды выполнения, в том числе .NET Framework и Mono (открытая мультиплатформенная версия .NET). А так как игры на Unity зачастую используют Mono, потенциально возможности Harmony покрывают их всех. Bannerlord в свою очередь имеет довольно интересную структуру: ядро игры (графика, физика, рендеринг, большой мир, запуск сражений и т.д.) - это нативный код на C++, работающий в рамках собственного движка TaleWorlds, однако логика игры, поведение ИИ, различные механики, квесты, интерфейс и многое другое, куда моддеры обычно хотят засунуть свои руки, написано на C# и работает поверх .NET. Именно поэтому важнейшая часть большинства модов - это .dll файлы и именно поэтому с ними так легко работать через Harmony.
Первым, кто адаптировал и начал распространять Harmony для Mount & Blade II: Bannerlord, был моддер Aragas. В августе 2020-ого года он загрузил на на Nexusmods свой проект под названием «Harmony at Mount & Blade II», которая по сути являлась ответвлением от оригинальной библиотеки Harmony. Этот проект является ключевым элементом наравне с ButterLib. Что интересно, хотя сам ButterLib зависит от Harmony как более высокоуровневого элемента, он несёт совсем другие задачи по доработке функционала Bannerlord и заслуживает отдельного разговора. Что интересно, мододелы M&B могут применять тот же трюк, что их коллеги из Rimworld: прикладывать отдельный файл 0harmony.dll к самому моду для того, чтобы он обрабатывался "из коробки". И, кстати говоря, ситуация с Bannerlord не единичный случай: свою долю популярности получил форк HarmonyX от команды BepInEx. Он оптимизирован под определённые загрузчики, вроде того же BepInEx, и лучше интегрируется с MonoMod. По сути, это инструмент "всё в одном", который сразу определяет порядок загрузки модов и оперирует их работой. Таким образом, важным элементом работы модификаций в таких известных играх, как Valheim и Lethal Company, является всё тот же Harmony.
Ну а Андреас... что же, он до сих пор поддерживает свой проект через GitHub. Пускай он не стал легендой, но, думаю, его могли бы поблагодарить многие фанаты игр. Мало того, эта библиотека уже нашла применение вне геймдева, например, в unit-тестировании у Microsoft и Google. Это решение применяют, когда нужно изменить поведение чужой библиотеки или фреймворка «на лету» или, например, добавить логирование без прямого редактирования файлов. Harmony помогает тестировать сложный код - с его помощью можно заставить какой-то метод возвращать тестовые данные, измерить, сколько раз он вызывался, или перехватить сложные зависимости.
Данную библиотеку создал программист Andreas Pardeike, известный в некоторых сообществах под ником Brrainz. Изначально Harmony разрабатывалась специально под RimWorld - игру с крайне активным и не менее требовательным моддерским сообществом. Причина появления Harmony проста: в ранних версиях игры моддеры часто сталкивались с довольно тривиальной проблемой: если два мода хотели изменить один и тот же метод или параметр игры, они либо перезаписывали друг друга, либо создавали конфликты и приводили к багам. Требовалось удобное, безопасное и совместимое решение. Им стал так называемый runtime-патчинг, то есть изменение кода непосредственно в оперативной памяти без правки оригинальных файлов. Так родилась и родилась Harmony - элегантная библиотека, которая позволяла добавлять код до (Prefix) и после (Postfix) стандартного метода или полностью заменять его. Позже добавили ещё один инструмент - Transpiler, для редактирования IL-кода на лету.
Понятное дело, что названия этих методов вряд ли хоть что-то говорят, поэтому приведу пример. Представим условный игровой параметр TakeDamage. Он у нас будет отвечать за то, как персонаж получает урон. На этот параметр пытаются воздействовать сразу два мода: мод A хочет, чтобы броня сильно снижала входящий урон, а мод Б добавляет глубокую систему ранений: если урон проходит сквозь броню, пешка получает кровотечение, переломы и штрафы к скорости. Что должно получиться при установке обоих модов без Harmony? Всё банально: у тебя либо не снижается урон от брони, либо не добавляются сложные повреждения - в зависимости от порядка загрузки. Лишь если оба автора договаривались и объединяли свой код, игроки получали и то, и другое. В общем, мягко говоря, это было неудобно.
Но благодаря Postfix методу Harmony, теперь изменения каждого мода вносятся по очереди прямо в оперативной памяти: сначала исполняется оригинальная функция, затем на неё накладывается один патч, а после и другой. В итоге работают оба мода. Более интересными являются два других метода. Возьмём Prefix: представьте, что в игре есть поле с ловушками, которое надо пройти наугад. Но мы хотим сделать особый читерский мод, который должен показывать персонажам где эти ловушки установлены. В этом случае нам не нужен расчёт оригинальной логики - нам, наоборот, надо, чтобы мод вмешался до неё. В итоге исходное действие ловушек отключается, хотя оригинальный расчёт из файлов игры никуда не делся - он просто перестал исполняться. Но самым интересным является Transpiler: этот "товарищ" позволяет не просто что-то изменить до или после - он меняет начинку самого метода, вычленяя отдельные её формулы. Опять же пример: у нас есть ящик гранат и нам нужно рассчитать какой урон будет нанесён при его взрыве. Prefix позволяет нам изменить количество гранат в ящике или вообще отменить взрыв, postfix - отредактировать фактическую цифру урона или добавить к нему какой-нибудь эффект, а transpiler - это тот случай, когда надо аккуратно поправить формулу, например, изменить модификатор накопительного эффекта от взрыва или порядок детонации. Кстати, если кому интересно, Brrainz отнюдь не мимо проходил, когда всё это придумывал. Он является автором таких довольно известных модов, как Camera+, Visual Exceptions, MOD-E, так что его интерес был вполне личным.
Теперь давайте вернёмся к истории Harmony. Первая публичная версия (1.x) появилась примерно в 2017 году на официальном форуме Ludeon (разработчиков RimWorld). На этот момент это был простой DLL файл, который нужно было включить в дистрибутив мода самостоятельно. Но даже в таком виде Harmony быстро стала стандартом в моддинга. Её хвалили за удобство, стабильность и то, что она позволяла множеству модов мирно сосуществовать вместе. В 2020 году, вместе с выходом RimWorld 1.1, Андреас выпустил релиз Harmony 2, в котором он серьёзно доработал функционал проекта - добавил новые возможности, произвёл исправление багов, ввёл более проработанный стандарт. Кроме того, с выходом новой версии RimWorld, в игре изменилась система загрузки модов, поэтому Harmony перестала включаться в каждый мод отдельно. Вместо этого появился отдельный Harmony-мод, который с этого момента загружается первым и предоставляет общую версию библиотеки всем остальным модам. Это решило проблему дублирования и конфликтов версий.
Но самое интересное другое: библиотека вышла далеко за пределы RimWorld и используется в десятках игр: Cities: Skylines, Stardew Valley, Subnautica, 7 Days to Die, Oxygen Not Included, многих основанных на Unity-проектах и, конечно же, Mount & Blade II: Bannerlord. Фишка в том, что Harmony способен работать почти с любым C#, .NET или Mono-приложением. Это, опять же, магия программирования. Дело в том, что когда какой-то автор пишет код своего проекта на C#, компилятор превращает его не сразу в машинный код для компьютера, а в специальный промежуточный код — CIL (или просто IL — Intermediate Language). CIL можно назвать «универсальным черновиком», который понимают разные среды выполнения, в том числе .NET Framework и Mono (открытая мультиплатформенная версия .NET). А так как игры на Unity зачастую используют Mono, потенциально возможности Harmony покрывают их всех. Bannerlord в свою очередь имеет довольно интересную структуру: ядро игры (графика, физика, рендеринг, большой мир, запуск сражений и т.д.) - это нативный код на C++, работающий в рамках собственного движка TaleWorlds, однако логика игры, поведение ИИ, различные механики, квесты, интерфейс и многое другое, куда моддеры обычно хотят засунуть свои руки, написано на C# и работает поверх .NET. Именно поэтому важнейшая часть большинства модов - это .dll файлы и именно поэтому с ними так легко работать через Harmony.
Первым, кто адаптировал и начал распространять Harmony для Mount & Blade II: Bannerlord, был моддер Aragas. В августе 2020-ого года он загрузил на на Nexusmods свой проект под названием «Harmony at Mount & Blade II», которая по сути являлась ответвлением от оригинальной библиотеки Harmony. Этот проект является ключевым элементом наравне с ButterLib. Что интересно, хотя сам ButterLib зависит от Harmony как более высокоуровневого элемента, он несёт совсем другие задачи по доработке функционала Bannerlord и заслуживает отдельного разговора. Что интересно, мододелы M&B могут применять тот же трюк, что их коллеги из Rimworld: прикладывать отдельный файл 0harmony.dll к самому моду для того, чтобы он обрабатывался "из коробки". И, кстати говоря, ситуация с Bannerlord не единичный случай: свою долю популярности получил форк HarmonyX от команды BepInEx. Он оптимизирован под определённые загрузчики, вроде того же BepInEx, и лучше интегрируется с MonoMod. По сути, это инструмент "всё в одном", который сразу определяет порядок загрузки модов и оперирует их работой. Таким образом, важным элементом работы модификаций в таких известных играх, как Valheim и Lethal Company, является всё тот же Harmony.
Ну а Андреас... что же, он до сих пор поддерживает свой проект через GitHub. Пускай он не стал легендой, но, думаю, его могли бы поблагодарить многие фанаты игр. Мало того, эта библиотека уже нашла применение вне геймдева, например, в unit-тестировании у Microsoft и Google. Это решение применяют, когда нужно изменить поведение чужой библиотеки или фреймворка «на лету» или, например, добавить логирование без прямого редактирования файлов. Harmony помогает тестировать сложный код - с его помощью можно заставить какой-то метод возвращать тестовые данные, измерить, сколько раз он вызывался, или перехватить сложные зависимости.





Всего: 30241