Files
LittleSim/CLAUDE.md
Leonid PershinandClaude Fable 5 580cb6ccc9 Browser multiplayer client: promote the KNI spike to src/LittleSim.Web
LittleSim.Web (Blazor WASM + KNI/WebGL) is a real network client now: it
connects to the dedicated server over WebSocket (ClientWebSocket maps to
the browser socket), applies MrGameEng.Net delta snapshots into its
EntityStore and draws pawns through SpriteBatch — fatigue dims them just
like on desktop. The server address comes from ?server=ws://host:port
in the page URL, defaulting to the page's host on port 9050. The net
contract is mirrored in NetContract.cs (KNI and DesktopGL assemblies
can't mix until the graphics libraries build per platform) with loud
keep-in-sync comments on both sides.

Both clients now smooth replicated positions between 10 Hz snapshots:
NetLerp + NetSmoothingSystem lerp the visual position toward the latest
server position every frame (exponential, ~0.25 s to converge).

Verified against a live LittleSim.Server --listen: the browser client
connects (server log), draws ~3.3k lit pixels of pawns whose layout
changes between samples, and survives 400+ ticks without errors. Found
along the way: requestAnimationFrame freezes in hidden windows — the
game loop only runs while the tab is visible.

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

4.4 KiB

LittleSim

A god-game: minimal graphics, deep simulation. Built on the mrgameeng engine (MonoGame + Friflo ECS), vendored as the git submodule engine/ so the game and the engine are developed side by side in one editor window.

This game is also the engine's showcase: mrgameeng has no sample project, so every new engine feature gets demonstrated here (a scene, a console command, or a system using it) as part of landing the feature.

Game design docs live in docs/ and are written in Russian. Engine rules live in engine/CLAUDE.md — read it before touching engine code; both rule sets apply here.

Layout

engine/            mrgameeng git submodule (own repo, own CLAUDE.md)
src/LittleSim      the game (net8.0); references engine projects directly
src/LittleSim.Server  dedicated server: the world headless (engine HeadlessHost) +
                   WebSocket replication (MrGameEng.Net); also fast-forward and probe modes
src/LittleSim.Web  browser client (Blazor WASM + KNI/WebGL): connects to the dedicated
                   server, renders replicated pawns; mirrors the net contract (NetContract.cs)
                   because KNI and DesktopGL assemblies can't mix — keep in sync with
                   src/LittleSim/Net/NetSchema.cs. Outside LittleSim.sln's test flow.
Mods/Core          the game's own content as a mod: About, Defs, Languages, Textures
Cache/             runtime-built atlases (gitignored)
docs/              концепт, симуляция, моды, roadmap (Russian)
LittleSim.sln      game + engine sources + engine tests — one window for everything

Commands

git submodule update --init             # after fresh clone
dotnet build LittleSim.sln
dotnet run --project src/LittleSim -c Release   # measure perf in Release only
dotnet run --project src/LittleSim.Server -- --days 10 --tps 60   # headless fast-forward
dotnet run --project src/LittleSim.Server -- --listen             # multiplayer world (WebSocket)
dotnet run --project src/LittleSim -- --connect                    # client → ws://localhost:9050
dotnet run --project src/LittleSim.Server -- --probe               # CLI check of a running server
dotnet run --project src/LittleSim.Web                             # browser client (?server=ws://…)
dotnet test LittleSim.sln                        # runs the engine test suites

Content and mods

All game content is data in mods (MrGameEng.Mods): the game itself ships as the Core mod. Mods/Core/Defs holds JSON defs (terrain, plants, pawns — see docs/mods.md), Mods/Core/Languages/{ru,en} holds UI strings (default language is ru), Mods/Core/Textures holds source images. New mechanics get defs + localization keys, not hardcoded arrays; UI strings go through LanguageManager, never inline.

Atlases are built at game start from the merged texture tree of all active mods into Cache/Atlases (incremental: unchanged groups are skipped, a clean first run takes ~20 s). Region keys are paths relative to Textures/ without extension: atlases.GetRegion(device, "things/plant/treeoak/TreeOakA"). Console commands: mods, lang [code], defs [type], atlas [name].

Submodule workflow

Engine changes are committed inside engine/ first (engine repo, its commit style), pushed to the engine remote, then the submodule pointer bump is committed here. Never commit a pointer to an unpushed engine commit.

Game rules

  • Simulation first: depth of behavior over visuals. Graphics stay primitive (tinted quads are fine); complexity budget goes to simulation systems.
  • Determinism: the whole world derives from one integer seed. Systems that need randomness own a seeded Random; never use Random.Shared inside simulation.
  • Simulation/presentation split: simulation systems mutate components only; rendering reads them. No draw calls or UI from simulation systems.
  • ECS-first per the engine: plain struct : IComponent data, logic in systems.
  • Content as data: numbers, textures and balance live in Mods/Core/Defs, user-facing strings in Mods/Core/Languages — code only defines systems and def classes.
  • Every new mechanic gets a dev-console command for testing (regen, timescale, …).
  • Formatting: all C# code is formatted with CSharpier (editor.defaultFormatter is csharpier.csharpier-vscode, format-on-save is on). Match CSharpier's output — run csharpier format . (or let format-on-save handle it) before committing; never hand-format against it.