Merge branch 'animals' into main: animal/zoology system (A1-A8 + serialization)

Brings the full animal foundation onto main and folds its new defs into the
Defs/ subfolder layout introduced on main:
- animal genes -> Defs/Genes/Animal.json (split out of genes.json)
- animals/bodies/hediffs/needs/thoughts -> own Defs/<Type>/ subfolders
- ProductMeat/Bone/Leather + bigger world presets auto-merged via rename detection
- PawnDef un-sealed (AnimalDef : PawnDef); def-location doc comments updated to subfolders
- engine pointer kept at main's newer 96e19c7 (only adds directional sun shadows)

Build + --check-content clean: 11 def types, 33 genes, 35 plants, 32 traits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-06-14 12:48:49 +03:00
co-authored by Claude Opus 4.8
25 changed files with 4348 additions and 51 deletions
+35
View File
@@ -0,0 +1,35 @@
{
"type": "Animal",
// Виды-животные (фаза A1): подтип Pawn (kind=animal) + базовый геном вида из общих Gene-дефов
// (см. genes.json). Особь при спавне получает аллели вокруг этих баз, фенотип — формулами генов.
// Пол, стадии роста, размножение, здоровье и поведение приходят в фазах A2+.
"defs": [
{
"defName": "Deer",
"label": "pawn.deer",
"kind": "animal",
"texture": "things/pawn/animal/deer/DeerFemale_east",
"maleTexture": "things/pawn/animal/deer/DeerMale_east",
"babyTexture": "things/pawn/animal/deer/DeerBaby_east",
"corpseTexture": "things/pawn/animal/deer/Dessicated_DeerFemale_east",
"body": "Quadruped",
"diet": ["plant"],
"spawnPer1000Cells": 2.5,
"genome": {
"GeneMaxBodySize": 1.5,
"GeneMetabolism": 1.0,
"GeneMoveSpeed": 1.2,
"GeneBloodVolume": 1.4,
"GeneVision": 1.3,
"GeneBrainSize": 0.45,
"GeneInsulation": 0.55,
"GeneFurColor": 0.45,
"GeneMaturityAge": 90,
"GeneLifespan": 360,
"GeneBreedingSeason": 2,
"GeneGestationDays": 30,
"GeneLitterSize": 1
}
}
]
}
+34
View File
@@ -0,0 +1,34 @@
{
"type": "Body",
// Анатомия видов (фаза A5): дерево частей/органов. Вклады в способности (capacities) по телу
// суммируются ≈1 у здоровой особи. maxHp умножается на размер тела особи при создании.
// Источников урона пока нет — части на полном HP, способности = 1; каркас под болезни/хищников.
"defs": [
{
"defName": "Quadruped",
"parts": [
{ "name": "torso", "coverage": 0.32, "maxHp": 40, "vital": true },
{ "name": "heart", "parent": "torso", "coverage": 0.02, "maxHp": 12, "vital": true,
"capacities": { "BloodPumping": 1.0 } },
{ "name": "lungLeft", "parent": "torso", "coverage": 0.03, "maxHp": 12,
"capacities": { "Breathing": 0.5 } },
{ "name": "lungRight", "parent": "torso", "coverage": 0.03, "maxHp": 12,
"capacities": { "Breathing": 0.5 } },
{ "name": "liver", "parent": "torso", "coverage": 0.03, "maxHp": 14, "vital": true },
{ "name": "stomach", "parent": "torso", "coverage": 0.03, "maxHp": 12,
"capacities": { "Digestion": 1.0 } },
{ "name": "head", "coverage": 0.1, "maxHp": 25 },
{ "name": "brain", "parent": "head", "coverage": 0.02, "maxHp": 12, "vital": true,
"capacities": { "Consciousness": 1.0 } },
{ "name": "eyeLeft", "parent": "head", "coverage": 0.015, "maxHp": 8,
"capacities": { "Sight": 0.5 } },
{ "name": "eyeRight", "parent": "head", "coverage": 0.015, "maxHp": 8,
"capacities": { "Sight": 0.5 } },
{ "name": "legFrontLeft", "coverage": 0.08, "maxHp": 15, "capacities": { "Moving": 0.25 } },
{ "name": "legFrontRight", "coverage": 0.08, "maxHp": 15, "capacities": { "Moving": 0.25 } },
{ "name": "legBackLeft", "coverage": 0.08, "maxHp": 15, "capacities": { "Moving": 0.25 } },
{ "name": "legBackRight", "coverage": 0.08, "maxHp": 15, "capacities": { "Moving": 0.25 } }
]
}
]
}
+51
View File
@@ -0,0 +1,51 @@
{
"type": "Gene",
// Гены животных: организм-агностичные гены зверя (их несёт геном животного). Тело/обмен/движение/
// чувства/мозг + пол (локус) и размножение. Признаки читают системы животных (рост, ИИ, здоровье).
"defs": [
{ "defName": "GeneMaxBodySize", "parent": "BaseNumericGene", "label": "gene.bodySize",
"default": 1.0, "min": 0.1, "max": 4.0, "tags": ["animal", "body"],
"effects": { "bodySize": "value" } },
{ "defName": "GeneMetabolism", "parent": "BaseNumericGene", "label": "gene.metabolism",
"default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "metabolism"],
"effects": { "metabolism": "value" } },
{ "defName": "GeneMoveSpeed", "parent": "BaseNumericGene", "label": "gene.moveSpeed",
"default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "movement"],
"effects": { "moveSpeed": "value" } },
{ "defName": "GeneBloodVolume", "parent": "BaseNumericGene", "label": "gene.bloodVolume",
"default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "health"],
"effects": { "bloodVolume": "value" } },
{ "defName": "GeneVision", "parent": "BaseNumericGene", "label": "gene.vision",
"default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "senses"],
"effects": { "vision": "value" } },
{ "defName": "GeneBrainSize", "parent": "BaseNumericGene", "label": "gene.brainSize",
"default": 0.45, "min": 0.0, "max": 1.0, "spread": 0.03, "tags": ["animal", "brain"],
"effects": { "brainSize": "value" } },
{ "defName": "GeneInsulation", "parent": "BaseNumericGene", "label": "gene.insulation",
"default": 0.5, "min": 0.0, "max": 1.0, "tags": ["animal", "temperature"],
"effects": { "insulation": "value" } },
{ "defName": "GeneFurColor", "parent": "BaseNumericGene", "label": "gene.furColor",
"default": 0.5, "min": 0.0, "max": 1.0, "spread": 0.06, "tags": ["animal", "morphology", "color"],
"effects": { "furHue": "value" } },
{ "defName": "GeneMaturityAge", "parent": "BaseNumericGene", "label": "gene.maturityAge",
"default": 90, "min": 1, "max": 400, "tags": ["animal", "lifecycle"],
"effects": { "maturityAge": "value" } },
// Пол как локус (фаза A3): аллели {X=0, Y=1}; самка XX, самец XY. Эффекта нет — пол читается из
// самих аллелей (наличие Y), не из выраженного значения. mutationChance 0 (X не мутирует в Y).
// Генерация особи-основателя задаёт пол явно (XX или XY), чтобы не возник невозможный YY.
{ "defName": "GeneSex", "kind": "Discrete", "label": "gene.sex",
"variants": 2, "variantWeights": [0.5, 0.5], "mutationChance": 0, "tags": ["animal", "sex"] },
// Размножение (фаза A4): сезон гона фиксирован по виду (0 весна … 3 зима), срок вынашивания и помёт.
{ "defName": "GeneBreedingSeason", "parent": "BaseNumericGene", "label": "gene.breedingSeason",
"default": 2, "min": 0, "max": 3, "spread": 0, "mutationChance": 0, "tags": ["animal", "reproduction"],
"effects": { "breedingSeason": "value" } },
{ "defName": "GeneGestationDays", "parent": "BaseNumericGene", "label": "gene.gestationDays",
"default": 30, "min": 1, "max": 200, "tags": ["animal", "reproduction"],
"effects": { "gestationDays": "value" } },
{ "defName": "GeneLitterSize", "parent": "BaseNumericGene", "label": "gene.litterSize",
"default": 1, "min": 1, "max": 12, "tags": ["animal", "reproduction"],
"effects": { "litterSize": "value" } }
]
}
+17
View File
@@ -0,0 +1,17 @@
{
"type": "Hediff",
// Хедифы — состояния организма (фаза A4: лёгкий каркас). Гон (Rut) навешивается сезонно на взрослых
// и поднимает половое влечение. Раны/болезни/возрастные эффекты со стадиями придут в A5/A6.
"defs": [
{ "defName": "Rut", "label": "hediff.rut" },
// Болезнь (фаза A6): прогрессирует, параллельно растёт иммунитет (гонка). Обычно иммунитет
// успевает победить (~3 дня), но больной зверь медленнее и слабее; слабые/невезучие гибнут.
{
"defName": "Fever", "label": "hediff.fever",
"initialSeverity": 0.05, "severityPerDay": 0.25, "immunityPerDay": 0.32,
"lethalSeverity": 1.0, "pain": 0.3, "ambientPerDay": 0.03,
"capMods": { "Moving": 0.6, "Consciousness": 0.85, "Digestion": 0.8 }
}
]
}
+20
View File
@@ -0,0 +1,20 @@
{
"type": "Need",
// Нужды как данные (фаза A2, рефактор расширяемости): добавить нужду виду = добавить запись здесь.
// kind=deplete убывает и утоляется действием; kind=drive растёт под хедифом (гон) и сбрасывается им.
// action — id поведения-исполнителя (реестр в коде). minBrain — гейт интеллектом (активен с A7):
// нужда, чей minBrain выше эффективного интеллекта особи (brainSize × Consciousness), в выбор ИИ не
// входит. Пороги — тиры мозга: 0.0 голод-рефлекс, 0.25 жажда (низший позвоночный), 0.40 сон/секс
// (зверь). У оленя мозг ~0.45: здоров — весь набор; повреждение мозга/болезнь роняют сознание →
// эффективный интеллект падает → первыми отключаются сон/спаривание (обратная связь A7).
"defs": [
{ "defName": "Hunger", "label": "need.hunger", "kind": "deplete", "action": "Eat",
"decayPerDay": 0.55, "feedPerDay": 4, "lethal": true, "minBrain": 0.0 },
{ "defName": "Thirst", "label": "need.thirst", "kind": "deplete", "action": "Drink",
"decayPerDay": 0.9, "feedPerDay": 8, "lethal": true, "minBrain": 0.25 },
{ "defName": "Rest", "label": "need.rest", "kind": "deplete", "action": "Sleep",
"decayPerDay": 0.7, "feedPerDay": 3, "lethal": false, "minBrain": 0.40 },
{ "defName": "Mating", "label": "need.mating", "kind": "drive", "action": "Mate",
"decayPerDay": 1.0, "risePerDay": 1.2, "risesUnder": "Rut", "minBrain": 0.40 }
]
}
+6 -1
View File
@@ -8,6 +8,11 @@
{ "defName": "ProductFiber", "label": "product.fiber", "kind": "material" },
{ "defName": "ProductBerry", "label": "product.berry", "kind": "food" },
{ "defName": "ProductAcorn", "label": "product.acorn", "kind": "food" },
{ "defName": "ProductMushroom", "label": "product.mushroom", "kind": "food" }
{ "defName": "ProductMushroom", "label": "product.mushroom", "kind": "food" },
// Животные продукты (фаза A5): добываются из трупа (разделка/гниение). Инвентарь/добыча — позже.
{ "defName": "ProductMeat", "label": "product.meat", "kind": "food" },
{ "defName": "ProductBone", "label": "product.bone", "kind": "material" },
{ "defName": "ProductLeather", "label": "product.leather", "kind": "material" }
]
}
+13
View File
@@ -0,0 +1,13 @@
{
"type": "Thought",
// Мысли настроения (фаза A8): событие вешает на зверя временный сдвиг настроения, затухающий за
// durationDays. Триггер события — код (реестр AnimalThoughts), сила/длительность/метка — данные.
// Настроение есть только у тира 4+ (мозг ≥ 0.40); непрерывный фон (голод/жажда/усталость/боль)
// считается отдельно, мысли — поверх него. Негативные событийные мысли (потеря детёныша) придут с
// родительской опекой (горизонт) — пока горе идёт через непрерывный фон.
"defs": [
{ "defName": "GaveBirth", "label": "thought.gaveBirth", "moodOffset": 0.25, "durationDays": 3 },
{ "defName": "Mated", "label": "thought.mated", "moodOffset": 0.15, "durationDays": 1.5 },
{ "defName": "QuenchedThirst", "label": "thought.quenchedThirst", "moodOffset": 0.1, "durationDays": 0.5 }
]
}
@@ -1,8 +1,8 @@
{
"type": "WorldPreset",
"defs": [
{ "defName": "Small", "label": "preset.small", "order": 0, "width": 80, "height": 50, "population": 40 },
{ "defName": "Medium", "label": "preset.medium", "order": 1, "width": 120, "height": 70, "population": 80 },
{ "defName": "Large", "label": "preset.large", "order": 2, "width": 180, "height": 110, "population": 140 }
{ "defName": "Small", "label": "preset.small", "order": 0, "width": 128, "height": 80, "population": 60 },
{ "defName": "Medium", "label": "preset.medium", "order": 1, "width": 200, "height": 120, "population": 110 },
{ "defName": "Large", "label": "preset.large", "order": 2, "width": 300, "height": 180, "population": 180 }
]
}
+35
View File
@@ -10,6 +10,9 @@
"inspect.tab.overview": "Overview",
"inspect.tab.genes": "Genes",
"inspect.tab.products": "Products",
"inspect.tab.needs": "Needs",
"inspect.tab.health": "Health",
"inspect.tab.mood": "Mood",
"inspect.stage": "Stage: {0} ({1}/{2})",
"inspect.growing": "Growth: {0:0}% to next stage",
"inspect.mature": "Fully grown",
@@ -31,6 +34,35 @@
"inspect.harvest": "Harvest: {0} ×{1:0.#}",
"inspect.fruit": "Fruit: {0} ×{1:0.#} ({2}) · ripe {3:0.#}",
"inspect.barren": "Bears no fruit",
"inspect.sex.male": "male",
"inspect.sex.female": "female",
"inspect.animal.sex": "Sex: {0} · generation {1}",
"inspect.animal.pregnant": "Pregnant: {0:0.0} d to birth",
"inspect.needline": "{0}: {1:0}%",
"inspect.health.blood": "Blood: {0:0}% · pain: {1:0}%",
"inspect.health.caps": "— Capacities —",
"inspect.health.cap": "{0}: {1:0}%",
"inspect.health.hediffs": "— Conditions —",
"inspect.health.hediffline": "{0}: severity {1:0}%",
"inspect.health.none": "Healthy, no wounds or illness",
"inspect.mood.value": "Mood: {0:0}%",
"inspect.mood.none": "No mood (primitive brain)",
"inspect.mood.thoughts": "— Thoughts —",
"inspect.mood.thoughtline": "{0}: {1}",
"inspect.mood.calm": "Calm, nothing on its mind",
"animalstage.baby": "baby",
"animalstage.juvenile": "juvenile",
"animalstage.adult": "adult",
"animalstage.senior": "senior",
"need.hunger": "hunger",
"need.thirst": "thirst",
"need.rest": "rest",
"need.mating": "mating",
"cap.consciousness": "consciousness",
"cap.moving": "moving",
"cap.sight": "sight",
"hediff.rut": "rut",
"hediff.fever": "fever",
"inspect.hint": "LMB — select · RMB/Esc — clear",
"hud.paused": "PAUSED",
"menu.title": "LittleSim",
@@ -123,6 +155,9 @@
"pawn.wolf": "wolf",
"pawn.muffalo": "muffalo",
"pawn.squirrel": "squirrel",
"thought.gaveBirth": "gave birth",
"thought.mated": "mated",
"thought.quenchedThirst": "drank its fill",
"net.hud": "Multiplayer: {0} | beings: {1} | Esc — back to menu",
"net.connecting": "connecting…",
"net.connected": "connected",
+35
View File
@@ -10,6 +10,9 @@
"inspect.tab.overview": "Обзор",
"inspect.tab.genes": "Гены",
"inspect.tab.products": "Продукты",
"inspect.tab.needs": "Нужды",
"inspect.tab.health": "Здоровье",
"inspect.tab.mood": "Настроение",
"inspect.stage": "Стадия: {0} ({1}/{2})",
"inspect.growing": "Рост: {0:0}% до следующей стадии",
"inspect.mature": "Полностью выросло",
@@ -31,6 +34,35 @@
"inspect.harvest": "Сбор: {0} ×{1:0.#}",
"inspect.fruit": "Плоды: {0} ×{1:0.#} ({2}) · зрелых {3:0.#}",
"inspect.barren": "Не плодоносит",
"inspect.sex.male": "самец",
"inspect.sex.female": "самка",
"inspect.animal.sex": "Пол: {0} · поколение {1}",
"inspect.animal.pregnant": "Беременна: {0:0.0} дн до родов",
"inspect.needline": "{0}: {1:0}%",
"inspect.health.blood": "Кровь: {0:0}% · боль: {1:0}%",
"inspect.health.caps": "— Способности —",
"inspect.health.cap": "{0}: {1:0}%",
"inspect.health.hediffs": "— Состояния —",
"inspect.health.hediffline": "{0}: тяжесть {1:0}%",
"inspect.health.none": "Здоров, ран и болезней нет",
"inspect.mood.value": "Настроение: {0:0}%",
"inspect.mood.none": "Настроения нет (примитивный мозг)",
"inspect.mood.thoughts": "— Мысли —",
"inspect.mood.thoughtline": "{0}: {1}",
"inspect.mood.calm": "Спокоен, особых мыслей нет",
"animalstage.baby": "детёныш",
"animalstage.juvenile": "подросток",
"animalstage.adult": "взрослый",
"animalstage.senior": "старый",
"need.hunger": "голод",
"need.thirst": "жажда",
"need.rest": "отдых",
"need.mating": "влечение",
"cap.consciousness": "сознание",
"cap.moving": "движение",
"cap.sight": "зрение",
"hediff.rut": "гон",
"hediff.fever": "лихорадка",
"inspect.hint": "ЛКМ — выбрать · ПКМ/Esc — снять",
"hud.paused": "ПАУЗА",
"menu.title": "LittleSim",
@@ -123,6 +155,9 @@
"pawn.wolf": "волк",
"pawn.muffalo": "муффало",
"pawn.squirrel": "белка",
"thought.gaveBirth": "родила потомство",
"thought.mated": "спарилась",
"thought.quenchedThirst": "напилась вволю",
"net.hud": "Мультиплеер: {0} | жителей: {1} | Esc — в меню",
"net.connecting": "подключение…",
"net.connected": "подключено",