Раздел:
Раздел 1
Моды в игре имеют достаточно гибкую систему перевода, что позволяет переводить моды на любые языки без знания программирования или каких-либо других навыков.
Я рекомендую для этих дел использовать «Notepad++», это мощный бесплатный текстовый редактор.

Структура папок
Все файлы перевода находятся в папке «Language» в папке с модом.
Если такой папки нет, вы можете её создать сами.
Внутри может находится разное количество папок-языков, каждый из которых соответствует языку в игре. Правильное написание папки с нужным языком можно посмотреть в «Core» оригинальной игры: «<Папка_с_игрой>/Mods/Core/Languages»
Каждая папка может содержать разное количество вложенных папок, все зависит от того, что вы переводите. Полный набор папок:
  1. Backstories - перевод историй пешек;
  2. DefInjected — самая часто используемая папка, используется для перевода Def-ов;
  3. Keyed — еще одна часто используемая папка, используется для перевода по ключам (в основном, если вы делаете какие-либо надписи, предметы, тексты непосредственно в коде игры, не относящиеся к def-ам);
  4. RimWorldUniverse — история игры;
  5. Strings — множество разных строк из игры: имена пешек, животных, миров и т.д;
  6. WorldInfo - информация о мире: имя сида, мира;
LangIcon — картинка языка в игре;
LanguageInfo - информация о языке;
Самые часто используемые это DefInjected и Keyed.
Перевод DefInjected
DefInjected перевод осуществляется (как и Keyed) по схеме «Ключ — значение".
Ключ — уникальный идентификатор, по которому игра найдет нужные деф-ы и строки у них. Любой def по стандарту имеет один ключ — «defName», т.к в рамках def-а он уникален (например, среди болезней, предметов, пешек и т.д).
Поэтому, перевод базовых значений (без вложенности) выглядит так:
<defName.поле_для_перевода>перевод</defName.поле_для_перевода>
Папка DefInjected так-же имеет одну особенность: поиск предметов для перевода осуществляется в папках, соответствующих названию коренного Def-a
Например, если вы переводите предмет «ThingDef», то вы должны создать папку «ThingDef» в папке «DefInjected» и поместить туда файл с переводом, при этом внутрення вложенность папок может быть любая, как и название файлов.
Разберем простой пример. Найдем «RimWorld\Mods\Core\Defs\ThingDefs_Items\Items_Resource_Stuff.xml» и предмет «Silver»— это пример простого предмета, у которого требуется перевести имя и описание. В основном вы будете встречаться именно с такими, у которых нужно будет перевести описание, описание эффекта, имя, какую-то надпись. Важно отметить, что тут нет вложенности. Т.е все находится в рамках одного уровня.
Уровни вложенности в том же «Notepad++» видны сразу:
<параметр>
<влорженный_параметр2>
<вложенный_параметр3>
</параметр>
Приступим к переводу.
Стоит отметить, что место нахождение перевода не важно. Единственно, если перевод находится в другом моде (например есть «мод А», а вы перевод вынесли в «мод Б»), то «мод Б» (мод с переводом) должен быть ниже в списке загрузки.
Переходим в папку «Languages» (или создаем её), переходим в папку «Russian» (или создаем её, но тогда LanguageIcon и LanguageInfo копируем из «RimWorld/Core/Languages/Russian»), затем переходим в папку DefInjected (или создаем её).
Мы переводим предмет def-a «ThingDef» (коренное имя XML Node)
Поэтому нам нужна папка ThingDef, если её нет, то создайте.
Внутри папки вы можете использовать существующие XML или создать свою. Так вы можете разделять предметы на файлы (например, файл для оружия, файл для одежды и т.д), либо делать все в одном. Разницы в производительности/скорости загрузки игры — не будет.
Если вы создали свою папку, то разумеется файлов там не будет. Пример файла можно взять из других папок папки «DefInjected» этого же мода или из ванили («RimWorld/Core/Languages/Russian/DefInjected»).
Я взял за основу файл «WakeUp.xml» из «RimWorld/Core/Languages/Russian/DefInjected/ThingDef» и просто скопировал его и поменял имя.
Откроем его, очистим, оставив только Xml заголовки.
Т.к перевод осуществляется по схеме <defName.поле_для_перевода>перевод</defName.поле_для_перевода>, то берем defName нашего предмета
и выбираем поле, которое будет переводить. Начнем с label.
Для этого, берем defName, ставим точку и пишем имя поле (из <>).
Результат:
Здесь видно нашу схему: сначала идет <defName>, затем точка и поле, которое требуется перевести. Аналогично переводим description
Это — пример самого простого перевода, но иногда бывает, что некоторые надписи могут находится во вложенных уровнях, а некоторые и вовсе в списках.
Здесь на помощь к нам приходит атрибут «TranslationHandle» и «MustTranslate», который указывает, что будет является ключом и что должно быть переведено. На первом уровне мы с вами разобрались — это defName, а дальше все зависит от конкретного случая.
Разберем другой пример. Возьмем пиво.
Как видно, у него есть 2 строки, которые находится в параметре <ingestible>
Здесь для перевода воспользуемся тем же приемом: возьмем defName, но затем, вместо сразу строки, которую нужно перевести, сначала укажем имя корневого параметра и только затем поле, которое хотим перевести.
В итоге получаем такое:
label и description уже разобрали: <defName.поле>, а вот дальше мы сначала указали имя корневого параметра (ingestible) и только затем строку, которую хотим перевести.
Практически аналогично мы можем перевести списки. Возьмем параметр tools у того-же пива.
Как видно, он идет списком (<li>), здесь, практически всегда (по крайней мере в ванильных def-ах), ключом является <label>, тогда перевод будет выглядеть так:
<defName.параметр.<label>.label>перевод</defName.параметр.<label>.label>
Снова defName, затем какое-то количество вложенных параметров, затем ключ, затем поле, которое хотим перевести.
Результат:
Beer — defName, tools — поле, где находится наш список, bottle/neck — <label>(ключи), а затем label уже поле.
Понять ,что являтся ключом в том или ином def-e достаточно легко: просто посмотрите перевод другим предметов.
Так-же есть несколько интересных особенностей:
  1. В самом label могут быть пробелы: <label>my neck</label> и т.д. В таком случае, при переводе пробелы заменяются на _, например:
