Свой сервер

Оптимизация Killing Floor Dedicated Server - настройки KillingFloor.ini

Killing Floor Dedicated Server обычно упирается не в "секретные" параметры, а в стабильную сеть, аккуратный KillingFloor.ini, быстрый redirect для кастомных файлов и разумный tickrate. Этот гайд собирает рабочий baseline для KF1-сервера и объясняет, какие значения стоит менять первыми.

Перед правками остановите сервер и сохраните копию System/KillingFloor.ini. Меняйте параметры по одному блоку и проверяйте сервер после каждой группы изменений.

Быстрый baseline

Что настраиваемРекомендуемое началоКогда менять
CacheSizeMegs128 или 256Если много кастомных карт, mutators и долгие смены карты
NetServerMaxTickRate25 или 30Если есть запас CPU и стабильный ping
MaxInternetClientRate10000 или 15000Если игрокам не хватает пропускной способности
HTTP redirectВключитьЕсли игроки скачивают карты с самого сервера
PrecacheСначала оставить как естьМенять только при стабильных фризах или долгих загрузках

Для публичного интернет-сервера обычно лучше стабильные 25-30 tickrate, чем завышенный tickrate с рывками и потерей пакетов.

1. Кеш и память

[Engine.GameEngine]
CacheSizeMegs=256

Практичная таблица:

RAM сервераЗначение
256 MB или меньшеCacheSizeMegs=32
512 MBCacheSizeMegs=64
768 MBCacheSizeMegs=128
1 GB и большеCacheSizeMegs=256

Не ставьте огромное значение "на всякий случай". Для старого UE2.5 важнее предсказуемая работа процесса, чем агрессивный кеш.

2. Сетевые лимиты и tickrate

[IpDrv.TcpNetDriver]
MaxClientRate=15000
MaxInternetClientRate=10000
NetServerMaxTickRate=30
LanServerMaxTickRate=35
ServerTravelPause=4.0
SpawnPrioritySeconds=1.0
RelevantTimeout=5.0
KeepAliveTime=0.2
InitialConnectTimeout=200.0
ConnectionTimeout=15.0
AckTimeout=1.0
DownloadManagers=IpDrv.HTTPDownload
AllowDownloads=True

Что важно

  • NetServerMaxTickRate=30 - частота обновления сервера. Для публичных серверов обычно достаточно 25-30.
  • LanServerMaxTickRate=35 - можно держать выше для LAN или закрытых серверов с низким ping.
  • MaxClientRate и MaxInternetClientRate - верхний лимит пропускной способности на игрока.
  • AllowDownloads=True - нужно для выдачи кастомных файлов, но лучше не раздавать большие карты напрямую с игрового процесса.

Если сервер начинает лагать во время плотных волн, сначала снизьте tickrate до 25, а не урезайте все сетевые лимиты сразу.

3. HTTP redirect для карт и mutators

Когда игроки качают кастомные карты с самого игрового сервера, это забирает канал и может портить ping всем остальным. Для production-сервера лучше настроить HTTP redirect.

[IpDrv.HTTPDownload]
RedirectToURL=https://example.com/kf-redirect/
UseCompression=True

Проверочный список:

  1. Файлы на redirect должны совпадать с файлами сервера.
  2. Имена и расширения должны быть такими же, как ожидает клиент.
  3. После обновления карты или mutator обновляйте redirect одновременно с сервером.
  4. Если игроки получают Package version mismatch, сначала проверьте redirect и кеш клиента.

Смежная инструкция: ошибка Package version mismatch.

4. Precache: включать или отключать

Отключение precache в нескольких подсистемах может ускорить старт или смену карты, но иногда переносит фризы на первый спавн оружия, zed или эффекта.

[ALAudio.ALAudioSubsystem]
UsePrecache=False

[Engine.LevelInfo]
bNeverPrecache=True

[Engine.NullRenderDevice]
UsePrecaching=False

[D3DDrv.D3DRenderDevice]
UsePrecaching=False

[D3D9Drv.D3D9RenderDevice]
UsePrecaching=False

[OpenGLDrv.OpenGLRenderDevice]
UsePrecaching=False

[PixoDrv.PixoRenderDevice]
UsePrecaching=False

Для dedicated server обычно важнее стабильность. Если после отключения precache появились микрофризы в начале волны или при первом появлении контента, верните прежние значения.

5. Трупы, гибы и лишняя физика

Для KF1 не копируйте блоки вида [KFGame.KFGoreManager] из KF2-гайдов. В Killing Floor 1 чаще смотрят на параметры игрового типа и mutator-настройки, которые реально есть в вашем KillingFloor.ini.

