FOnline Engine
Current master GitHub
Документация Docs/ru/explanation/architecture/index.md

Архитектура движка

Этот документ содержит основанную на исходном коде карту слоёв FOnline. Используйте её, чтобы определить владельца поведения перед переходом к документации конкретной подсистемы.

Решение о владении

Маршрутизируйте изменение через четыре решения:

  1. Поведение, которое должно одинаково работать в нескольких играх, помещайте во владеющий слой исходников Engine и руководство соответствующей подсистемы. Правила игры, авторский контент, конфигурация продукта, пороги приёмки и release policy оставляйте во встраивающем проекте.
  2. Используйте эту страницу архитектуры, когда поведение пересекает несколько слоёв Engine или границу Engine/project. Используйте Дерево исходников, когда требуется узнать расположение кода или первый каталог для проверки.
  3. Привязывайте генерируемые контракты Engine к владеющим исходникам Engine, машинной модели и generator. Входы проекта и генерируемые результаты проекта не становятся переиспользуемым авторитетом Engine только потому, что их читает или создаёт инструмент Engine.
  4. Ссылайтесь с невладеющей страницы на владельца вместо повторения контракта. Перечень каталогов исходников не является архитектурным решением, а интеграция одного проекта не доказывает общее поведение Engine.

Полный ответ о границе называет и владельца, и маршрут документации: используйте эту страницу для поведения уровня всей архитектуры, «Дерево исходников» для навигации по коду, а руководство владеющей подсистемы для её подробного контракта.

Общая картина

FOnline состоит из переиспользуемого движка, встраиваемого игровым проектом. Игровой проект владеет контентом, скриптами, конфигурацией продукта и release policy; движок владеет переиспользуемыми runtime systems, tools, инфраструктурой generated API, platform frontends и композицией сборки.

Диаграмма показывает переиспользуемый движок FOnline слева и встраивающий игровой проект справа. Движок предоставляет runtime systems, tools, code generation и platform applications. Игра предоставляет project configuration, scripts, content, tests и release policy. Стороны соединяются generated contracts и extension hooks.
Движок владеет переиспользуемыми runtime и tooling; встраивающий проект владеет правилами игры, контентом, конфигурацией продукта, валидацией и release policy. Зависимости пересекают границу только через объявленную конфигурацию, generated contracts и extension hooks.

Основные слои:

  • Applications - точки входа исполняемых файлов и библиотек в Source/Applications/.
  • Essentials - низкоуровневые platform, memory, filesystem, logging, serialization, sockets и utilities в Source/Essentials/.
  • Common runtime - общая модель движка в Source/Common/: entities, properties, prototypes, maps, networking primitives, config, scripts и базовые services движка.
  • Client runtime - presentation/resource/network-client сторона в Source/Client/.
  • Server runtime - authoritative world, managers, database backends, network-server сторона и updater backend в Source/Server/.
  • Frontend - абстракция application/window/rendering в Source/Frontend/.
  • Scripting - реализованные backend AngelScript и Managed C#, зарезервированный placeholder Native и регистрация script methods в Source/Scripting/.
  • Tools - baker, редактирование вокруг Mapper, asset processors и связанный developer tooling в Source/Tools/.
  • BuildTools - CMake stages, helpers, toolchains, генерация platform projects, package layout и поддержка валидации в BuildTools/.

Слой приложений

Source/Applications/ является практическим каталогом точек входа. Он содержит обёртки приложений:

  • ClientApp.cpp и ClientLib.cpp для client host/runtime flows.
  • ServerApp.cpp, ServerDaemonApp.cpp, ServerHeadlessApp.cpp и ServerServiceApp.cpp для вариантов server.
  • MapperApp.cpp для центрального интерактивного инструмента редактирования.
  • BakerApp.cpp и ASCompilerApp.cpp для поддержки generation/build.
  • TestingApp.cpp для выполнения тестов.

BuildTools/cmake/stages/Applications.cmake подключает эти файлы к project-specific targets в зависимости от build options, включая режимы client/server/tool/platform/library/headless. Не фиксируйте target names в документации движка: они часто выводятся из FO_DEV_NAME и presets встраивающего проекта.

Карта приложений приведена в Applications.

Проверенные пути исходного кода

  • Source/Applications/
  • Source/Common/EngineBase.h
  • Source/Common/EngineBase.cpp
  • Source/Common/Entity.h
  • Source/Common/Entity.cpp
  • Source/Common/ScriptSystem.h
  • Source/Common/ScriptSystem.cpp
  • Source/Client/Client.h
  • Source/Server/Server.h
  • Source/Frontend/Application.h
  • Source/Frontend/ApplicationInit.cpp
  • BuildTools/cmake/stages/Applications.cmake

Слой общей среды выполнения

