Files
mrgameeng/CLAUDE.md
T
Leonid PershinandClaude Fable 5 5d3c18de40
CI / build-test (push) Failing after 1m8s
Add MrGameEng.Mods: mod loading, JSON defs and localization
Mods are folders with About/About.json metadata; ModLoader resolves a
deterministic load order (dependencies first, ties alphabetical) and
later mods override earlier ones everywhere.

DefDatabase loads JSON def files ({ "type", "defs": [...] }) into
game-registered Def subclasses, with parent inheritance (own fields on
top of the parent's, nested values replaced whole), abstract parents
and full replacement of same-named defs by later mods.

LanguageManager loads Languages/<code>/*.json flat key-string maps,
switches language at runtime and falls back current -> default -> key.

ModContentTree merges one content folder across mods by relative path;
AtlasBuilder gains an explicit-sources Build overload so a merged
texture tree can be packed incrementally at game start.

The LittleSim game now ships its entire content as the Core mod,
demonstrating the module end to end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 21:51:17 +03:00

4.7 KiB

mrgameeng

2D game engine built on MonoGame 3.8.4 (DesktopGL), .NET 8, C#. ECS-first: Friflo.Engine.ECS 3.6 is tightly integrated into the core — all gameplay state lives in components, all logic in systems.

Design docs and developer documentation live in docs/ and are written in Russian. Keep them up to date when architecture or conventions change.

Solution layout

src/      MrGameEng.* engine libraries (one per functional area)
tests/    xUnit test projects, one per engine library
tools/    CLI tools (atlas packer)
docs/     architecture, conventions, roadmap (Russian)

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), 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).

Commands

dotnet build MrGameEng.sln
dotnet test MrGameEng.sln

Architecture rules

  • ECS-first: components are plain data (struct implementing IComponent), behavior goes into Friflo systems (QuerySystem), wired through SystemRoot. No Update() methods on game objects, no inheritance-based entities.
  • Hot paths (per-frame systems) must be allocation-free below the renderer's parallel threshold; above it Parallel.For scheduler overhead is the accepted trade. A Friflo chunk holds a whole archetype — parallelize by slicing chunks into segments, never by chunk alone. Measure in Release only, using the Renderer2D phase timings.
  • Rendering: custom batcher in Graphics (vertex buffers, layer→depth→texture sort, atlas support); SpriteBatch is not used in engine code. Draw systems write vertices directly from Friflo chunk iteration. Orthographic camera (one active per scene), registered render layers (World or Screen space, optional Y-sort), AABB culling against the camera rect before vertices are written.
  • No MGCB content pipeline. Assets are raw files under Assets/, loaded at runtime (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.
  • 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).

Code conventions

  • Nullable reference types enabled, warnings as errors, file-scoped namespaces.
  • Public engine API requires XML doc comments (English).
  • Tests: xUnit, named Method_Scenario_Expectation.

Memory (echovault MCP)

  • At session start, call memory_context to load prior decisions for this project; call memory_search before working on a topic that may have prior context (e.g. "renderer", "transitions", "generator").
  • Before ending a session where you decided, fixed or learned something, save it with memory_save: decisions (X over Y + why), bug root causes, non-obvious gotchas (e.g. Friflo/Myra API traps). Write for a future agent with zero context.
  • Don't save what the repo already records (code, docs/, git history) or trivia.