Найти в Дзене
PlayGround.ru

Делаем мод своими руками или NWScript с jenkeee для Star Wars: Knights of the Old Republic

Введение: Я благодарю аудиторию KOTOR на Playground: если бы не их интерес к достаточно сложной теме, а именно к модификации ресурсов игры, этой статьи бы не было! На правах автора я позволю себе лирическое вступление. Я удивлён, что именно KOTOR стал той игрой, для которой мне захотелось выделить время и изучить фундаментальные разработки BioWare; эти инструкции стали частью этого мира! К сожалению, я сегодня наблюдаю очень тревожную картину, и я рад, что именно сага Джорджа Лукаса помогает мне сегодня подобрать слова, которые я буду писать ниже. О грустном я говорить не буду: я буду описывать, что КОТОР нам дал и почему я сегодня отдаю честь этому апостолату на кладбище. Среди разработчиков очень много ненависти к аура/одисей-движкам BioWare, и я понимаю, с чем это связано: я попробовал, и теперь мои слова не будут пустыми. Эти движки действительно тяжёлые в освоении, местами неудобные, капризные и беспощадные к ошибкам. Они не прощают поверхностного подхода, не ведут разработчика за

Введение:

Я благодарю аудиторию KOTOR на Playground: если бы не их интерес к достаточно сложной теме, а именно к модификации ресурсов игры, этой статьи бы не было!

На правах автора я позволю себе лирическое вступление.

Я удивлён, что именно KOTOR стал той игрой, для которой мне захотелось выделить время и изучить фундаментальные разработки BioWare; эти инструкции стали частью этого мира! К сожалению, я сегодня наблюдаю очень тревожную картину, и я рад, что именно сага Джорджа Лукаса помогает мне сегодня подобрать слова, которые я буду писать ниже. О грустном я говорить не буду: я буду описывать, что КОТОР нам дал и почему я сегодня отдаю честь этому апостолату на кладбище. Среди разработчиков очень много ненависти к аура/одисей-движкам BioWare, и я понимаю, с чем это связано: я попробовал, и теперь мои слова не будут пустыми. Эти движки действительно тяжёлые в освоении, местами неудобные, капризные и беспощадные к ошибкам. Они не прощают поверхностного подхода, не ведут разработчика за руку и постоянно требуют внимания к мелочам. Но именно в этой суровости и проявляется их сила: они заставляют разбираться в логике игры по-настоящему, а не просто нажимать кнопки в редакторе.

