G1: bump engine (formula engine + Host split), wire formula demo

Engine pointer -> 10898b0, which brings in two engine changes:
- the gene-system formula engine (Core): a data-driven expression
  evaluator that compiles a def string once and evaluates it
  allocation-free against a variable context;
- a parallel refactor splitting the platform out of Core into a new
  MrGameEng.Host library.

Game migration for the Host split: reference MrGameEng.Host (+ add it
and its test project to the solution), import MrGameEng.Host where
GameHost/GameHostOptions/Input are used, switch Transition.Fade ->
Transitions.Fade, and read the device via context.GetGraphicsDevice()
now that EngineContext is platform-free.

Showcase the formula engine with a dev-console 'formula <expr>' command
that compiles and evaluates an expression. Also adds docs/гены.md, the
gene-system design doc (phases G1-G5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-06-12 23:30:44 +03:00
co-authored by Claude Opus 4.8
parent 49936a1de3
commit 32bae03869
13 changed files with 181 additions and 12 deletions
+1
View File
@@ -6,6 +6,7 @@
<ItemGroup>
<ProjectReference Include="..\..\engine\src\MrGameEng.Core\MrGameEng.Core.csproj" />
<ProjectReference Include="..\..\engine\src\MrGameEng.Host\MrGameEng.Host.csproj" />
<ProjectReference Include="..\..\engine\src\MrGameEng.Graphics\MrGameEng.Graphics.csproj" />
<ProjectReference Include="..\..\engine\src\MrGameEng.Audio\MrGameEng.Audio.csproj" />
<ProjectReference Include="..\..\engine\src\MrGameEng.Content\MrGameEng.Content.csproj" />
+1
View File
@@ -1,6 +1,7 @@
using LittleSim.Scenes;
using Microsoft.Xna.Framework;
using MrGameEng.Core;
using MrGameEng.Host;
// Контент Core-мода грузится уже в окне — на загрузочном экране (BootScene), в фоне.
using var host = new GameHost(
+2 -1
View File
@@ -5,6 +5,7 @@ using LittleSim.UI;
using Microsoft.Xna.Framework;
using MrGameEng.Audio;
using MrGameEng.Core;
using MrGameEng.Host;
using MrGameEng.UI;
using Myra.Graphics2D.UI;
@@ -73,6 +74,6 @@ public sealed class BootScene : Scene
Context.Services.Add(content);
Context.Services.Add(new ModAtlases(content.AtlasCacheDirectory));
content.Languages.SetLanguage(_settings.Language);
Context.Scenes.Switch(new MainMenuScene(), Transition.Fade(0.6f));
Context.Scenes.Switch(new MainMenuScene(), Transitions.Fade(0.6f));
}
}
+2 -1
View File
@@ -2,6 +2,7 @@ using LittleSim.Content;
using LittleSim.UI;
using Microsoft.Xna.Framework.Input;
using MrGameEng.Core;
using MrGameEng.Host;
using MrGameEng.Input;
using MrGameEng.UI;
@@ -40,7 +41,7 @@ public sealed class CreditsScene : Scene
{
if (!Context.Scenes.IsTransitioning)
{
Context.Scenes.Switch(new MainMenuScene(), Transition.Fade(0.4f));
Context.Scenes.Switch(new MainMenuScene(), Transitions.Fade(0.4f));
}
}
}
+3 -2
View File
@@ -3,6 +3,7 @@ using LittleSim.Content;
using LittleSim.UI;
using Microsoft.Xna.Framework.Input;
using MrGameEng.Core;
using MrGameEng.Host;
using MrGameEng.Input;
using MrGameEng.UI;
using Myra.Graphics2D.UI;
@@ -73,7 +74,7 @@ public sealed class LoadGameScene : Scene
{
Context.Scenes.Switch(
new WorldScene(save.ToConfig(), save),
Transition.Fade(0.6f)
Transitions.Fade(0.6f)
);
}
},
@@ -104,7 +105,7 @@ public sealed class LoadGameScene : Scene
{
if (!Context.Scenes.IsTransitioning)
{
Context.Scenes.Switch(new MainMenuScene(), Transition.Fade(0.4f));
Context.Scenes.Switch(new MainMenuScene(), Transitions.Fade(0.4f));
}
}
}
+2 -1
View File
@@ -2,6 +2,7 @@ using LittleSim.Content;
using LittleSim.UI;
using Microsoft.Xna.Framework;
using MrGameEng.Core;
using MrGameEng.Host;
using MrGameEng.UI;
namespace LittleSim.Scenes;
@@ -37,7 +38,7 @@ public sealed class MainMenuScene : Scene
{
if (!Context.Scenes.IsTransitioning)
{
Context.Scenes.Switch(scene, Transition.Fade(0.4f));
Context.Scenes.Switch(scene, Transitions.Fade(0.4f));
}
}
}
+3 -2
View File
@@ -6,6 +6,7 @@ using LittleSim.Content;
using LittleSim.UI;
using Microsoft.Xna.Framework.Input;
using MrGameEng.Core;
using MrGameEng.Host;
using MrGameEng.Input;
using MrGameEng.UI;
using Myra.Graphics2D.UI;
@@ -153,14 +154,14 @@ public sealed class NewWorldScene : Scene
Seed = seed,
SmoothPasses = _smoothing,
};
Context.Scenes.Switch(new WorldScene(config), Transition.Fade(0.6f));
Context.Scenes.Switch(new WorldScene(config), Transitions.Fade(0.6f));
}
private void Back()
{
if (!Context.Scenes.IsTransitioning)
{
Context.Scenes.Switch(new MainMenuScene(), Transition.Fade(0.4f));
Context.Scenes.Switch(new MainMenuScene(), Transitions.Fade(0.4f));
}
}
}
+1
View File
@@ -5,6 +5,7 @@ using LittleSim.UI;
using Microsoft.Xna.Framework;
using MrGameEng.Audio;
using MrGameEng.Core;
using MrGameEng.Host;
using Myra.Graphics2D.Brushes;
using Myra.Graphics2D.UI;
+2 -1
View File
@@ -5,6 +5,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using MrGameEng.Audio;
using MrGameEng.Core;
using MrGameEng.Host;
using MrGameEng.Input;
using MrGameEng.UI;
using Myra.Graphics2D.UI;
@@ -59,7 +60,7 @@ public sealed class SettingsScene : Scene
{
if (!Context.Scenes.IsTransitioning)
{
Context.Scenes.Switch(new MainMenuScene(), Transition.Fade(0.4f));
Context.Scenes.Switch(new MainMenuScene(), Transitions.Fade(0.4f));
}
}
}
+29 -3
View File
@@ -10,7 +10,9 @@ using Microsoft.Xna.Framework.Input;
using MrGameEng.Assets;
using MrGameEng.Core;
using MrGameEng.DevConsole;
using MrGameEng.Formulas;
using MrGameEng.Graphics;
using MrGameEng.Host;
using MrGameEng.Input;
using MrGameEng.Inspector;
using MrGameEng.Lighting;
@@ -73,7 +75,7 @@ public sealed class WorldScene : Scene
var assets = Context.Services.GetOrDefault<AssetManager>() ?? Context.UseAssets();
var content = Context.Services.Get<GameContent>();
var atlases = Context.Services.Get<ModAtlases>();
var device = Context.GraphicsDevice;
var device = Context.GetGraphicsDevice();
var input = this.UseInput();
_speed = Context.Services.Get<GameSpeed>();
_speed.SetStep(0); // новый мир/загрузка стартуют на x1
@@ -435,7 +437,7 @@ public sealed class WorldScene : Scene
if (!Context.Scenes.IsTransitioning)
{
_speed.Resume();
Context.Scenes.Switch(scene, Transition.Fade(0.5f));
Context.Scenes.Switch(scene, Transitions.Fade(0.5f));
}
}
@@ -456,10 +458,34 @@ public sealed class WorldScene : Scene
c.WriteLine($"regenerating world, seed {seed}");
Context.Scenes.Switch(
new WorldScene(_config with { Seed = seed }),
Transition.Fade(0.6f)
Transitions.Fade(0.6f)
);
}
);
console.Register(
"formula",
"formula <expr> — compile and evaluate an expression (gene-formula engine demo)",
(c, args) =>
{
if (args.Length == 0)
{
c.WriteLine(
"usage: formula <expr> e.g. formula clamp(lerp(0, 10, 0.5), 0, 8)"
);
return;
}
var expression = string.Join(' ', args);
try
{
c.WriteLine($"{expression} = {Formula.Compile(expression).Evaluate()}");
}
catch (FormulaException e)
{
c.WriteLine($"error: {e.Message}");
}
}
);
console.Register(
"menu",
"menu — return to the main menu",