spikes/KniWeb (outside LittleSim.sln): a kni-blazor-gl template project (KNI 4.2.9001, net8.0) referencing MrGameEng.Core directly. A mini-host in the GameHost mold drives EngineContext/GameClock/Scene phases over KNI's Game; the scene moves 300 Friflo entities in the update phase and draws them with SpriteBatch (WebGL). Verified in a real browser: sprites render and animate, browser console is clean. Decision (docs/web-client.md): path A — KNI — is the primary route for the web client; the core runs in Blazor WASM unchanged thanks to the Core/Host split. Known follow-ups: per-platform compilation of the graphics libraries against nkast.* packages, shader compatibility for Renderer2D, HTTP-served content instead of the filesystem. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
63 lines
4.7 KiB
Markdown
63 lines
4.7 KiB
Markdown
# Веб-клиент: spike KNI и решение A/B
|
||
|
||
Дата: 2026-06-12. Спайк живёт в `spikes/KniWeb` (вне `LittleSim.sln`).
|
||
|
||
## Вопрос
|
||
|
||
Путь A — «MonoGame в браузере» через [KNI](https://github.com/kniEngine/kni)
|
||
(форк MonoGame с платформой Blazor WebAssembly/WebGL, те же неймспейсы
|
||
`Microsoft.Xna.Framework.*`). Путь B — тонкий веб-клиент без MonoGame
|
||
(TypeScript/PixiJS поверх сетевой репликации). Спайк проверял минимальную
|
||
жизнеспособность пути A: **ядро движка + Friflo + WebGL-спрайт в браузере**.
|
||
|
||
## Что сделано
|
||
|
||
`dotnet new kni-blazor-gl` (пакет шаблонов `nkast.Kni.Templates`, KNI 4.2.9001,
|
||
net8.0) + ProjectReference на `engine/src/MrGameEng.Core` + мини-хост в духе
|
||
`GameHost` поверх KNI `Game`. Сцена: 300 сущностей в Friflo `EntityStore`,
|
||
`QuerySystem` двигает их в Update-фазе (отскок от краёв, seed 42), Draw-фаза
|
||
рисует через KNI `SpriteBatch` (WebGL).
|
||
|
||
## Результат — путь A жизнеспособен
|
||
|
||
- **`MrGameEng.Core` работает в Blazor WASM без изменений**: `EngineContext`,
|
||
`GameClock`, `Scene`/`SceneManager`, тайминг переходов — всё ядро завелось
|
||
как есть (заслуга расслоения Core/Host: в ядре нет ни MonoGame, ни платформы).
|
||
- **Friflo.Engine.ECS 3.6 работает в wasm**: создание сущностей, архетипы,
|
||
`QuerySystem`, `ForEachEntity` — без ошибок в консоли браузера.
|
||
- **KNI 4.2.9001 рендерит через WebGL** с XNA-API: `Game`,
|
||
`GraphicsDeviceManager`, `SpriteBatch`, `Texture2D.SetData` — совпадает с
|
||
кодом, который пишется под десктопный MonoGame.
|
||
- Сборка тривиальна: обычный `Microsoft.NET.Sdk.BlazorWebAssembly` проект,
|
||
никаких wasm-workload-плясок не понадобилось.
|
||
|
||
## Известные ограничения пути A (работа на этапе «веб-клиент»)
|
||
|
||
1. **Пер-платформенная компиляция библиотек движка.** `MrGameEng.Graphics`,
|
||
`Content`, `Audio`, `UI` ссылаются на `MonoGame.Framework.DesktopGL`; для
|
||
веба их надо собирать против пакетов `nkast.*` (типы те же по API, но другие
|
||
сборки). Решение — msbuild-условие (`KniPlatform=BlazorGL` → nkast-пакеты),
|
||
без изменения исходников.
|
||
2. **Шейдеры.** `Renderer2D` использует прекомпилированные `dotnet-mgfxc`
|
||
эффекты — KNI имеет собственный компилятор эффектов; совместимость надо
|
||
проверять отдельным спайком, прежде чем тащить батчер в веб.
|
||
3. **Нет файловой системы.** Моды/дефы/атласы в браузер приезжают по HTTP;
|
||
текущая схема «собрать атласы при старте из PNG» в вебе не работает —
|
||
атласы пре-билдятся и кладутся в `wwwroot` (или приезжают с сервера).
|
||
4. **Потоки.** `Task.Run`-загрузка контента и `Thread.Sleep`-пейсинг не для
|
||
браузера (клиенту `HeadlessHost.Run` и не нужен — цикл гонит
|
||
`requestAnimationFrame` через KNI).
|
||
5. **Производительность не мерялась** (300 спрайтов — гладко); бюджет
|
||
сущностей в wasm-интерпретаторе будет заметно ниже десктопного, замерять
|
||
на реальной сцене с включённым AOT.
|
||
|
||
## Решение
|
||
|
||
**Путь A (KNI)** — основной для веб-клиента: переиспользуем ядро, сцены и
|
||
в перспективе графику движка; код игры один на все платформы. Путь B остаётся
|
||
запасным, если упрёмся в шейдеры (п. 2) или производительность (п. 5).
|
||
|
||
Порядок работ не меняется: сначала `MrGameEng.Net` (WebSocket-транспорт +
|
||
репликация — нужен любому пути) и сетевой мультиплеер на десктопе, затем
|
||
`MrGameEng.Host.Web` поверх KNI по образцу спайка.
|