Теория Gameface модов
Пользовательский интерфейс игры состоит из совокупности окон (Windows), которыми управляет движок wulf. Сами окна могут быть реализованы на:
CGF– Coherent GameFace, этоHTML+JavaScript+CSSUnbound– собственный фреймворк ЛестыScaleform– этоFlash, в котором используется язык программированияActionScript 3(AS3)
Coherent Gameface
Coherent Gameface (CGF) — это технология, которая позволяет создавать интерфейсные окна с использованием веб-технологий: HTML, CSS и JavaScript. Такие окна отображаются внутри игры. Движок для отображения этих окон похож на браузер, однако оптимизирован для работы в игровом окружении.
Для выполнения JavaScript-кода в окнах CGF используется движок V8, который также применяется в браузере Google Chrome.
Ознакомиться с документацией по Coherent Gameface можно на официальном сайте: https://docs.coherent-labs.com/cpp-gameface/, учтите, что игра использует не самую свежую версию CGF, поэтому некоторые функции могут быть недоступны.
Важными отличиями CGF от обычного браузера являются:
- Задержка между установкой
CSSстилей и их применением к элементам страницы (2 кадра) - Работа с анимациями
CSS-CGFпредоставляет оптимизированную структуру для выполнения анимаций, прямое манипулирование стилями ухудшает производительность - Масштабирование реализовано путём установки
font-size: 2pxна корневой элемент страницы, поэтому все размеры на странице должны быть заданы вemилиremединицах - В качестве лейаута страницы по умолчанию используется
flexbox - Доступны фильтры для взаимодействия с фоном игры, например блюр
Окна CGF в игре
Как браузер состоит из разных вкладок, внутри каждой из которых "живёт" своя веб-страница, так и в игре разные компоненты интерфейса реализованы в виде отдельных окон CGF, каждое из которых загружает свою страницу. Отличием от браузера является то, что на одном экране может находиться сразу несколько окон CGF. Например ангар на Lesta состоит из смеси CGF-окон и Scaleform-окон.
Обмен данными между Python и JavaScript
Для взаимодействия JavaScript-кода страницы с Python-скриптами игры использутся реактивная ViewModel система. Окно определяется классом View(ViewImpl), который инициализирует модель данных Model(ViewModel), в которой определяются значения (properties) и команды (commands).
- Команды (
JS -> Python) — это события, которые могут быть вызваны изJavaScript-кода страницы и обработаны вPython-скриптах. - Значения (
Python -> JS) — это реактивные данные, которые могут быть изменены изPython-скриптов и прочитаны вJavaScript-коде страницы. Когда значение изменяется вPython, об этом автоматически уведомляетсяJavaScript-код страницы.
from frameworks.wulf import ViewModel
from gui.impl.pub import ViewImpl
class ExampleModel(ViewModel):
def __init__(self, properties=3, commands=1):
super(ExampleModel, self).__init__(properties=properties, commands=commands)
def _initialize(self):
super(ExampleModel, self)._initialize()
self._addStringProperty('exampleString', '')
self._addNumberProperty('exampleNumber', 0)
self._addBoolProperty('exampleBool', False)
self.exampleCommand = self._addCommand('exampleCommand')
class ExampleView(ViewImpl):
viewLayoutID = ModDynAccessor('RES_JSON_KEY')
def __init__(self, server, pageName='', pageId=''):
settings = ViewSettings(ExampleView.viewLayoutID(), flags=ViewFlags.VIEW, model=CDPModel())
super(ExampleView, self).__init__(settings)
@property
def viewModel(self):
return super(ExampleView, self).getViewModel()Ресурсы игры (res_map.json)
Для использования в Python-скриптах различных ресурсов известных на этапе компиляции игры, Мир Танков использует механизм DynAccessor и файл res_map.json, на который эти DynAccessor ссылаются.
{
...
"f4": {
"type": "Layout",
"path": "coui://gui/gameface/_dist/production/lobby/crew/CrewHeaderTooltipView/CrewHeaderTooltipView.html",
"parameters": {
"entrance": "CrewHeaderTooltipView",
"extension": "",
"impl": "gameface"
}
},
"10db6": {
"type": "Image",
"path": "img://gui/maps/icons/crewWidget/buttonsBar/background.png",
"parameters": {
"extension": "",
}
},
...
}Для взаимодействия с CGF-окнами необходимо зарегистрировать ресурсы в res_map.json.
OpenWG.Gameface
OpenWG.Gameface — это специальный мод, который позволяет упростить регистрацию своих ресурсов в res_map.json и предоставляет дополнительные возможности для работы с окнами CGF.
Процесс регистрации состоит из перезаписи (путём помещения в папку res_mods) файла res_map.json, в котором дописываются новые ресурсы и последующим автоматическим перезапуском игры, который нужен только если файл был изменён (например установлен новый мод).
Пример регистрации ресурсов
В пакете мода необходимо создать файл mods/configs/res_map/*.json в котором описать используемые ресурсы.
[
{
"itemID": "mods/testDialog/title",
"type": "String",
"parameters": {
"key": "Dialog window made with Unbound (WULF)",
"textdomain": "dialogs",
"extension": ""
}
},
{
"itemID": "mods/testTooltip/layoutID",
"type": "Layout",
"path": "coui://gui/gameface/mods/testTooltip/TestTooltip.html",
"parameters": {
"extension": "",
"entrance": "TestTooltip",
"impl": "gameface"
}
}
]После чего, в Python-коде можно получить доступ к этим ресурсам через ModDynAccessor:
from openwg_gameface import ModDynAccessor
title = ModDynAccessor('mods/testDialog/title')Или из JavaScript-кода окна CGF:
const title = R.dialogs.title;TODO: Проверить такой ли путь
Andrei Soprachev