Split the platform out of Core: new Host library + HeadlessHost
CI / build-test (push) Successful in 1m24s

Core now depends only on Friflo.Engine.ECS — no MonoGame, no platform.
The windowed MonoGame host moves to the new MrGameEng.Host library:
GameHost, GameHostOptions, visual scene transitions (OverlayTransition,
Transitions.Fade/Wipe, TransitionRenderer) and the Input feature
(namespace MrGameEng.Input is unchanged). Transition timing stays in
Core (SceneManager exposes ActiveTransition/TransitionCoverage/
TransitionPhase; the host draws the overlay). EngineContext loses its
GraphicsDevice property: hosts publish the device as a service and
graphics code reads it via context.GetGraphicsDevice() in Graphics.

Core gains HeadlessHost: a fixed-timestep loop without a window or GPU
(Tick/RunTicks, Run with wall-clock pacing and lag resync) for dedicated
servers, batch simulation and tests. Graphics and Audio now carry their
own MonoGame.Framework.DesktopGL reference instead of inheriting it
from Core.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-06-12 23:04:34 +03:00
co-authored by Claude Fable 5
parent 79d406a9f4
commit 2ac074004a
33 changed files with 560 additions and 184 deletions
+19 -10
View File
@@ -27,13 +27,18 @@ is the living showcase — new engine features are demonstrated there.
Engine libraries (each feature is a namespaced subfolder of its host):
- **`Core`** — game loop, ECS world, scenes, time (`GameClock` with `TimeScale`; `GameSpeed`
for discrete pause/1×/3×/6× speed control over the clock, `context.UseGameSpeed(...)`;
`Calendar` turning scaled time into in-game days, `context.UseCalendar(secondsPerDay)`;
`Climate` — continuous seasonal/daily temperature and season over the calendar,
`context.UseClimate(settings)`),
plus **Input** (`MrGameEng.Input`: `InputManager`, `ActionMap`, `InputSystem`, in
`Core/Input/`). Depends only on MonoGame and Friflo.Engine.ECS.
- **`Core`** — the platform-free kernel: ECS world, scenes and transition timing, time
(`GameClock` with `TimeScale`; `GameSpeed` for discrete pause/1×/3×/6× speed control over
the clock, `context.UseGameSpeed(...)`; `Calendar` turning scaled time into in-game days,
`context.UseCalendar(secondsPerDay)`; `Climate` — continuous seasonal/daily temperature
and season over the calendar, `context.UseClimate(settings)`), services, logging, and
**`HeadlessHost`** — a fixed-timestep loop without a window or GPU (dedicated servers,
batch simulation, tests). Depends only on Friflo.Engine.ECS — no MonoGame, no platform.
- **`Host`** — the windowed MonoGame host: `GameHost` (wraps `Game`, owns the window and
`GraphicsDeviceManager`, publishes `GraphicsDevice` as a service), visual scene
transitions (`OverlayTransition`, `Transitions.Fade/Wipe`, `TransitionRenderer`), plus
**Input** (`MrGameEng.Input`: `InputManager`, `ActionMap`, `InputSystem`, in
`Host/Input/`). Nothing depends on `Host` except the game itself. → `Core`.
- **`Graphics`** — custom batched renderer, camera, sprites, plus **Tilemaps**
(`MrGameEng.Tilemaps`: code-built tile grids rendered through the batcher,
`scene.UseTilemaps()` after `UseRenderer2D()`, in `Graphics/Tilemaps/`) and **Lighting**
@@ -70,9 +75,13 @@ Engine libraries (each feature is a namespaced subfolder of its host):
netstandard2.0 analyzer.
Dependency rule: a library may depend only on `Core` and `Graphics`; `Core` depends only
on MonoGame and Friflo.Engine.ECS. Features grouped into one library share its package
set (e.g. `Content` carries both FontStash and StbImage) — keep optional/heavy deps
(Myra, NVorbis) in their own library so the rest of the engine stays free of them.
on Friflo.Engine.ECS (no MonoGame — the simulation must run headless). MonoGame is pulled
in by the platform/graphics libraries (`Host`, `Graphics`, `Audio`). Platform resources
(e.g. `GraphicsDevice`) are published by hosts as services in `EngineContext.Services`;
graphics code reaches the device via `context.GetGraphicsDevice()` (extension in
`Graphics`). Features grouped into one library share its package set (e.g. `Content`
carries both FontStash and StbImage) — keep optional/heavy deps (Myra, NVorbis) in their
own library so the rest of the engine stays free of them.
## Commands