Updated the organization of engine libraries to group features by architectural role rather than by individual feature. Enhanced documentation in CLAUDE.md and architecture.md to reflect these changes. Removed obsolete project references and added new modules for content management and simulation. Adjusted project files for MrGameEng.Graphics and MrGameEng.UI.Tests to align with the new structure. This refactor aims to streamline the development process and improve clarity in the engine's architecture.
This commit is contained in:
@@ -10,38 +10,56 @@ Keep them up to date when architecture or conventions change.
|
||||
## Solution layout
|
||||
|
||||
```
|
||||
src/ MrGameEng.* engine libraries (one per functional area)
|
||||
src/ MrGameEng.* engine libraries (grouped by role, not one-per-feature)
|
||||
tests/ xUnit test projects, one per engine library
|
||||
tools/ CLI tools (atlas packer)
|
||||
docs/ architecture, conventions, roadmap (Russian)
|
||||
```
|
||||
|
||||
Libraries are grouped by architectural role rather than split per feature, to avoid a
|
||||
sprawl of two-file projects. A feature lives in a subfolder of its host library and
|
||||
keeps its own `MrGameEng.<Feature>` namespace (namespaces are independent of the
|
||||
assembly), so `using MrGameEng.Tilemaps;` etc. still resolve after a merge.
|
||||
|
||||
The engine has no sample project: the **LittleSim** game
|
||||
(https://gitea.hsrv.site/mrleo1nid/LittleSim, this repo as the `engine/` submodule)
|
||||
is the living showcase — new engine features are demonstrated there.
|
||||
|
||||
Engine modules: `Core` (game loop, ECS world, scenes, time), `Graphics` (custom batched
|
||||
renderer, camera, sprites), `Input`, `Audio`, `Assets` (runtime loading, no content
|
||||
pipeline), `Assets.Generator` (Roslyn source generator for typed asset handles),
|
||||
`Atlases` (texture-atlas builder + runtime loader; CLI wrapper in `tools/MrGameEng.AtlasTool`),
|
||||
`Tilemaps` (code-built tile grids rendered through the batcher; `scene.UseTilemaps()`
|
||||
after `UseRenderer2D()`), `Pathfinding` (grid A*/Dijkstra/BFS and flow fields over a
|
||||
game-implemented `IPathGrid`; Core-only, owns no world data),
|
||||
`AI` (utility-AI primitives — `ResponseCurve`, `Consideration<TContext>`, `UtilityAction<TContext>`,
|
||||
`UtilityAi<TContext>` selector, and a `Blackboard`; deterministic, generic over a game context,
|
||||
Core-only, owns no world data), `Collisions` (`Collider`
|
||||
component, spatial hash rebuilt per tick, pairs/queries/raycast; `scene.UseCollisions()`
|
||||
after movement systems), `UI` (Myra integration: `scene.UseUI()` after `UseRenderer2D()`),
|
||||
`DevConsole` (in-game console capturing `Core.Log`; `scene.UseDevConsole()` last in OnLoad),
|
||||
`Mods` (mod discovery + load order from `About/About.json`, JSON `Defs/` with parent
|
||||
inheritance and later-mod override, `Languages/<code>/` localization, merged content
|
||||
trees for textures; the game ships its own content as the `Core` mod).
|
||||
Dependency rule: every module may depend only on `Core`; `Core` depends only on
|
||||
MonoGame and Friflo.Engine.ECS. `Assets.Generator` is a netstandard2.0 analyzer.
|
||||
Documented exceptions: Myra renders with its own SpriteBatch internally; `Atlases`
|
||||
depends on `Graphics` (Texture2DRegion) and `Assets` (loader registration);
|
||||
`Tilemaps` depends on `Graphics` (regions, layers, renderer);
|
||||
`Collisions` depends on `Graphics` (Transform2D, RectF).
|
||||
Engine libraries (each feature is a namespaced subfolder of its host):
|
||||
|
||||
- **`Core`** — game loop, ECS world, scenes, time, plus **Input** (`MrGameEng.Input`:
|
||||
`InputManager`, `ActionMap`, `InputSystem`, in `Core/Input/`). Depends only on
|
||||
MonoGame and Friflo.Engine.ECS.
|
||||
- **`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/`). → `Core`.
|
||||
- **`Audio`** — ogg playback (NVorbis). → `Core`.
|
||||
- **`Content`** — the asset/content pipeline: **Assets** (`MrGameEng.Assets`: runtime
|
||||
loading, no MGCB pipeline; FontStash), **Atlases** (`MrGameEng.Atlases`: texture-atlas
|
||||
builder + runtime loader, CLI wrapper in `tools/MrGameEng.AtlasTool`; StbImage), and
|
||||
**Mods** (`MrGameEng.Mods`: mod discovery + load order from `About/About.json`, JSON
|
||||
`Defs/` with parent inheritance and later-mod override, `Languages/<code>/`
|
||||
localization, merged texture content trees; the game ships its content as the `Core`
|
||||
mod). → `Core`, `Graphics` (Atlases needs `Texture2DRegion`).
|
||||
- **`Simulation`** — deterministic gameplay primitives that own no world data:
|
||||
**Pathfinding** (`MrGameEng.Pathfinding`: grid A*/Dijkstra/BFS and flow fields over a
|
||||
game-implemented `IPathGrid`), **AI** (`MrGameEng.AI`: utility-AI primitives —
|
||||
`ResponseCurve`, `Consideration<TContext>`, `UtilityAction<TContext>`,
|
||||
`UtilityAi<TContext>` selector, `Blackboard`; generic over a game context), and
|
||||
**Collisions** (`MrGameEng.Collisions`: `Collider` component, spatial hash rebuilt per
|
||||
tick, pairs/queries/raycast, `scene.UseCollisions()` after movement systems).
|
||||
→ `Core`, `Graphics` (Collisions needs `Transform2D`, `RectF`).
|
||||
- **`UI`** — Myra integration (`scene.UseUI()` after `UseRenderer2D()`) plus
|
||||
**DevConsole** (`MrGameEng.DevConsole`: in-game console capturing `Core.Log`,
|
||||
`scene.UseDevConsole()` last in OnLoad). → `Core` (Myra renders with its own
|
||||
SpriteBatch internally).
|
||||
- **`Assets.Generator`** — Roslyn source generator for typed asset handles; standalone
|
||||
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.
|
||||
|
||||
## Commands
|
||||
|
||||
@@ -71,8 +89,11 @@ generator do not load under the SDK 8 compiler); the target framework stays net8
|
||||
(textures via `Texture2D.FromFile`, fonts via FontStashSharp, ogg via NVorbis,
|
||||
shaders precompiled by `dotnet-mgfxc` at build time). Game code references assets
|
||||
only through generated typed handles (`AssetRef<T>`), never string paths.
|
||||
- New engine functionality goes into the matching module, or a new
|
||||
`MrGameEng.<Area>` library if it is a distinct area — never into `Core` by default.
|
||||
- New engine functionality goes into the host library for its role (a namespaced
|
||||
subfolder, e.g. a new render feature under `Graphics/`), not a fresh project. Add a
|
||||
new `MrGameEng.<Area>` library only when the area is a genuinely new role or needs an
|
||||
isolated heavy/optional dependency — never into `Core` by default, never a
|
||||
two-file project per feature.
|
||||
- Every public engine feature must be covered by tests where logic is testable
|
||||
without a GPU, and demonstrated in the LittleSim game (the engine's showcase).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user