Source/Common/ содержит общие понятия, используемые client, server, tools и scripts. Важные точки входа:

  • EngineBase.h / EngineBase.cpp - базовые services движка и общее runtime state.
  • Entity.h / Entity.cpp - экспортируемые entity concepts, общие для runtime sides.
  • Properties.h, EntityProperties.h, EntityProtos.h, ProtoManager.h - модель property/prototype.
  • ScriptSystem.h / ScriptSystem.cpp - абстракция script engine для runtime sides и tools.
  • Geometry.h, Movement.h, PathFinding.h, MapLoader.h - переиспользуемые primitives карт и движения.
  • NetBuffer.h, NetworkUdp.h - общие networking primitives.
  • ConfigFile.h, DataSource.h, FileSystem.h, CacheStorage.h - поддержка config и data access.
  • ImageWriter.h - кодировщики PNG для screenshots, dumps render target и atlas. WritePng записывает RGBA в файл; EncodeCompactPng создаёт фильтрованный непрозрачный RGB в памяти для передачи. Game.CaptureScreenshot(maxSide) читает последний завершённый кадр, при необходимости уменьшает его целочисленным коэффициентом (0 сохраняет полный размер) и запрещает захват внутри render callback, когда кадр ещё не дорисован.

Этот слой должен оставаться переиспользуемым. Правила игры обычно выражаются через content/scripts или project-native extensions, а не через включение policy одного проекта в common engine code.

Состояние генератора случайных чисел

random_generator владеет своим состоянием: capture_state() возвращает четыре 64-битных слова, задающих последовательность, а restore_state() кладёт их обратно, отвергая полностью нулевое состояние, потому что xoshiro256++ на нём стоит в неподвижной точке. BaseEngine::CaptureRandomState() и RestoreRandomState() делегируют генератору под тем же mutex, что и обычные розыгрыши. Формата сериализации на уровне движка нет: вызывающий, которому нужно сохранить состояние, сериализует четыре слова сам.

Этот API — примитив сохранения, а не полная граница снимка. Авторитетный сервер обязан сначала остановить изменение игрового состояния и только потом снимать генератор вместе с соответствующими миром, временем, событиями и хранилищем. Клиентская презентация, транспорт и генераторы отдельных подсистем независимы и в это состояние не входят.

Серверная операция RunInQuiescence() даёт такую переиспользуемую внутрипроцессную границу остановки: приём новых соединений закрывается, исполнение main/worker вычерпывается, кадровое и синхронизированное время вместе с планированием отложенных задач замораживаются, живой граф сущностей покрывается, а синхронизированное время и состояние генератора снимаются до вызова callback. ServerEngine::CreateSnapshot() собирает стабильное подмножество: отвергает подсчитанные runtime-блокеры скриптов, отложенных задач, событий времени и движения, сбрасывает точные время и id и возвращает байты базы данных вместе с описывающим их состоянием. Свежая конструкция принимает эту пару обратно, восстанавливает состояние генератора до стартовых задач, загружает байты в хранилище и проверяет время и id до игровых хуков. Атомарная публикация слота, персистентные формы событий времени и движения, пригодность на стороне проекта, политика UI, целостность и ротация, а также согласованная перезагрузка клиента остаются работой встраивающего слоя. Точные гарантии и исключения — в серверной среде выполнения и хранении данных.

Слои клиента и сервера

Source/Client/Client.h включает точки композиции client-side: интеграцию application, доступ к resource/cache, views для critters/items/locations/maps, effects, rendering-facing structures и client connection code.

Source/Server/Server.h включает authoritative runtime: entities, managers, database, geometry, scripting-facing server objects, client validation, networking и поддержку updater backend.

Документируйте client и server раздельно, потому что у них разные владельцы:

  • Client представляет локальные views, resources, UI-facing objects и network-client behavior.
  • Server владеет authoritative world state, persistence, entity managers, validation и network-server behavior.

Слой frontend

Source/Frontend/Application.h и связанные файлы Application*.cpp / Rendering*.cpp абстрагируют запуск platform app и rendering backends. Различия headless/stub/native frontend принадлежат этому слою, а не документации игры.

Документация platform workflow:

Слой scripting

Source/Common/ScriptSystem.* определяет общую абстракцию script system. Source/Scripting/ предоставляет runtime-specific регистрацию methods и integration folders:

  • Source/Scripting/AngelScript/
  • Source/Scripting/Native/
  • Source/Scripting/Managed/ — реализованный backend Managed C#, bridge CoreScripts, analyzers, load-context host и tests
  • Source/Scripting/*ScriptMethods.cpp

Движок владеет переиспользуемым script/native bridge. Игровой проект владеет конкретными game script modules и gameplay logic.

Слой сборки и генерации

BuildTools/cmake/stages/ является staged CMake pipeline. Текущие stage files:

  • Init.cmake
  • ProjectOptions.cmake
  • CoreLibs.cmake
  • ThirdParty.cmake
  • EngineSources.cmake
  • Codegen.cmake
  • Applications.cmake
  • ScriptsAndBaking.cmake
  • Packages.cmake
  • Finalize.cmake

Эти stages компонуют code движка с конфигурацией встраивающего проекта. Перед изменением build behavior прочитайте Процесс сборки.

Типичный runtime flow

Обычный workflow встраивающего проекта:

  1. Repository игры конфигурирует CMake из корня проекта.
  2. BuildTools загружает project options и engine sources.
  3. Шаги codegen и baking подготавливают generated API/resources/scripts.
  4. Applications собираются из точек входа Source/Applications/.
  5. Runtime запускается через выбранное приложение: client, server, mapper, baker, test app или platform package.
  6. Client/server/tools используют common runtime services и при необходимости вызывают принадлежащие игре scripts/content.

Где документировать изменения

Введите запрос.