Именно КОТОР, как он есть, — прекрасная игра, которая прививает дисциплину с детства. Я помню первое прохождение, как я читерил, чтобы убить ранкора палкой; помню первое прохождение без читов, первые чувства, что ты победил скрипт (у меня потом это WoW'ом закончилось, но не важно). И самое главное: эта игра была беспощадна. Постоянные вылеты, краши, битые белые сейвы затрудняли прохождение и вынуждали постоянно делать бекап. Такой, казалось бы, банальный, привитый с детства навык в будущем ещё не раз вспомнят добрым словом джедаи, которые росли на КОТОР. В 2026 году я решил сразиться в этой игре с боссом, которого ещё не убивал, и эта статья посвящена знаниям, которые я получил в этой битве. Возможно, все эти буквы станут тем самым датападом с подсказкой; как минимум это станет ещё одним подтверждением алгоритма для CLI-систем.

Босса я сделал. Описывать весь техпроцесс мне, если честно, просто лень: этот путь джедай должен пройти самостоятельно, когда захочет поиграть в КОТОР следующего уровня.

Я расскажу о техпроцессе, который был затронут в ходе обсуждения комментария пользователя Wolfryu21. Это очень удобный частный случай, на котором я бы хотел описать, как КОТОР даёт по щам на этом уровне сложности.

Приступаем к работе

Наша цель – создать модификацию для КОТОР, которая будет менять компаньона в слоте 7 посредством диалогов в игре.

Скачиваем архив `KOTOR_HANDMADE.zip`. В архиве компилятор, инструкции и исходные файлы; в каталоге `05_release` также лежат готовые файлы для сравнения, чтобы было видно, что в итоге должно получиться.

В примере будем использовать путь `D:\KOTOR_HANDMADE`.

Вы можете расположить каталог по такому же пути для удобства дальнейшей работы.

Я уже поместил исходные файлы мода Sleheyron + RU by jenkeee в каталог `01_original`. Там лежат файлы из лайв-клиента, с ними мы и будем работать. Убедитесь, что файлы в вашем каталоге `Override` побайтно равны моим.

Если они отличаются, то инструкция, которую я пишу ниже, является лишь примером, а не точным руководством.

Каталог `01_original`, надо наполнить файлами вашего клиента. С этими данными будет связана вся дальнейшая работа. Для продолжения работы нам потребуется Python.

Важная предустановка.

скачай установщик `Python 3` для Windows

запусти установщик

на первом экране обязательно включи галочку `Add Python to PATH`

нажми `Install Now`

дождись конца установки

Главное место здесь – галочка `Add Python to PATH`.

Если её не включить, команды `python ...` в `cmd` могут не работать.

Подготовив инструменты, переходим к безудержному веселью.

Декомпиляция

Открой `cmd` и выполни:

cd /d D:\KOTOR_HANDMADE\tools\nwnnsscomp

Дальше:

nwnnsscomp.exe -d "D:\KOTOR_HANDMADE\01_original\t3_return.ncs" -o "D:\KOTOR_HANDMADE\02_decompiled\t3_return_decomp.nss"

Дальше:

nwnnsscomp.exe -d "D:\KOTOR_HANDMADE\01_original\recruit_vima.ncs" -o "D:\KOTOR_HANDMADE\02_decompiled\recruit_vima_decomp.nss"

Как итог, мы получим дизассемблированный байткод `.ncs` — то есть compiled NWScript из движка BioWare в доступном для чтения и редактирования `NSS`-формате. Пока полученный байткод не трогаем!

Чтение DLG

Дальше ещё веселее. Мы будем читать `DLG`-файлы. Мы будем использовать предустановленный Python для этого. Выполните команду:

python "D:\KOTOR_HANDMADE\tools\python\inspect_dlg_entries.py" "D:\KOTOR_HANDMADE\01_original\party_vima.dlg" 6 117 24

Так мы сможем увидеть, как построен диалог с Вимой и имеющиеся вхождения.

Командой ниже мы изучим диалог с Т3.

python "D:\KOTOR_HANDMADE\tools\python\inspect_dlg_entries.py" "D:\KOTOR_HANDMADE\01_original\k_htmd_dialog.dlg" 4

Следующим шагом мы соберём данные из `UTC`-файла Вимы и посмотрим конкретные нужные нам строки.

python "D:\KOTOR_HANDMADE\tools\python\kotor_inspect.py" gff "D:\KOTOR_HANDMADE\01_original\p_vimasunrider.utc" --field TemplateResRef --field Tag --field Conversation

Ты должен увидеть примерно это:

`TemplateResRef: p_vimasunrider`

`Tag: p_vimasunrider`

`Conversation: party_vima`

Теперь, изучив полученные данные, мы готовы к бою.

Создаём руками файлы в папке `03_scripts`.

Первый файл назовём:

vima_call_t3.nss

И наполняем его C-подобным содержимым:

void SpawnSlot7(location lSpot) {

SpawnAvailableNPC(7, lSpot);

}

void main() {

object oCurrent = OBJECT_SELF;

object oHost = GetFirstPC();

location lSpot = GetLocation(oCurrent);

object oTempT3 = GetObjectByTag("x_t3m4", 0);

object oRealT3 = GetObjectByTag("t3m4", 0);

RemoveAvailableNPC(7);

AddAvailableNPCByTemplate(7, "availnpc7_t3");

AssignCommand(oHost, SetGlobalFadeOut(0.0, 0.35, 0.0, 0.0, 0.0));

if (GetIsObjectValid(oTempT3)) {

AssignCommand(oHost, DelayCommand(0.40, DestroyObject(oTempT3)));

}

if (GetIsObjectValid(oRealT3)) {

AssignCommand(oHost, DelayCommand(0.40, DestroyObject(oRealT3)));

}

AssignCommand(oHost, DelayCommand(0.40, DestroyObject(oCurrent)));

AssignCommand(oHost, DelayCommand(0.45, SpawnSlot7(lSpot)));

AssignCommand(oHost, DelayCommand(0.80, SetGlobalFadeIn(0.0, 0.35, 0.0, 0.0, 0.0)));

}

================================================================================

Теперь создадим:

t3_call_vima.nss

И также наполним его, но уже другим содержимым.

================================================================================

void SpawnSlot7(location lSpot) {

SpawnAvailableNPC(7, lSpot);

}

void main() {

object oCurrent = OBJECT_SELF;

object oHost = GetFirstPC();

location lSpot = GetLocation(oCurrent);

object oTempT3 = GetObjectByTag("x_t3m4", 0);

object oRealT3 = GetObjectByTag("t3m4", 0);

object oVima = GetObjectByTag("p_vimasunrider", 0);

RemoveAvailableNPC(7);

AddAvailableNPCByTemplate(7, "p_vimasunrider");

AssignCommand(oHost, SetGlobalFadeOut(0.0, 0.35, 0.0, 0.0, 0.0));

if (GetIsObjectValid(oTempT3)) {

AssignCommand(oHost, DelayCommand(0.40, DestroyObject(oTempT3)));

}

if (GetIsObjectValid(oRealT3)) {

AssignCommand(oHost, DelayCommand(0.40, DestroyObject(oRealT3)));

}

if (GetIsObjectValid(oVima) && oVima != oCurrent) {

AssignCommand(oHost, DelayCommand(0.40, DestroyObject(oVima)));

}

AssignCommand(oHost, DelayCommand(0.40, DestroyObject(oCurrent)));

AssignCommand(oHost, DelayCommand(0.45, SpawnSlot7(lSpot)));

AssignCommand(oHost, DelayCommand(0.80, SetGlobalFadeIn(0.0, 0.35, 0.0, 0.0, 0.0)));

}

================================================================================

Модим диалоги

Дальнейший шаг достаточно объёмный и уже не очень про NWScript, а больше про Python. Я не стал его описывать. Просто выполните в cmd:

python "D:\KOTOR_HANDMADE\tools\python\student_build_vima_t3_patch.py" --source-dir "D:\KOTOR_HANDMADE\01_original" --output-dir "D:\KOTOR_HANDMADE\04_build"

Этой командой мы добавим новые строки в диалоги. Пересобранные файлы уже лежат в `04_build`. Можете посмотреть результат так:

вима

python "D:\KOTOR_HANDMADE\tools\python\inspect_dlg_entries.py" "D:\KOTOR_HANDMADE\04_build\party_vima.dlg" 6 117 24

теперь т3

python "D:\KOTOR_HANDMADE\tools\python\inspect_dlg_entries.py" "D:\KOTOR_HANDMADE\04_build\k_htmd_dialog.dlg" 4

Финал

И самый последний и ответственный шаг: нам осталось скомпилировать свои `NSS` в `NCS`.

Надо перейти в папку компилятора

cd /d D:\KOTOR_HANDMADE\tools\nwnnsscomp

Скомпилировать первый скрипт

nwnnsscomp.exe "D:\KOTOR_HANDMADE\03_scripts\vima_call_t3.nss" -o "D:\KOTOR_HANDMADE\04_build\vima_call_t3.ncs"

Скомпилировать второй скрипт

nwnnsscomp.exe "D:\KOTOR_HANDMADE\03_scripts\t3_call_vima.nss" -o "D:\KOTOR_HANDMADE\04_build\t3_call_vima.ncs"

Теперь у нас почти всё готово для рабочего патча Т3/Вима. Нам осталось подготовить файл `availnpc7_t3.utc`; о том, как его подготовить, кому интересно, почитайте в `README` в этом каталоге `04_build`.

Если вы выполнили это руководство у вас уже есть готовые файлы в каталоге `04_build`.

фаил availnpc7_t3.utc я уже подготовил и положил в 04_build

gz gl hf

Получившиеся 5 файлов — это наш готовый патч. Переносим эти файлы в каталог `Override`, проверяем результат в игре.

P.S. Лирическое отступление.

Эта публикация является финальной в моей трилогии постов, посвящённых КОТОР; следующие публикации будут не скоро, если вообще суждено им появиться. Эти публикации — побочный продукт моих экспериментов над ресурсами игры. Эти публикации и темы не случайны: я специально выбрал два очень разных по структуре мода, для того чтобы посмотреть, как изменилась техника джедаев за 20 лет. Первая публикация, посвящённая моду Слехерон, — это прекрасный показатель того, как к КОТОР сегодня подходят модерн-программисты. Тут есть дисциплина в организации файлов, и это, в принципе, выглядит как масштабируемый проект. Мод Явин — он совершенно другой: это легаси из тех самых лет, когда не было нормального компилятора и Python не был таким, чтобы применять его так же легко, как в руководстве выше. Мод Явин впечатлил меня очень сильно; тот отпечаток, который оставили разработчики этого мода, показал мне изящные способы, которые имеют право на жизнь в крайне сложных ситуациях. Я надеюсь, следующие джедаи, которые придут в КОТОР, смогут сделать то, что не смогли мои предшественники, но я ещё не закончил. Моя реставрация Явина требует доработки, и этот мод я доделаю, чтобы оставить свой след в истории проекта, который создал из меня достаточно сильного джедая, который принимает вызовы и способен их решать!

олсо ~ Приглашаю всех на форум. Wolfryu21 оказывается делает сборку всех модов, как я уже говорил я удивлен тем, что над котором все еще кто-то работает. А удивляет меня в этой жизни только хорошее. Так что сабж достойный обсуждения готов - Нужен ли КОТОР 1 адекватный мод менеджер, и кто готов принять участие в подобном проекте?. чтобы решить максимально приемлемо, нужно мнение разных джедаев. Только ситхи все возводят в абсолют! а сегодняшние ситхи стадо овец, ситхов должно быть только двое, это вечная борьба за абсолютное доминирование, путем неприкрытого покорения. Ситхов тоже приглашаю, возмущение силы сегодня запредельно. в последнее время, чаще всего я вижу перед собой не джедаев и не ситхов, а лишь сгустки комплексов.