Implement short-lived stellar event handling and optimize batch processing; add tests for new functionality

This commit is contained in:
Kirill
2026-09-22 22:50:54 +03:00
parent a3d24114a1
commit d6fd40969f
11 changed files with 238 additions and 41 deletions
+13 -1
View File
@@ -27,6 +27,18 @@
## Постепенные партии
### Короткоживущие звёздные события внутри длинного шага
Для SN, DSN, BSN, HN и GRB-событий полностью завершившиеся окна рождения не создают отдельные словари партий. Их целые количества суммируются в очередь завершений текущего расчёта; обычные партии сохраняются только для окон, срок которых ещё не закончился. Состояние этой очереди не записывается в сохранение: она полностью обрабатывается до публикации нового состояния.
Окно завершено, если `window_end + lifespan ≤ to_year`. Его доля количества рассчитывается прежним методом разности накопленных целых значений. Для производства пространства интеграл исчезновения вычитается по окнам в прежнем порядке, чтобы сохранить округление. Здесь остаётся лёгкий арифметический проход по окнам, но отсутствуют создание, копирование, сортировка и последующая обработка тысяч временных словарей.
Ресурсы, остатки звёзд и бласты от завершившейся части применяются на следующем поколении расчёта, как раньше. Поэтому сохраняются порядок передачи привязок, среда бластов и ограничения цивилизаций. Ускорение допускается только для событий группы `SNGRBB` с линейным выходом и без преемников с ненулевым сроком жизни. При изменении таблиц остальные случаи автоматически используют обычный путь. Сроки жизни и ширина окон не увеличиваются, формат сохранения не меняется.
На сохранении возраста 140,55 млн лет, при шестой скорости и шаге 1/60 секунды: максимальное временное число партий SN/GRB уменьшилось с 1668 до 2; средний расчёт кадра без отрисовки — примерно с 15 до 10 мс. За 120 шагов результаты старого и нового путей совпали по всем полям состояния. Эти значения характеризуют конкретное сохранение, а не гарантированную частоту кадров на всех устройствах.
### Общие окна рождения и эволюции
Окно рождения шириной `w = lifespan / 40` при `lifespan > 10`, иначе `w = lifespan`. Окно превращения сдвинуто на `lifespan`. При частичном списании:
```
@@ -72,7 +84,7 @@ GI не хранит накопленные счётчики первичной
Уровень 1 превращает только `blastability=1` в RP (HP, EON, цивилизации до C1.2). C1.3 и выше защищены от этого уровня. Уровень 2 уничтожает все планеты, включая защищённые цивилизации, без создания RP. Уничтоженные объекты удаляются из жизненных партий, чтобы не возникать заново.
`blast` в выходе — событие, а не предмет. Поле `blast` сущности повторно не суммируется с выходом `blast:N`.
Единственный источник мощности — поле `blast` сущности: `power = expired_count × max(0, entity.blast)`. При `blast = 0` внешнего воздействия нет. Старые вхождения `blast:N` в `output` игнорируются, включая альтернативные выходы; двойного суммирования нет. Внутренний выход `blast` остаётся событием, а не предметом. `destroy_level` независимо задаёт уровень локального разрушения у умирающего объекта; внешние бласты всегда действуют на уровне 1.
## Границы этапа