Pathfinding (depends on Core only): GridPathfinder with A* (octile/
Manhattan heuristic), Dijkstra and BFS over a game-implemented
IPathGrid; 4/8 connectivity, diagonals never cut corners. FlowField +
FlowFieldBuilder (multi-source Dijkstra) give crowds O(1) steering per
agent per frame. All buffers are grid-sized once and invalidated by a
generation stamp - repeated queries allocate nothing and clear nothing.
Collisions (Graphics exception: Transform2D, RectF): Collider component
(circle/AABB, offset, two-way layer masks), CollisionWorld - a uniform
spatial hash on flat arrays rebuilt from scratch each tick (O(n) for
movers, zero alloc after warm-up, deterministic pair order), pair
collection, QueryAabb and closest-hit Raycast. scene.UseCollisions()
registers CollisionSystem after movement systems.
30 new tests (string-map mazes, cost weighting, corner cutting, flow
descent; pair/mask/query/raycast). Sample gains a PathfindingScene
('path' console command): click to set the goal, 250 agents follow the
flow field, the A* path is highlighted, colliding agents flash red.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TileSet maps ids to texture regions with tints (0 = empty), TileGrid is a
bounds-checked dense ushort grid, and the Tilemap component places a grid
in the world per render layer. UseTilemaps() inserts TilemapRenderSystem
before the flush; it submits only the camera-visible cell range
(TilemapMath.VisibleCells), so frame cost scales with the screen, not the
grid. Demonstrated in the sample as a checkerboard floor; Tiled loading
stays on the roadmap on top of this API.
AtlasBuilder packs a directory tree of loose images into atlas pages plus
JSON metadata (deterministic shelf packing, incremental rebuilds, orphan
cleanup); TextureAtlas loads them back handing out Texture2DRegions, so
sprites from one page batch into a single draw call. The asset handle
generator maps .atlas files to TextureAtlas and skips page images.
Demonstrated in the sample (Assets/Atlases + 'atlas' console command),
wrapped as tools/MrGameEng.AtlasTool for build scripts.
Documented dependency exception: Atlases depends on Graphics and Assets.
Load memory_context at session start, search before topic work,
save decisions/bugs/gotchas before ending a session.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Core gains a static Log (Debug/Info/Warning/Error + event); the engine
logs key events like scene switches. The console captures Log output
into a 2048-line ring buffer and executes registered commands with
input history (up/down), Tab prefix completion and scrolling
(PageUp/PageDown/End/wheel). Built-ins: help, clear, echo, timescale,
close, quit; games register their own (sample: stress/main/beep).
Console core is pure logic covered by headless tests; the Myra overlay
renders a single label rebuilt only when the Revision counter moves -
an idle or closed console costs nothing per frame. Toggled with the
backquote key; sample gameplay hotkeys are suppressed while open.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Five optimizations measured on the 100k-entity stress scene (Release,
vsync off): 103 FPS baseline -> 297 FPS.
- Sprite submission and vertex building run on all cores above
Renderer2DOptions.ParallelThreshold (default 8192). Work is sliced
into 4096-entity segments: a Friflo chunk holds a whole archetype,
so per-chunk parallelism degenerates to one thread. Segments merge
in deterministic order, preserving radix sort stability.
- Vertex buffer is ring-written with SetDataOptions.NoOverwrite
(GPU buffer 2x frame size); Discard only on wrap-around.
- Texture2DRegion precomputes UVs - four float divisions per sprite
per frame removed.
- Renderer2D exposes per-phase timings (submit/sort/build/upload/draw),
shown in the sample HUD - all further optimization is data-driven.
- Sample BounceSystem parallelized the same segmented way.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
scene.UseUI() creates a per-scene Myra Desktop and registers
UiRenderSystem last in the draw phase (UI on top, window pixels).
GameHost now exposes itself as a Game service (Myra needs the instance;
useful for games too). Myra was picked over Gum/ImGui for the
FontStashSharp ecosystem fit, pipeline-free assets and maturity; its
internal SpriteBatch use is a documented exception to the engine rule.
Sample: on-screen HUD replaces window-title-only stats — live FPS label,
music volume slider and scene-switch buttons on both scenes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>