[KFMod.KFGameType]
TimeUntilVanished=5.0

Слишком низкие значения выглядят странно для игроков, но могут помочь слабому серверу на больших волнах и custom-картах.

[IpServer.UdpServerQuery]
bEnabled=True

[IpDrv.MasterServerUplink]
DoUplink=True
SendStats=True
ServerBehindNAT=False
DoLANBroadcast=True

Если сервер за NAT, значение ServerBehindNAT зависит от вашей схемы сети. Важнее всего корректно открыть game/query порты и проверить сервер из внешней сети.

7. Пути и базовая целостность

[Core.System]
CachePath=..\Cache
CacheExt=.uxx
Paths=..\System\*.u
Paths=..\Maps\*.rom
Paths=..\StaticMeshes\*.usx
SavePath=..\Save

Не удаляйте Paths ради оптимизации. Если сервер перестал видеть карты, mutators или пакеты, проверьте этот блок первым.

  • Контент из другой папки. Строки Paths можно дублировать абсолютными путями, чтобы сервер брал файлы ещё и из другой установки и одни и те же карты не приходилось копировать. Пример krestps (форум killingfloor.ru, тема «Быстрая скачка В НЕСКОЛЬКО потоков»; по его словам, с картами это работает и на Steam-версии):
Paths=../System/*.u
Paths=D:/killingfloor/System/*.u
Paths=../Maps/*.rom
Paths=D:/killingfloor/Maps/*.rom
Paths=../Textures/*.utx
Paths=D:/killingfloor/Textures/*.utx

В той же теме проверено, что несколько строк RedirectToURL не делают скачивание с редиректа многопоточным.

8. Логи и эксплуатация

Полностью выключать полезные логи не стоит. Лучше держать отдельный файл лога на каждый инстанс и периодически чистить старые файлы.

Практика для нескольких серверов на одной машине:

  • отдельная папка или отдельный конфиг на каждый инстанс
  • разные game/query ports
  • отдельные log-файлы
  • регулярная очистка старых логов и временных файлов
  • мониторинг CPU во время поздних волн, а не только на пустом сервере

UE2.5 ограниченно использует несколько ядер. Если один процесс упирается в CPU, часто эффективнее разнести несколько серверов по разным ядрам/инстансам, чем искать один магический параметр.

Замеры нагрузки

Цифры админов из темы «Нагрузка сервера на железо» (2010-2012) и соседних тем. Это старые машины и частные наблюдения, а не бенчмарки:

  • Важнее максимум игроков на сервере, а не их сумма. Proton: на обычном двухъядерном Celeron с 2 ГБ памяти можно запустить 4-5 серверов до примерно 20 человек на каждом, загрузка процессора около 20-25%, тормозов почти нет. А один сервер на 30 слотов на той же машине тормозит конкретно.
  • Linux против Windows. NTFS: одна и та же машина, 6 человек в одном месте карты: Linux - CPU 30%, 43 градуса; Windows XP - CPU 60%, 51 градус. В простое XP нагружает процессор на 2-10% больше. MAUOHE3, везде по 6 игроков: 13% от одного ядра Q6600 на CentOS 6, на пятой ветке CentOS вдвое меньше, на Windows - 37% от одного ядра Turion X2 2 ГГц.
  • Ещё примеры. pingvus: Athlon XP 2200+, 768 МБ, минимальный консольный Linux - один классический сервер на 6 игроков берёт максимум 50-55% процессора и около 350-370 МБ памяти вместе с ОС; если распределить нагрузку через CpuLimit, влезает ещё один сервер на 6 игроков. Локомотив: CentOS 5.7, 8-ядерный Xeon, 3 ГБ - три сервера по 6 слотов дают нагрузку максимум 5-10%. offutt: одноядерный Pentium 2.66 ГГц с Hyper-threading (Win2003 R2) под сервером KF на 14 игроков плюс серверами CS и Source доходил до 100%, рос пинг; после перехода на двухъядерный процессор в придачу без проблем заработали два сервера KF.
  • Пик - смена карты. REGETT (тема «AMD Athlon 64 3000+ (1,8Ггц) vs Intel Celeron D (2.6Ггц)»): на Athlon 64 3000+ - ожидание 10%, игра 18-23%, смена карты до 80% на 10-15 секунд при 5 игроках; на Celeron D с Linux - ожидание 4-10%, игра 50-80%, смена карты 100% на 40-50 секунд при 3 игроках. После недели тестов он сделал вывод, что AMD лучше держит нагрузку.
  • Одно ядро на Linux. В теме «Есть поддержка мультипроцессорности?» Rush (Ubuntu 12.04, Core 2 Quad Q8300 2.5 ГГц) видел в htop, что сервер грузит одно ядро на 100%, а три других простаивают: ядро системы собрано с SMP, но сервер не умеет использовать больше одного ядра и лишь переключается между ними. Pir@tehnic предлагал привязать сервер к ядрам через taskset, поставив taskset -c 0,1,2,3 перед обычной командой запуска screen -A -m -d -S KF-SERVER с полным путём к бинарнику сервера в папке System, но предупреждал, что по его опыту с CS:Source это лишь привязывает процесс и не раскидывает нагрузку; при нескольких серверах каждый просто занимает своё ядро. w.a.l написал, что на Windows сервер (UCC.exe) у него использует все 4 ядра.

Бегущий лог в окне консоли (Windows)

Из темы «CMD LOG» (форум killingfloor.ru): при быстром выводе текста cmd.exe постоянно перерисовывает окно, и это может нагружать машину сильнее самого сервера. Проще всего свернуть окно. Если текст из консоли не нужен совсем, перенаправьте вывод ucc в nul, то есть вместо start /wait ucc server ... в батнике перезапуска запускайте:

ucc server KF-Angkor.rom?game=*********?mutator=MutLoader.MutLoader?MaxPlayers=30?AdminName=*****?AdminPassword=******* > nul

Весь текстовый вывод ucc.exe при этом выбрасывается, но в файл лога сервер продолжает писать.

Батник автоперезапуска с логами по времени

Батник Dr_Killjoy из темы «Автоматический перезапуск сервера» (форум killingfloor.ru, времена сервера 1060). Карта, геймтайп, ini, админ и число игроков задаются переменными в начале. Батник ведёт свой лог в папке KFLogs (там видно, когда сервер падал), а лог сервера каждый раз получает имя со временем запуска, поэтому старые логи не затираются. Батник кладётся в корень сервера (рядом с папкой System); логин и пароль админа замените своими:

:begin
@echo off
title KF Server
setlocal enabledelayedexpansion
set workdir=%cd%
set sdir=%workdir%\system
set batlogdir=%cd%\KFLogs
if not exist %batlogdir% md %batlogdir%
:retry
call :settime
set map=KF-Farm.rom
set gametype=KFMod.KFGameType
set adminlogin=<логин>
set adminpass=<пароль>
set maxplayers=6
set kfini=KillingFloor.ini
set mutators=MutLoader.MutLoader
set batlog=runserver#1.bat
set batlog=%batlogdir%\%batlog%_%now%.log
set kflog=KFServer_%now%.log
if not exist %sdir%\ucc.exe call :notfounducc
call :echolog "Server started/restarted at %now% ..."
set callucc="%sdir%\ucc.exe" server %map%?game=%gametype%?VACSecured=true?MaxPlayers=%maxplayers%?Mutator=%mutators%?AdminName=%adminlogin%?AdminPassword=%adminpass% -ini=%kfini% -log=%kflog%
call :echolog "%callucc%"
call %callucc%
call :settime
call :echolog "Server crashed at %now% ..."
goto retry
exit /b
:settime
set now=%TIME:~0,-3%
set now=%now::=.%
set now=%now: =0%
set now=%DATE:~-4%.%DATE:~3,2%.%DATE:~0,2%.%now%
exit /b
:notfounducc
call :echolog "ucc.exe has not been found"
pause
goto end
:echolog
echo %~1
echo %~1>%batlog%
exit /b
:end

Готовый минимальный профиль

[Engine.GameEngine]
CacheSizeMegs=256

[IpDrv.TcpNetDriver]
MaxClientRate=15000
MaxInternetClientRate=10000
NetServerMaxTickRate=30
LanServerMaxTickRate=35
ServerTravelPause=4.0
SpawnPrioritySeconds=1.0
RelevantTimeout=5.0
KeepAliveTime=0.2
InitialConnectTimeout=200.0
ConnectionTimeout=15.0
AckTimeout=1.0
DownloadManagers=IpDrv.HTTPDownload
AllowDownloads=True

[IpServer.UdpServerQuery]
bEnabled=True

[IpDrv.MasterServerUplink]
DoUplink=True
SendStats=True
ServerBehindNAT=False
DoLANBroadcast=True

После этого настройте HTTP redirect, проверьте поздние волны на 6 игроках и только потом экспериментируйте с precache, временем жизни трупов и более высоким tickrate.