reckfellENGINE

Выделенный сервер: запуск, ENet и экспорт

Запуск без окна, серверная роль, UDP-порт, C#-пример и безопасный выбор Strip Visuals, Keep и Remove.

На этой странице

Что включает серверный режим

Выделенный сервер запускает игровую логику и сеть без отрисовки. Настройки запуска и экспорта решают разные задачи:

ДействиеЧто меняется
--headlessДрайвер окна становится headless, аудио — Dummy. Игровая логика сама по себе не становится серверной.
-- --serverПользовательский аргумент для вашего кода. В примере ниже запускает ENet-сервер.
Экспорт с тегом dedicated_serverДвижок автоматически выбирает headless и Dummy; пример включает серверную логику без --server.
Export as dedicated serverДобавляет тег и позволяет заменить ненужные визуальные ресурсы заглушками.

Добавление одного тега dedicated_server вручную не удаляет текстуры или меши из пакета. Запуск без окна также не означает нулевую нагрузку: физика, скрипты, импорт и сетевые обновления продолжают выполнять свою работу.

Первый запуск из проекта

Нужны C#-проект, настроенная главная сцена и работающая сборка проекта. Поместите оба файла ниже рядом с другими скриптами. Прикрепите DedicatedServerHost.cs к одной Entity в главной сцене. Этот пример владеет MultiplayerPeer дерева; не подключайте второй хост к тому же API Multiplayer.

Замените пути в команде на свои:

PowerShell
& 'C:\Tools\Reckfell\Reckfell Engine.console.exe' --headless --path 'D:\Games\MyGame' -- --server --port=7777 --bind=127.0.0.1

-- отделяет аргументы движка от аргументов игры. --headless стоит до разделителя, --server, --port=... и --bind=... — после него. OS.GetCmdlineUserArgs() получает только вторую часть.

Ожидаемый вывод: SERVER_READY bind=127.0.0.1 port=7777. Для клиента адрес подключения — 127.0.0.1, порт — 7777. ENet использует UDP. Сообщение подтверждает создание локального сервера, а не доступность из интернета и не успешную авторизацию игроков.

По умолчанию пример слушает только текущий компьютер. Для сетевого хоста явно задайте --bind=0.0.0.0 или --bind=*; клиент подключается к действительному адресу сервера, а не к 0.0.0.0. Параметр --bind принимает IP-адрес или *, не доменное имя. Открывайте в межсетевом экране выбранный UDP-порт. Для внешних клиентов за NAT может понадобиться настройка маршрутизатора.

Без --server и без тега dedicated_server код не создаёт ENet-сервер, даже если процесс запущен с --headless. Это позволяет тем же проектом выполнять безоконные проверки без случайного открытия сетевого порта.

Полный код запуска

ServerOptions.cs выбирает роль и проверяет параметры. Допустим один --port=<1..65535> и один --bind=...; аргументы чувствительны к регистру. Нулевой порт намеренно запрещён этим примером, чтобы сервер не получил случайный порт вместо указанного.

C#
using System;
using System.Globalization;
using System.Linq;
using System.Net;

public sealed record ServerOptions(bool Enabled, int Port, string BindAddress)
{
    public static bool TryRead(string[] args, bool dedicatedBuild,
        out ServerOptions options, out string error)
    {
        options = new(dedicatedBuild || args.Contains("--server"), 7777, "127.0.0.1");
        error = "";
        if (!options.Enabled) return true;
        bool portSeen = false, bindSeen = false;
        foreach (string arg in args)
        {
            if (arg.StartsWith("--port=", StringComparison.Ordinal))
            {
                if (portSeen || !int.TryParse(arg[7..], NumberStyles.None,
                    CultureInfo.InvariantCulture, out int port) || port is < 1 or > 65535)
                { error = "Use one --port=<1..65535>."; return false; }
                portSeen = true;
                options = options with { Port = port };
            }
            else if (arg.StartsWith("--bind=", StringComparison.Ordinal))
            {
                string address = arg[7..];
                if (bindSeen || (address != "*" && !IPAddress.TryParse(address, out _)))
                { error = "Use one --bind=<IP address or *>; hostnames are not accepted."; return false; }
                bindSeen = true;
                options = options with { BindAddress = address };
            }
        }
        return true;
    }
}

DedicatedServerHost.cs открывает порт, назначает транспорт и освобождает его при выходе Entity из дерева. StopServer() можно вызвать повторно. В примере установлен предел 32 клиента; это настройка ENet, а не подтверждённая производительность игры.

C#
using Reckfell;

public partial class DedicatedServerHost : Entity
{
    private ENetMultiplayerPeer? _peer;
    public bool Listening { get; private set; }

    public override void _Ready()
    {
        if (!ServerOptions.TryRead(OS.GetCmdlineUserArgs(), OS.HasFeature("dedicated_server"),
            out var options, out string error))
        { ReckfellApi.PrintErr(error); GetTree().Quit(2); return; }
        if (!options.Enabled) return;

        _peer = new ENetMultiplayerPeer();
        _peer.SetBindIP(options.BindAddress);
        Error result = _peer.CreateServer(options.Port, maxClients: 32);
        if (result != Error.Ok)
        {
            ReckfellApi.PrintErr($"SERVER_FAILED {result} bind={options.BindAddress} port={options.Port}");
            _peer.Dispose(); _peer = null;
            GetTree().Quit(3); return;
        }
        Multiplayer.MultiplayerPeer = _peer;
        Listening = true;
        ReckfellApi.Print($"SERVER_READY bind={options.BindAddress} port={options.Port}");
    }

