Files
owniverse/simulation_rules.md
T
Kirill 26347fca30 Add comprehensive civilization evolution tests and enhance civilization state management
- Introduced a new test script for civilization evolution (`test_civilization_evolution.gd`) to validate the evolution mechanics, including population dynamics, ethical transitions, and war impacts.
- Updated `README.md` to include instructions for running the new civilization evolution tests.
- Modified `test_civilization_state.gd` to accommodate changes in civilization rules and ensure proper validation of ethical stages.
- Enhanced `test_descriptions.gd` to check for accurate population counters and state validation.
- Adjusted `test_life.gd` to reflect updates in life version management.
- Improved `civilization_state.gd` to include habitat budget calculations and transition management.
- Added `civilization_evolution.gd` to handle the logic for civilization evolution, including population drift, warfare, and colonization mechanics.
- Updated `owniverse.gd` and `owniverse_entity.gd` to integrate new evolution logic and ensure proper initialization of entities.
2026-09-16 19:54:47 +03:00

124 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Эволюция звёзд Owniverse.GI
Механики перенесены из Owniverse.U с согласованными изменениями GI: постепенные партии, детерминированные дробные остатки, уязвимость цивилизаций до C1.2 и передача выживших планет преемнику. Баланс таблицы GI сохраняется.
## Порядок расчёта
1. Накопить игровое время; обработать новые десятые доли года.
2. Рассчитать производство существующих объектов за интервал с учётом их постепенного исчезновения; выполнить автоматическое создание звёзд и их планет.
3. Для очередного поколения определить долю заканчивающих жизнь звёзд. Применить локальное разрушение их планет до списания партий.
4. Снять целые объекты из партий, рассчитать основные и альтернативные выходы с накоплением дробей.
5. Передать выжившие планеты полученным звёздам/остаткам. Если преемников несколько, распределить по их фактическим количествам; если преемника нет — освободить. Остальные связанные объекты используют существующие правила GI.
6. Создать партии преемников. Учесть производство новорождённых за оставшуюся часть длинного шага, включая излучение короткоживущих сверхновых.
7. Применить суммарный бласт поколения; повторять обработку поколений, пока в интервале остаются переходы.
8. Пересчитать группы и опубликовать состояние.
## Постепенные партии
Окно рождения шириной `w = lifespan / 40` при `lifespan > 10`, иначе `w = lifespan`. Окно превращения сдвинуто на `lifespan`. При частичном списании:
```
expected = remainder + (remaining_count - remainder) * elapsed / remaining_window
converted = floor(expected)
remainder = expected - converted
```
Конец окна списывает остаток. Переход не уничтожает всю партию в начале окна. Начала и длительности сохраняют модель GI, включая годовую длительность событий SN/GRB.
## Планеты
При ручном и автоматическом создании звёзд:
```
expected = stars_created * planet_amount * planet_chance * metallicity + remainder
planets_created = floor(expected)
remainder = expected - planets_created
```
Остаток независим для каждой пары звезда/планета и сохраняется. Планеты сразу связаны со звездой. Эволюционный переход сам по себе не создаёт новую планетную систему. Шансы планет в таблице — доли, а проценты альтернативных выходов звёзд делятся на 100.
## Среда: адаптация формул Unity к состоянию GI
GI не хранит накопленные счётчики первичной материи Unity. Поэтому `stellar_environment()` вычисляет среду из текущего физического состава, включая связанные объекты, без суммирующих групп интерфейса. Это приближение для баланса GI, а не побитовое воспроизведение Unity.
- `M` — свободные и связанные H/He/Met плюс табличная масса конкретных объектов и масса SMBH.
- `V` — физическое S плюс табличный объём объектов и `voids * 1e22`.
- `Z = max(0, 0.4 * ln(100 * free_Met / M + 0.11) + 0.88)`; при `M = 0` металличность нулевая.
- `B = 65536 * f(M)`, где `f(0)=1`, `f(M)=M^0.1` при `0<M<1e10`, иначе `10`.
- `density = 1.23456e-7 * sqrt(B + M) / max(1, V)^(1/6)`.
- `blast_factor = clamp(free_S / V, 0, 1)`; при нулевом объёме `1`.
Система сил Unity и планетные бонусы в GI пока не перенесены; здесь используются нейтральные множители 1. Металличность для производства фиксируется до расходования ресурсов на звёзды. Среда бласта фиксируется для поколения до добавления его продуктов.
## Разрушение и бласты
Локальное воздействие: `ratio = dying_stars / physical_stars`, без множителя плотности.
Бласт: `hits = floor(power * blast_factor + saved_remainder)`. Распределение экспозиции между типами звёзд, имеющими планетные системы в таблице, пропорционально их физическому количеству. Для типа: `ratio = hits * star_share / physical_stars * density`.
Для каждого связанного типа планет накапливается `held_planets * min(1, ratio)`. Уничтожается целая часть, не больше существующего количества. Остатки локального воздействия и бластов раздельны. Это позволяет слабым воздействиям работать при постепенной эволюции.
Уровень 1 превращает только `blastability=1` в RP (HP, EON, цивилизации до C1.2). C1.3 и выше защищены от этого уровня. Уровень 2 уничтожает все планеты, включая защищённые цивилизации, без создания RP. Уничтоженные объекты удаляются из жизненных партий, чтобы не возникать заново.
`blast` в выходе — событие, а не предмет. Поле `blast` сущности повторно не суммируется с выходом `blast:N`.
## Границы этапа
Рассчитываются агрегаты по типам, а не отдельные звёздные системы; конкретная принадлежность каждой планеты отдельной звезде не моделируется. Распределения целых объектов детерминированы. Порядок внутри длинного шага — по поколениям, поэтому нелинейное воздействие бластов и среды не обязано совпадать с серией более коротких шагов. Эволюция HP и эонов подключена ниже; эволюция цивилизаций и бонусы структур описаны ниже. Глобальная система сил остаётся отдельной механикой.
Проверки: `tests/test_time.gd`, `tests/test_stellar_rules.gd`. Сохранения игрока тестами не затрагиваются.
## Первичная жизнь: HP → EON1 → … → EON5 → C0.0
Правила хранятся в `data/life_rules.txt`, исходные сроки и коэффициенты взяты из Unity `civs.txt`. В каждой обработанной части партии:
- прогресс: `count * progress + carry_progress`;
- деградация: `count * degradation + carry_degradation`;
- остальная жизнь остаётся на прежней стадии и получает новую партию для следующей попытки.
Прогресс и деградация округляются вниз с сохранением остатков. Если оба накопленных исхода конкурируют за последнюю планету, распределяются только существующие объекты, а неиспользованный остаток переносится на следующую попытку. Деградация распределяется по весам `fall`; знаковые ошибки распределения также сохраняются.
Для всех шести стадий базовые доли за попытку — `progress=0.00025`, `degradation=0.0025`. Интервалы HP/EON1/EON2/EON3/EON4/EON5: 5 млн, 10 млн, 10 млн, 1 млн, 1 млн, 500 тыс. лет. Используются постепенные окна GI шириной `span / 40`. Случайные множители Unity не применяются; агрессия, порядок и просвещение пока имеют нейтральное влияние.
HP деградирует в RP. У эонов возможен откат к предыдущим стадиям по таблице. RP не развивается сам. C0.0 и C0.1 также развиваются: период 2000 лет, прогресс 0.0175, деградация 0.025. Переходы C0.0 → C0.1 → C0.2, откат C0.0 → EON5 и C0.1 → C0.0. Развитие C0.2 и выше подключено через этические правила. Конфликт civ_bonus устранён повторным импортом: бонусы структур совпадают с Unity. Для существующих этических цивилизаций пользователь выбрал равномерное распределение между шестью этиками с детерминированным целым остатком.
Переходы сохраняют количество планет и их хозяев, включая передачу преемнику звезды и разрушение бластом. Повторная попытка той же стадии не увеличивает статистику созданных объектов. Партии новых планет регистрируются при создании; недостающие партии старых HP/эонов — однократно при загрузке с текущим возрастом вселенной, без выдумывания их прошлого возраста. Состояние содержит `life_version=2` (версия 1 также загружается) и `life_remainders`.
Миграция версии жизни 1 → 2 добавляет только недостающие партии C0.0/C0.1, сохраняя уже существующие партии HP и эонов.
## Этические и космические цивилизации
`civilization_rules.txt` содержит 43 стадии по шесть этик из Unity. Они загружаются в `Global.CivilizationRules` и участвуют в расчёте партий. После C4.4 следует Ct: конечная стадия без новых жизненных партий.
Состояние `ethics[stage][ethic]` хранит целые количества. Для существующих цивилизаций без этик количество распределяется поровну в порядке m, l, w, d, c, b; остаток распределяется по одному в этом порядке. Существующее распределение сохраняется. При внешних потерях оно пропорционально сокращается.
Цивилизации с непустым `home` (C2.0–C4.4) освобождаются от прежних привязок без изменения общего количества. Общий механизм переходов больше не переносит планетную привязку на такого преемника. Структуры назначаются отдельно в `civilization_homes`; при возвращении к планетным стадиям цивилизации размещаются у имеющихся карликовых звёзд.
Правило среды согласовано: число космических цивилизаций ограничено звёздным ресурсом. Для стадии `i` расход ёмкости — `population[i] * max(1, Stars[i])`. Каждое семейство `Home` имеет общий бюджет для всех использующих его стадий; звёзды внутри структур также учитываются, но повторно не суммируются. SMBH учитывается по суммарной массе в эквиваленте звёзд, согласно решению пользователя.
Переход переиспользует резерв исходной стадии. При нехватке ёмкости неподдержанные переходы остаются на исходной стадии. Лимит применяется к общему механизму выходов партий и ручному созданию; расчёт прогресса C0.2+ использует тот же бюджет.
При загрузке и после эволюционных поколений избыток деградирует последовательно до поддерживаемой стадии. Приоритет получают существующие более развитые цивилизации; остаток бюджета достаётся младшим. Деградация переносит количество и этики, сокращает старые партии и регистрирует новые, не уничтожая цивилизации. C2.0 при избытке становится C1.9 и распределяется по имеющимся звёздам-карликам. Если карликов нет, C1.9 остаётся свободной — отсутствующая звезда не создаётся. Планетные стадии до C2.0 не расходуют отдельную звёздную ёмкость: у одной звезды могут быть несколько планет.
Резерв ёмкости логический: звёзды не расходуются и продолжают производить ресурсы. Общий бюджет пересчитывается из физических количеств, отдельная копия бронирований в сохранении не хранится.
### Расчёт поколения C0.2–C4.4
1. Из истёкшей части партии пропорционально выбираются представители шести этик. Для каждой этики читаются `progress` и `degradation`; целые исходы получаются с сохранением дробных остатков. Неудавшийся из-за лимита переход возвращается на исходную стадию.
2. Прогресс ведёт на следующую стадию; деградация распределяется по весам `fall` конкретной этики. Повторные попытки не увеличивают статистику созданных цивилизаций.
3. При флаге `fights` рассчитываются войны. Веса исходов — 1:2:3:3, доли прогресса победителей — 0:0.25:0.5:0.75; первый исход деградирует атакующих. Потери противников — 2:1:1.5:2 на войну. Два последних исхода дают 10 и 30 единиц побочного ущерба предыдущей стадии. Выбор участников ограничен живой популяцией, включая ещё не сработавшие партии; их партии сокращаются вместе с населением.
4. Для обычного дрейфа веса своей/противоположной/каждой другой этики равны 196/0/1. Дипломатия умножает исходные численности на `diplomacy_rate`, затем нормирует к прежней численности. Флаг дипломатии действует на остающихся на стадии. При переходе в Ct этика сохраняется без дрейфа.
5. При флаге `colonizes` создаются колонии на две стадии ниже отправителя. Цели — существующие GG, AB, RP, HP; колонизация заменяет цель и сохраняет её звёздную привязку. Веса дрейфа колонистов — 960/4/9. Исходная цивилизация не расходуется. Новая партия начинается в текущий игровой момент.
6. После применения переходов пересчитываются этики, поклонение (`Σ population × worship`), бласты и ограничения среды. Число операций зависит от числа типов и партий, а не от числа цивилизаций.
Окна исходных партий сохраняют время переходов; несколько частей одного типа обрабатываются агрегированно между минимальным и максимальным временем. Побочный ущерб неистёкшим партиям применяется в текущий момент. Все остатки округления сохраняются в `civilization_remainders`, счётчики — в `civilization_stats`.
### Структуры и периоды
Прямой `claim` задаёт структуру стадии и норму 1; каждая промежуточная стадия умножает норму на 10 до следующего `claim`. Начиная с C3.0 требуется соответствующий запас структур, общий для использующих его стадий. При потере запаса избыток деградирует. Этот бюджет действует одновременно со звёздным.
Размещение выбирает структуры в порядке убывания `civ_bonus`, начиная с соответствующего стадии `claim`. Прямое размещение ограничено числом структур; остальные разрешённые структуры при наличии дают общий бонус, как в Unity. Период новых партий равен `span / средневзвешенный civ_bonus`, для неразмещённой части множитель равен 1. Уже назначенные сроки партий не переписываются при изменении бонуса.
`life_version = 3` добавляет часы существующим C0.2+ с момента загрузки; старые часы HP, эонов и начальных цивилизаций сохраняются. Ct не получает часы. Миграция выполняется однократно. Глобальные силы и их модификаторы не входят в этот перенос: используются нейтральные множители 1.