G2: bump engine (gene foundation), load genes + gene demo command

Engine pointer -> bc18db5: brings in the organism-agnostic gene
foundation (GeneDef, managed Genome, Phenotype trait computation) plus a
parallel MrGameEng.Net library the game does not use.

Game wiring: register the "Gene" def type and ship Mods/Core/Defs/
genes.json — a full gene set covering the plant phenotype dimensions
(environment optima/tolerances, vigor, lifecycle, reproduction) plus a
discrete morph gene, each declaring its trait effects as formulas. A
dev-console 'gene [seed]' command generates a genome from these defs,
prints its alleles, expressed values and computed traits, then breeds a
child — demonstrating the whole pipeline end to end. These genes seed
the G3 migration of plants onto traits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-06-12 23:43:50 +03:00
co-authored by Claude Opus 4.8
parent 32bae03869
commit 91a00b4305
4 changed files with 104 additions and 1 deletions
+2
View File
@@ -1,5 +1,6 @@
using MrGameEng.Atlases;
using MrGameEng.Core;
using MrGameEng.Genetics;
using MrGameEng.Mods;
namespace LittleSim.Content;
@@ -56,6 +57,7 @@ public sealed class GameContent
var defs = new DefDatabase();
defs.RegisterType<TerrainDef>("Terrain");
defs.RegisterType<GeneDef>("Gene");
defs.RegisterType<PlantDef>("Plant");
defs.RegisterType<PawnDef>("Pawn");
defs.RegisterType<WorldPresetDef>("WorldPreset");
+48
View File
@@ -11,6 +11,7 @@ using MrGameEng.Assets;
using MrGameEng.Core;
using MrGameEng.DevConsole;
using MrGameEng.Formulas;
using MrGameEng.Genetics;
using MrGameEng.Graphics;
using MrGameEng.Host;
using MrGameEng.Input;
@@ -486,10 +487,57 @@ public sealed class WorldScene : Scene
}
}
);
console.Register(
"gene",
"gene [seed] — generate a genome from Gene defs, show alleles/traits and a bred child",
(c, args) => RunGeneDemo(c, content, args)
);
console.Register(
"menu",
"menu — return to the main menu",
(_, _) => Switch(new MainMenuScene())
);
}
// Демонстрация генной системы (фаза G2): из Gene-дефов генерируем геном, печатаем аллели,
// выраженные значения и признаки (вычисленные формулами), затем скрещиваем двух особей.
private static void RunGeneDemo(DevConsole console, GameContent content, string[] args)
{
var genes = content.Defs.All<GeneDef>();
if (genes.Count == 0)
{
console.WriteLine("no Gene defs loaded");
return;
}
var registry = genes.ToDictionary(g => g.DefName, g => g, StringComparer.Ordinal);
var seed = args.Length > 0 ? int.Parse(args[0]) : Random.Shared.Next();
var random = new Random(seed);
console.WriteLine($"genome from {genes.Count} genes, seed {seed}:");
var parentA = Genome.Generate(genes, random);
foreach (var gene in genes)
{
var allele = parentA[gene.DefName];
console.WriteLine(
$" {gene.DefName}: [{allele.A:0.##}, {allele.B:0.##}] -> {parentA.Express(gene):0.###}"
);
}
console.WriteLine("traits:");
foreach (var (trait, value) in Phenotype.Compute(parentA, registry).OrderBy(t => t.Key))
{
console.WriteLine($" {trait} = {value:0.###}");
}
var parentB = Genome.Generate(genes, random);
var child = Genome.Breed(parentA, parentB, registry, random);
var childTraits = Phenotype.Compute(child, registry);
console.WriteLine(
$"bred child: {child.Alleles.Count} genes, "
+ $"vigor={childTraits.GetValueOrDefault("vigor"):0.###}, "
+ $"lifespan={childTraits.GetValueOrDefault("lifespan"):0.#}, "
+ $"variant={childTraits.GetValueOrDefault("variant"):0}"
);
}
}