    public void StopServer()
    {
        if (_peer is null) return;
        Multiplayer.MultiplayerPeer = null!;
        _peer.Close(); _peer.Dispose(); _peer = null;
        Listening = false;
    }

    public override void _ExitTree() => StopServer();
}

Это транспортный запуск. Репликация Entity, RPC, проверка полномочий и правила игры добавляются отдельно: сетевой игровой процесс. Не считайте клиентские команды достоверными только потому, что соединение установлено.

Экспорт без лишних ресурсов

  1. Убедитесь, что C#-проект имеет .csproj и .sln. Обычная сборка .csproj ещё не доказывает готовность к экспорту: C#-экспорт проверяет файл решения.
  2. Установите экспортные шаблоны той же версии движка с поддержкой C# для целевой платформы и архитектуры. Для игры на сервере используйте экспортный исполняемый файл; редактор нужен для импорта и экспорта.
  3. Создайте отдельный профиль экспорта, например Windows Server. Во вкладке ресурсов выберите Export as dedicated server.
  4. Для корня проекта выберите Strip Visuals, затем переопределите отдельные файлы и каталоги по таблице ниже. Режим каталога наследуется дочерними файлами, пока для них не задан собственный режим.
  5. Экспортируйте проект и перенесите всю папку результата, включая необходимые файлы C#. Не переносите только .exe или один PCK наугад.
  6. Запустите экспорт и проверьте SERVER_READY. Включённый тег сам выбирает безоконные драйверы и серверную ветку примера; --port и --bind по-прежнему передаются после --.
РежимРезультатКогда выбирать
Strip VisualsПоддерживаемые ресурсы заменяются заглушками. Например, Texture2D сохраняет размеры, Mesh — AABB, материал заменяется заглушкой. Исходные пиксели и геометрия не сохраняются как рабочие визуальные данные.Когда серверу не нужны данные этого ресурса.
KeepРесурс экспортируется с исходными данными.Карта высот, пиксели для правил игры, геометрия для расчётов и другие реально читаемые сервером данные.
RemoveФайл исключается из пакета. Ссылки на него не чинятся автоматически.Только для файлов, которые серверная ветка не загружает и на которые не ссылаются необходимые сцены и ресурсы.

Strip Visuals не является универсальным удалением всего графического содержимого: подмена зависит от поддержки create_placeholder у типа ресурса. Заглушка меша с AABB не заменяет его треугольники для ваших расчётов. Если форма столкновения уже хранится отдельно, сохраняйте нужную форму; если строите её из меша при запуске, сохраняйте и исходный меш через Keep. Аналогично, для анализа изображения нужен Keep, а не только сохранённые ширина и высота.

Не стройте серверную ветку с обязательной загрузкой клиентского меню, камеры или файла, помеченного Remove. Лучше иметь серверную главную сцену либо создавать клиентские Entity только в клиентской ветке. Файл ресурса Reckfell в текстовом формате имеет расширение .rdata; уровень — .rscene, префаб — .rprefab.

Подробности: теги возможностей, командная строка, экспорт проектов.

Запуск экспортного шаблона

PCK не является исполняемым файлом. Для ручной проверки используйте C#-экспортный шаблон той же версии, а не редактор: редактор не является проверкой загрузки экспортированных сборок C#.

В проверенном Windows debug-шаблоне 1.0.0 отключены переопределения пути: --path и --main-pack завершают запуск ошибкой. Эти параметры из команды запуска исходного проекта не нужно переносить в команду запуска экспортной игры.

Для отдельного пакета имена должны совпадать: Server.exe и Server.pck лежат рядом; консольная оболочка — Server.console.exe. При обычном экспорте сохраняйте созданные имена и всю структуру результата. Если пакет встроен в исполняемый файл, отдельный PCK не требуется.

Откройте терминал в папке экспорта и запустите:

PowerShell
& '.\Server.console.exe' -- --port=7777 --bind=127.0.0.1

Ни --headless, ни --server здесь не нужны, если в экспортном проекте есть dedicated_server. После SERVER_READY подключите отдельный клиент. Сам серверный пакет не предоставляет меню для клиента.

Если сервер не работает

СимптомЧто проверить
Окно не открылось, но SERVER_READY отсутствуетОдного --headless недостаточно для выбора роли. Передайте -- --server или проверьте тег экспортированного проекта.
Вывод Use one --port..., код завершения 2Порт должен быть целым числом 1..65535 без пробелов и повторного параметра.
Вывод Use one --bind..., код 2Укажите один IP-адрес или *, не имя хоста.
SERVER_FAILED, код 3Посмотрите имя ошибки, адрес и порт в той же строке. Проверьте, свободен ли UDP-порт и принадлежит ли адрес сетевому интерфейсу машины.
Локальный клиент подключается, внешний — нетПример по умолчанию слушает 127.0.0.1. Проверьте --bind, адрес клиента, UDP-правило межсетевого экрана и NAT.
После экспорта пропали данные изображения или мешаПроверьте наследуемый Strip Visuals; поставьте Keep для данных, которые сервер действительно читает.
Ошибка загрузки ресурсаПроверьте Remove, обязательные ссылки и полноту папки экспорта.
C#-экспорт сообщает об отсутствии решенияВосстановите правильный .sln рядом с проектом; успешная сборка одного .csproj эту проблему не устраняет.

Пример проверен на Windows с установленной SDK 1.0.0: запуск без окна, ENet-подключение через loopback и работа экспортного debug-шаблона с отдельным PCK. В пакете проверены заглушки текстуры, меша и материала, а также Keep и Remove. Это не проверка Linux-развёртывания, release-шаблона, внешней сети или нагрузки.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.