Мутаторы и UnrealScript

Компиляция пакетов Killing Floor через ucc make

ucc make — компилятор UnrealScript, который поставляется с играми на Unreal Engine 2. В Killing Floor 1 он лежит в папке System рядом с KillingFloor.exe. Это руководство адаптирует классическую страницу Unreal Wiki «Compiling With UCC» под файлы KF.

Структура папок

UCC ищет исходники в папке с именем пакета в корне игры, в подпапке Classes:

KillingFloor/
├── System/
│   ├── ucc.exe
│   ├── KillingFloor.ini
│   └── MyMutator.u        <- результат компиляции
└── MyMutator/
    └── Classes/
        ├── MyMutator.uc
        └── MyHelper.uc

Имя пакета — это имя папки, а каждый файл класса должен называться так же, как объявленный в нём класс.

Регистрация пакета

Откройте System/KillingFloor.ini, найдите строки EditPackages= в секции [Editor.EditorEngine] и добавьте свой пакет в конец:

EditPackages=Core
EditPackages=Engine
; ...остальной стандартный список, включая KFMod...
EditPackages=MyMutator

Порядок важен. Пакеты компилируются сверху вниз, и пакет может использовать классы только из тех, что стоят выше. Если мутатор зависит, например, от ServerPerks, его строка EditPackages должна стоять раньше вашей.

Компиляция

cd "C:\Program Files (x86)\Steam\steamapps\common\KillingFloor\System"
ucc make

ucc make проходит по всем EditPackages и компилирует только пакеты, у которых ещё нет .u. Если поменять код и запустить снова, ничего не произойдёт: MyMutator.u уже есть. Сначала удалите старый .u:

del MyMutator.u
ucc make

Полный вывод также пишется в System/ucc.log.

Быстрый ini под проект

Со стандартным ini UCC при каждом запуске загружает все перечисленные пакеты. Сделайте копию KillingFloor.ini, например MyProject.ini, оставьте в ней только EditPackages, от которых зависит ваш код, плюс свой пакет, и компилируйте с ней:

ucc make -ini=MyProject.ini

Bat-файлы

Бэкап, удаление, пересборка и ожидание нажатия клавиши:

@echo off
cd /d "%~dp0"
copy MyMutator.u MyMutator.u_backup >nul 2>&1
del MyMutator.u >nul 2>&1
ucc make -ini=MyProject.ini
pause

Цикл, который показывает результат в заголовке окна и пересобирает по любой клавише:

@echo off
:start
title COMPILING :: MyMutator
cls
copy UCC_MyMutator.log UCC_MyMutator_OLD.log >nul 2>&1
del MyMutator.u >nul 2>&1
ucc make -ini=MyProject.ini -log=UCC_MyMutator.log
if errorlevel 1 goto error
title OK :: MyMutator
goto done
:error
title ERROR :: MyMutator
:done
findstr /c:"Log file closed" UCC_MyMutator.log
echo.
pause
goto start

Любой из файлов кладите в System. Предыдущий лог (_OLD.log) удобно держать, чтобы сравнивать две сборки.

Чтобы не декомпилировать стандартные пакеты вручную после каждого обновления, Dr_Killjoy в теме «Декомпиляция стандартного кода» на форуме killingfloor.ru выложил батник. В Dir задаётся адрес папки сервера, в которой идёт компиляция, а для каждого пакета повторяются три строки:

set Dir=C:\...
set Package=Core
del %Dir%%Package% /q
UCC.exe BatchExport %Package% class uc %Dir%%Package%\Classes
set Package=KFMod
del %Dir%%Package% /q
UCC.exe BatchExport %Package% class uc %Dir%%Package%\Classes
pause

В его версии так выгружаются Core, engine, goodkarma, ipdrv, Fire, GamePlay, editor, GUI2K4, unrealed, unrealgame, utv2004c, utv2004s, uweb, xadmin, xgame, xinterface, xvoting, xwebadmin, ROEngine, ROEffects, ROInterface, Old2k4, KFGui, KFMod, KFChar и KFMutators.

