diff --git a/Mods/Core/Defs/genes.json b/Mods/Core/Defs/genes.json index 4252775..247801b 100644 --- a/Mods/Core/Defs/genes.json +++ b/Mods/Core/Defs/genes.json @@ -59,6 +59,12 @@ "default": 0.33, "min": 0, "max": 1, "spread": 0.04, "tags": ["morphology", "color"], "effects": { "leafHue": "value" } }, + // Производный ген: признак собирается группировкой по регэкспу — сумма всех генов-толерантностей + // (демонстрация gsom-функций фазы G5). Собственное значение гена не используется. + { "defName": "GeneHardiness", "parent": "BaseNumericGene", "label": "gene.hardiness", + "default": 0, "min": 0, "max": 1, "spread": 0, "mutationChance": 0, "tags": ["derived"], + "effects": { "hardiness": "gsum('Gene.*Tolerance')" } }, + // Дискретный ген морфы: вариант 0 доминирует, 1 (рецессивный) виден только в гомозиготе. { "defName": "GeneMorph", "kind": "Discrete", "label": "gene.morph", "variants": 2, "variantWeights": [0.82, 0.18], "mutationChance": 0.05, "tags": ["morphology"], diff --git a/Mods/Core/Defs/patches.json b/Mods/Core/Defs/patches.json new file mode 100644 index 0000000..81677c8 --- /dev/null +++ b/Mods/Core/Defs/patches.json @@ -0,0 +1,8 @@ +{ + "type": "Patch", + // Контент-патчи (фаза G5): применяются ко всем дефам типа defType, чьё имя подходит под regex match, + // проставляя поля set. Демонстрация: даём кустам древесину при сборе (веточки). + "patches": [ + { "defType": "Plant", "match": "Bush.*", "set": { "harvestProduct": "ProductWood" } } + ] +} diff --git a/engine b/engine index ead2251..d044caf 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit ead22517ee7a3da4d5d80c29f4061fc36f69089f +Subproject commit d044cafad93177e0fbffb79872bde12afcf03f9c diff --git a/src/LittleSim/Content/GameContent.cs b/src/LittleSim/Content/GameContent.cs index 2ec2b73..9fef03d 100644 --- a/src/LittleSim/Content/GameContent.cs +++ b/src/LittleSim/Content/GameContent.cs @@ -62,6 +62,14 @@ public sealed class GameContent defs.RegisterType("Plant"); defs.RegisterType("Pawn"); defs.RegisterType("WorldPreset"); + // Валидация имён при загрузке (фаза G5): гены и продукты обязаны иметь префикс типа. + defs.RegisterValidator("Gene", "defName", "^Gene", "gene defName must start with 'Gene'"); + defs.RegisterValidator( + "Product", + "defName", + "^Product", + "product defName must start with 'Product'" + ); defs.Load(mods); var languages = new LanguageManager(defaultLanguage: "ru"); diff --git a/src/LittleSim/Program.cs b/src/LittleSim/Program.cs index 597fc93..e663265 100644 --- a/src/LittleSim/Program.cs +++ b/src/LittleSim/Program.cs @@ -1,8 +1,35 @@ +using LittleSim.Content; using LittleSim.Scenes; using Microsoft.Xna.Framework; using MrGameEng.Core; +using MrGameEng.Genetics; using MrGameEng.Host; +// Контент-линт без окна/GPU: грузит моды/дефы (патчи и валидаторы тоже), компилирует формулы генов +// (включая группировку gsum) и выходит. Удобно для CI. +if (args.Contains("--check-content")) +{ + try + { + var content = GameContent.Load(); + var genes = content.Defs.All(); + var registry = genes.ToDictionary(g => g.DefName, g => g, StringComparer.Ordinal); + var traits = Phenotype.Compute(Genome.Generate(genes, new Random(1)), registry); + Console.WriteLine( + $"content ok: {content.Defs.TypeKeys.Count} def types, {genes.Count} genes, " + + $"{content.Defs.NamesOf("Plant").Count} plants, {traits.Count} traits " + + $"(hardiness={traits.GetValueOrDefault("hardiness"):0.##})" + ); + return; + } + catch (Exception error) + { + Console.Error.WriteLine($"content FAILED: {error.Message}"); + Environment.Exit(1); + return; + } +} + // Контент Core-мода грузится уже в окне — на загрузочном экране (BootScene), в фоне. using var host = new GameHost( new GameHostOptions