Архитектура OpenCiv3: движок, модель и интерфейс
Границы модулей
| Часть | Ответственность |
|---|---|
C7 | Godot-проект, карта, сцены, интерфейс, анимации, звук |
C7Engine | Правила, действия, AI, генерация, цикл хода |
C7Engine/C7GameData | Состояние партии, определения объектов, DTO сохранений |
QueryCiv3 | Чтение бинарных структур BIQ/SAV |
ConvertCiv3Media | Декодирование PCX, FLC и AMB |
Blast | Распаковка сжатия PKWare DCL |
EngineTests | Проверки логики, импорта и сохранений |
Разделение подтверждается заметкой об engine и зависимостями интерфейса. Старое имя C7 сохраняется в пространствах имён и путях. Упоминание отдельного корневого C7GameData в README не соответствует расположению данных в этом дереве.
Путь команды
Интерфейс отправляет типизированное сообщение MessageToEngine; очередь обрабатывается в EngineStorage.ProcessNextMessageToEngine. Движок меняет GameData и отправляет MessageToUI либо сообщение анимации. Для ожидания завершения анимации хранятся TaskCompletionSource по идентификатору; есть и ожидание конкретного типа сообщения.
Это позволяет видеть границу «приказ → правила → состояние → уведомление». Однако EngineStorage — статическое хранилище, а GameData доступна через него и из Lua. Наличие очередей не доказывает потокобезопасность, готовый multiplayer или сетевой протокол. Комментарии о будущей сети отражают намерение.
Источники: C7Engine/EngineStorage.cs, C7Engine/EntryPoints/MessageToEngine.cs, C7Engine/EntryPoints/MessageToUI.cs.
Отделение от Godot
Проект C7Engine/C7Engine.csproj использует Microsoft.NET.Sdk и net8.0; Godot SDK задан в клиентском проекте. Это делает правила пригодными для отдельного тестирования. При этом движок всё ещё знает об анимациях через сообщения и асинхронное ожидание, поэтому независимость представления не абсолютна.
Применение к нашей игре
Наш dist/app.js объединяет состояние, DOM, бой, AI и редактирование. Первая полезная адаптация — выделить чистые операции над состоянием и общую проверку допустимости приказов. UI и AI должны вызывать одни правила; редактор должен менять определения через явный интерфейс.
Рекомендуемая схема: команда → validate → apply → события → render. Это наш проектный вывод. На первом этапе достаточно модулей JavaScript и явных аргументов состояния; перенос Godot, C# и статического singleton не требуется. Сохранение лучше строить по отдельной схеме, чтобы DOM-узлы, кэши и циклические ссылки не попадали в JSON.