5ea65a7e9b
- Updated export path and version code in export_presets.cfg - Changed project version in project.godot to 0.7.0 - Expanded simulation rules in simulation_rules.md to clarify resource management - Improved testing framework in tests/README.md to include new civilization budget checks - Added new tests for batch boundaries and civilization state transitions - Enhanced civilization_state.gd with shared budget and transition logic - Refactored owniverse.gd to enforce capacity during life batch initialization
104 lines
15 KiB
Markdown
104 lines
15 KiB
Markdown
# Эволюция звёзд 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) освобождаются от прежних привязок без изменения общего количества. Общий механизм переходов больше не переносит планетную привязку на такого преемника. Назначение структур и обратное размещение при деградации ещё не подключены.
|
|
|
|
Правило среды согласовано: число космических цивилизаций ограничено звёздным ресурсом. Для стадии `i` расход ёмкости — `population[i] * max(1, Stars[i])`. Каждое семейство `Home` имеет общий бюджет для всех использующих его стадий; звёзды внутри структур также учитываются, но повторно не суммируются. SMBH учитывается по суммарной массе в эквиваленте звёзд, согласно решению пользователя.
|
|
|
|
Переход переиспользует резерв исходной стадии. При нехватке ёмкости неподдержанные переходы остаются на исходной стадии. Лимит применяется к общему механизму выходов партий и ручному созданию; это само по себе не включает пока отсутствующий расчёт прогресса C0.2+.
|
|
|
|
При загрузке и после эволюционных поколений избыток деградирует последовательно до поддерживаемой стадии. Приоритет получают существующие более развитые цивилизации; остаток бюджета достаётся младшим. Деградация переносит количество и этики, сокращает старые партии и регистрирует новые, не уничтожая цивилизации. C2.0 при избытке становится C1.9 и распределяется по имеющимся звёздам-карликам. Если карликов нет, C1.9 остаётся свободной — отсутствующая звезда не создаётся. Планетные стадии до C2.0 не расходуют отдельную звёздную ёмкость: у одной звезды могут быть несколько планет.
|
|
|
|
Резерв ёмкости логический: звёзды не расходуются и продолжают производить ресурсы. Общий бюджет пересчитывается из физических количеств, отдельная копия бронирований в сохранении не хранится.
|