Flame советовал искать нужный код именно так: декомпилировать все стандартные пакеты и искать файлы с нужной строкой поиском по тексту. Например, exec function ReloadMeNow() (перезарядка) и ToggleIronSight находятся в KFMod.KFWeapon; второй вызывает PerformZoom из ROEngine.ROProjectileWeapon. Свои exec-функции обычно объявляют в контроллере (тема «Контроль игрока»).

Частые проблемы

Сообщение или симптомПричина
Ничего не компилируется, ошибок нет.u уже существует. Удалите его
Can't find files matching ...\Classes\*.ucНе та папка: исходники должны лежать в <корень KF>\<Пакет>\Classes
Unrecognized type / Bad class definition для класса из другого пакетаЭтого пакета нет в EditPackages или он стоит ниже вашего
Superclass ... not found после правки iniПравили копию ini, а компилируете без -ini= (или наоборот)
После пересборки сервер не пускает клиентовИзменённый .u с тем же именем вызывает Package version mismatch у всех, у кого в Cache старая копия. Для каждого публичного релиза меняйте имя пакета (MyMutatorV2)
The file '..\NZPR\Inc\NZPRClasses.h' needs to be updated. Do you want to overwrite the existing version? (Y/N)Отвечайте N: компиляция завершится нормально, а при Y будет ошибка couldn't open file. По опыту форума вопрос вызывает лишний «бесхозный» класс в пакете (эмиттер, ненужный класс); после его удаления запрос пропадает (форум killingfloor.ru, тема «Сообщение ...Classes.h' needs to be updated...»)
Скачанное оружие с исходниками после правок не компилируется: не найден пакет ресурсов (например, SVDLLI_A)Не хватает ресурсов, на которые ссылается код: положите .ukx в Animations, .utx в Textures. Подробности ищите по слову error в System\ucc.log (форум killingfloor.ru, тема «Изменение оружия»)
Superclass KFPlayerController_Story of class KFPCServ not found при сборке ServerPerks 7В EditPackages нет EditPackages=KFStoryGame и EditPackages=KFStoryUI выше пакетов ServerPerks (или сервер слишком старый) (форум killingfloor.ru, тема «Ошибка, при компиляции SP 7»)
Error: ... Unknown property in defaults: showMesh=SkeletalMesh'...' в классах Pickup оружия (после патча 1058)Переменную showMesh удалили из класса Pickup. Удалите или закомментируйте строку; по словам Flame, на работоспособность пакетов это не влияет. Если после этого у модели оружия от третьего лица пропали текстуры, перенесите строку в класс attachment оружия, убрав «show»: Mesh=SkeletalMesh'XMV850_A.XMV850-3rd' (форум killingfloor.ru, тема «Патч 1058 - Проблемы и их решения»)
UCC не компилирует и не декомпилирует ни в одной папке: General Protection Fault! и History: appInitУ Dr_Killjoy причиной был запущенный Steam; помогла и простая перезагрузка компьютера (форум killingfloor.ru, тема «Полетел ucc»)
ScrnBalance не собирается после правки бонусов перковScrnBalance — надстройка над ServerPerks и при компиляции запрашивает его классы: добавьте в сборку исходники ServerPerks (Dr_Killjoy, форум killingfloor.ru, тема «ScrnBalance»)

Строки #exec OBJ LOAD FILE=... в .uc говорят UCC, какие .utx/.uax/.ukx загрузить во время компиляции. В .u они не сохраняются и не заставляют сервер отправлять эти файлы клиентам.

ServerPerks в один пакет

Чтобы собрать ServerPerks V7 одним пакетом (форум killingfloor.ru, тема «Компиляция SP V7», ответ kok-s): перенесите все классы в пакет ServerPerks, затем найдите в них упоминания ServerPerksP и ServerPerksMut и замените на ServerPerks.