Тогда перевод будет такой:
Как видно, пробел мы заменили на _.
  1. Элементы с одинаковым ключом можно перевести использую цифры как указатель позиции. Например, у нас есть такое:
Подобное встречается очень часто в «HediffDef». Как видно, оба элемента имеют ключ bottle. Чтобы перевести такое, используем цифры, указывая номер элемента из списка (помним, массивы начинаются с 0).
Чтобы перевести первый «bottle» используем -0, а чтобы второй -1.

Дополнительно

Пару слов о параметрах: довольно часто встречаются в строках различные {0}, {1}, {2} или {PAWN_NAME} и т.д. — это динамичные параметры, которые подставляются непосредственно во время игры. Их нельзя удалять (в противном случае перевод будет кривой).
Так-же их нельзя перемешивать - это попросту не будет работать. Если в самом коде первым параметров идет имя, то на место {0} всегда будет имя, куда бы вы его не поставили.
Перевод Keyed
Keyed — это те-же «ключ - значение», только используется в основном для перевода того, что не относится к def-ам, тоесть в основном какие-то кастомные надписи, тексты и т.д.
Перевод ключей осуществляется в папке «Keyed», вы так-же можете создать её, если её нет. Внутри папки не требуется никаких обязательных иерархий, вы можете создавать любые папки, любые файлы.
Если в моде есть такие файлы, то самым лучшим способом будет скопировать их из папки основного языка, т.к ключи нелзя записать в самих дефах.
В отличии def-ов — здесь никогда нет вложенностей. Всегда одна пара: «ключ — значение».
Как видно, все так-же в <> записывается ключ, а в самом теге — значение.
Особо говорить здесь нечего, т.к если такое есть — то как я уже сказал, лучшим способом будет просто скопировать их из основного перевода и вставить в папку с нужным переводом, после чего перевести.

Дополнительно

Дополнительно я хочу показать, как создавать свои ключи.
Чтобы подставить значение по ключу, достаточно написать ключ, после чего добавить .Translate();
После чего, во время, например, вывода информации будет подставлено значения ключа «MySupaKey» текущего языка.
Например, вывести значения в log:
Вы так-же можете подставлять значения {0}, {1}, аналогично дефа-ам.
Для этого укажите параметры типа «string» или другого типа, который может быть неявно преобразован в тип «string» в скобках.
Например, вы хотите подставить какую-то цифру:
Тогда ключ будет выглядеть так:
Разумеется, если параметров будет несколько, то будет {1}, {2} и т.д.
Советы
— Старайтесь при создании своего ода ориентироваться на базовый язык — английский. Пишите на нем в самих def-ах, тогда вам ненужно будет создавать перевод для «English», а так-же это повысит популярность мода и удобство в дальнейшем;
— При создании ключей в Keyed старайтесь давать им говорящие имена. Согласитесь, ключ «LabelWhenYouDie» сразу говорит, что это надпись, когда ты умираешь, чем «KillString» или что-то подобное;
— Делайте ключи на английском;
— Не делайте ключи очень большими;
— По возможности, разбивайте перевод на подфайлы. Выделяйте файл для построек, для оружия, брони, но не увлекайтесь. Делать файл перевода для каждого предмета — не лучшая идея.
— Используйте комментарии в XML: они ставятся так:
<!— Тут оружие —!>
`
ОЖИДАНИЕ РЕКЛАМЫ...