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>
10 KiB
Гены как фундамент
Гены — основополагающая система LittleSim, общая для растений, животных и людей, а не
структура под один вид. Геном — переменного состава, поэтому возможны произвольные гибриды
(хоть человек с генами растения). Поведение организма не зашито в код, а вычисляется из генов
формулами через слой признаков. Этот документ описывает модель и порядок реализации (фазы G1–G5).
Дизайн потребителя-растений — в растения.md; гены заменяют его жёсткий PlantGenome.
Ключевые понятия
GeneDef— отдельный деф на ген, организм-агностичный: id, тип (числовой/дискретный/флаг), диапазон/дефолт/разброс (для генерации особи), доминантность (дискретные — доминант/рецессив; числовые — смешение), мутации (вероятность/величина), теги/категория и эффекты — вклады гена в признаки через формулы.- Геном — управляемый объект на сущности: набор генов переменного состава (id гена → пара аллелей, диплоид). Поддерживает добавление/удаление/смешивание генов → гибриды. Скрещивание — помейозно по объединению генов родителей + мутация. Сериализуется в сейв.
- Признаки (traits) — фенотип, вычисляемый из генома + среды:
growthSpeed,fruitYield, продукт добычи, цвет, период плодоношения, жизнь, расселение… Системы читают готовые признаки, а не гены напрямую. Поэтому одна система плодоношения работает и для дерева, и для человека с «плодовым» геном; и так «учитываются гены во всех расчётах». - Движок формул — свой (без внешних библиотек) вычислитель выражений в дефах: числа, операции,
функции (
min/max/clamp/lerp/pow/exp/…), переменные (значения генов/среды/других признаков). Парсинг → AST → компиляция в делегат; детерминизм; покрыт тестами. - Регэкспы в дефах — три применения: выбор/группировка генов по шаблону имени в формулах
(напр. «сумма всех
leaf_*»); правила/патчи контента (применять патч ко всем дефам по шаблону); валидация строковых полей дефов при загрузке.
Модель
GeneDef (данные) ──┐
├─► Геном особи (id гена → аллели) ──► [формулы эффектов + среда] ──► Признаки ──► Системы
GeneDef.effects ───┘ (движок формул) (traits)
- Генерация особи: из базового набора генов вида (деф организма ссылается на
GeneDefс базовыми значениями/разбросом) создаются аллели; всё сидируетсяRandomмира — детерминизм. - Признаки кэшируются на особи; пересчитываются при изменении генома (статические признаки) и/или по среде (динамические — напр. итоговая скорость роста зависит ещё от света/температуры в точке).
- Скрещивание: для каждого гена потомок берёт по аллелю от каждого родителя (если ген есть у обоих;
если только у одного — наследуется с шансом), затем мутация по
GeneDef.
Фазы
Каждая фаза — отдельным планом (план → утверждение → коммит), как остальные работы.
G1 — движок формул (Core)
Самодостаточный keystone, нужен всему остальному.
- Свой вычислитель выражений: лексер → парсер → AST → компиляция в
Func<context, float>. Поддержка: числа,+ - * / %, скобки, унарный минус, сравнения/тернарник (для условий вроде «плодоносит ли»), функции (min,max,clamp,lerp,pow,exp,floor,round,abs,…), переменные по имени. - Контекст переменных — провайдер
name → value(значения генов, среды, признаков). - Детерминизм, без аллокаций при вычислении (компиляция один раз). Тесты на парсинг/вычисление/ошибки.
- Локация:
engine/src/MrGameEng.Core(илиMrGameEng.Content, ближе к дефам) — уточнится в плане.
G2 — фундамент генов (движок + контент-слой)
GeneDef(тип дефа) и реестр генов; парсинг эффектов как формул (зависит от G1).- Управляемый
Genome(компонент-объект): набор генов с аллелями; генерация из набора вида; скрещивание + мутация; (де)сериализация. - Слой признаков: вычисление
traitsиз генома и эффектов (формулы) + провайдера среды; кэш и инвалидация. APITrait(name)для систем. - Без растительной специфики — общая машинерия для любых организмов.
G3 — миграция растений на гены/признаки
- Рост/размножение/жизненный цикл растений читают признаки (
growthSpeed, оптимум/толерантность света/температуры/почвы, жизнь, расселение, самоопыление, мутации) вместо полей фиксированногоPlantGenome. plants.json/GeneDef: набор генов вида описывается данными; убираем жёсткийPlantGenome/Breed.- Поведение эквивалентно текущему (фазы A–D), но теперь полностью data-driven через гены/формулы.
- Сейв популяции хранит динамический геном.
G4 — генный контент растений
Новые механики как признаки + небольшие системы:
- Плодоношение: признаки «плодоносит ли» (флаг), тип плода (дискретный ген → продукт-деф), число плодов, период/сезон плодоношения; система создаёт плоды у зрелых растений.
- Добыча: что даёт при сборе (дерево/грибы/трава/…) — дискретный ген → продукт; количество — числом.
- Цвета/морфология: тинт и вариации спрайта из генов; периоды и скорость роста — уже признаки.
G5 — регэкспы и контент-инструменты
- Группировка генов по шаблону имени в формулах/эффектах (часть G1/G2, выносится сюда как фича).
- Контент-патчи: применять патч-деф ко всем дефам, чьё имя подходит под регэксп (массовые правки модами поверх Core).
- Валидация: проверка строковых полей дефов (id/ключи/форматы) по шаблонам при загрузке мода.
Позже — животные и люди, гибриды
Та же машинерия генома/признаков переиспользуется для животных и людей; гибриды — добавлением
«чужих» генов в геном (напр. фотосинтез человеку «растительным» геном, дающим признак, который
читает существующая система). Никаких спец-веток в коде — только новые GeneDef и формулы.
Принципы
- Гены — источник истины; формулы — мост; признаки — то, что читают системы. Системы не знают о конкретных видах, только о признаках.
- Data-driven: новый ген/эффект/признак — это деф и формула, а не код.
- Детерминизм: генерация, скрещивание и мутации — на сидированном
Random; формулы чисты. - Движок vs игра: движок даёт формулы,
GeneDef, геном, вычисление признаков, регэксп-инструменты; игра задаёт конкретные гены/формулы/системы-потребители (плодоношение, добыча) данными и кодом.