Files
owniverse/simulation_rules.md
T
Kirill 5f3875bc14 Add life rules and implement tests for civilization and life states
- Introduced a new file `life_rules.txt` to define life progression and degradation rules.
- Created `test_civilization_state.gd` to validate the functionality of civilization rules and ethics.
- Added `test_life.gd` to test life evolution, including initialization, batch processing, and state validation.
- Implemented `civilization_state.gd` to manage civilization ethics and space civilization detachment logic.
- Ensured all tests check for expected outcomes and validate state integrity after operations.
2026-09-15 23:05:05 +03:00

13 KiB

Эволюция звёзд 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 и эонов подключена ниже; развитие цивилизаций после появления C0.0, их бонусы и силы остаются отдельными этапами переноса.

Проверки: 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, но расчёт их прогресса, деградации, войн и колонизации ещё не подключён.

Состояние ethics[stage][ethic] хранит целые количества. Для существующих цивилизаций без этик количество распределяется поровну в порядке m, l, w, d, c, b; остаток распределяется по одному в этом порядке. Существующее распределение сохраняется. При внешних потерях оно пропорционально сокращается.

Цивилизации с непустым home (C2.0–C4.4) освобождаются от прежних привязок без изменения общего количества. Общий механизм переходов больше не переносит планетную привязку на такого преемника. Назначение структур и обратное размещение при деградации ещё не подключены.

Открытое правило среды: Unity читает Stars, но не использует эту норму в ограничении количества цивилизаций. Требуется выбор между фактическим поведением Unity и количественным ограничением доступными звёздами.