Архитектура движка
Этот документ содержит основанную на исходном коде карту слоёв FOnline. Используйте её, чтобы определить владельца поведения перед переходом к документации конкретной подсистемы.
Решение о владении
Маршрутизируйте изменение через четыре решения:
- Поведение, которое должно одинаково работать в нескольких играх, помещайте во владеющий слой исходников Engine и руководство соответствующей подсистемы. Правила игры, авторский контент, конфигурация продукта, пороги приёмки и release policy оставляйте во встраивающем проекте.
- Используйте эту страницу архитектуры, когда поведение пересекает несколько слоёв Engine или границу Engine/project. Используйте Дерево исходников, когда требуется узнать расположение кода или первый каталог для проверки.
- Привязывайте генерируемые контракты Engine к владеющим исходникам Engine, машинной модели и generator. Входы проекта и генерируемые результаты проекта не становятся переиспользуемым авторитетом Engine только потому, что их читает или создаёт инструмент Engine.
- Ссылайтесь с невладеющей страницы на владельца вместо повторения контракта. Перечень каталогов исходников не является архитектурным решением, а интеграция одного проекта не доказывает общее поведение Engine.
Полный ответ о границе называет и владельца, и маршрут документации: используйте эту страницу для поведения уровня всей архитектуры, «Дерево исходников» для навигации по коду, а руководство владеющей подсистемы для её подробного контракта.
Общая картина
FOnline состоит из переиспользуемого движка, встраиваемого игровым проектом. Игровой проект владеет контентом, скриптами, конфигурацией продукта и release policy; движок владеет переиспользуемыми runtime systems, tools, инфраструктурой generated API, platform frontends и композицией сборки.
Основные слои:
- 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.hSource/Common/EngineBase.cppSource/Common/Entity.hSource/Common/Entity.cppSource/Common/ScriptSystem.hSource/Common/ScriptSystem.cppSource/Client/Client.hSource/Server/Server.hSource/Frontend/Application.hSource/Frontend/ApplicationInit.cppBuildTools/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:
- Сборка, упаковка и отладка в браузере
- Сборка, упаковка и отладка на Android
- Нативная отладка, AngelScript и Managed C#
Слой 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 и testsSource/Scripting/*ScriptMethods.cpp
Движок владеет переиспользуемым script/native bridge. Игровой проект владеет конкретными game script modules и gameplay logic.
Слой сборки и генерации
BuildTools/cmake/stages/ является staged CMake pipeline. Текущие stage files:
Init.cmakeProjectOptions.cmakeCoreLibs.cmakeThirdParty.cmakeEngineSources.cmakeCodegen.cmakeApplications.cmakeScriptsAndBaking.cmakePackages.cmakeFinalize.cmake
Эти stages компонуют code движка с конфигурацией встраивающего проекта. Перед изменением build behavior прочитайте Процесс сборки.
Типичный runtime flow
Обычный workflow встраивающего проекта:
- Repository игры конфигурирует CMake из корня проекта.
- BuildTools загружает project options и engine sources.
- Шаги codegen и baking подготавливают generated API/resources/scripts.
- Applications собираются из точек входа
Source/Applications/. - Runtime запускается через выбранное приложение: client, server, mapper, baker, test app или platform package.
- Client/server/tools используют common runtime services и при необходимости вызывают принадлежащие игре scripts/content.
Где документировать изменения
- Поведение уровня архитектуры: этот файл.
- Навигация по исходному коду: Source Tree Guide.
- Точки входа приложений: Applications.
- Workflow сборки: процесс сборки и конвейер BuildTools.
- Граница script/native: Nullability и Scripting.
- Отладка платформ: Web, Android и native debugging.