Модули Owniverse
Первый этап разделения Owniverse выделяет два модуля:
quantity_math.gd: нормализация положительных весов, ограниченное целочисленное распределение методом наибольших остатков, распределение с накоплением ошибки округления, накопление дробного выпуска и минимальный целый размер производственной партии.entity_catalog.gd: загрузка определений, индексы групп и событий, списки автоматических производителей и разблокируемых сущностей.
Математика не обращается к дереву сцены, Global или Owniverse. Методы накопления изменяют переданный словарь остатков; остальные методы возвращают результат. Для распределения split количество должно быть целым, веса — неотрицательными. Равные остатки разрешаются по строковому ID. Количества считаются целочисленно в диапазоне E27, дробные остатки хранятся в float. Модуль арифметики описывает допуск дробных переносов, точные отношения и формат сохранения 4.
Каталог получает словарь исходных строк через load_definitions(rows), вызываемый один раз для нового экземпляра. Конструктор OwniverseEntity по-прежнему использует настройки Global. Каталог не хранит количества, партии или состояние интерфейса. Определения пока остаются Node: освобождает их владелец мира, как до рефакторинга.
Метод members(id) возвращает копию списка. После изменения group_as нужно вызвать rebuild_group_index(); добавление или удаление определения автоматически обнаруживается по изменению размера словаря. Полная перезагрузка определений выполняется созданием нового каталога.
Stage загружает каталог, затем отдельно инициализирует количество, статистику и UI. Доступ к определениям идёт через world.catalog.entities, к группам — через world.catalog.members(id). Совместимые свойства и методы-переадресации из Owniverse удалены. Эволюция цивилизаций обращается непосредственно к QuantityMath.
Формулы, порядок обхода определений, формат сохранения и правила симуляции не изменены. Проверки модулей: tests/test_quantity_catalog.gd; интеграционные проверки перечислены в tests/README.md.
Представление количеств и разблокировка иконок
item_presentation.gd получает состояние и каталог, не изменяет симуляцию и не обращается к UI или Global.
amounts(state, catalog, total_produced)строит текущие или исторические количества. Текущие планеты включают свободные и связанные объекты. Подробные стадии сохраняют собственные значения одновременно с суммой count_as; готовые групповые счётчики повторно не суммируются.unlocks(state, catalog, locked)проверяет условия по историческим количествам и их отображаемым суммам. Возвращает remaining (ещё закрытые сущности) и visible (открываемые сущности и их count_as). Переданный список не изменяется. Уже открытые иконки повторно не блокируются.refreshуправляет снимком pending_amounts и флагом dirty, учитывает отложенное обновление и принудительную публикацию. Сам модуль не запускает таймеры и не меняет частоту обновления.
Stage обращается непосредственно к world.presentation, применяет результат разблокировки к контролам и хранит список закрытых иконок. Снимки и флаги принадлежат отдельному миру и не включаются в сохранение.
Партии, учёт, производство и эволюция
| Модуль / свойство мира | Ответственность |
|---|---|
object_batches.gd / batches |
Окна рождения и эволюции, частичное выбытие, остатки округления, масштабирование партий, интеграл времени жизни, прямое завершение короткоживущих партий |
object_ledger.gd / ledger |
Свободные и связанные количества, списание и зачисление, статистика выпуска, целочисленность, резервирование и передача привязок |
manual_production.gd / production |
Предпросмотр доступного количества, транзакция оплаты и привязок, ручное производство, объединение чёрных дыр в SMBH |
automatic_production.gd / automatic |
Выпуск за период и жизнь новорождённых объектов, разделение ресурсов на обычные и автоматические, энергия, квоты звёзд и бурых карликов |
stellar_rules.gd / stellar |
Продукты звёздной эволюции, создание планет, выбор звёздных преемников, два уровня разрушения и глобальные бласты |
life_evolution.gd / life |
Прогресс, деградация и повторная попытка планетарной жизни |
civilization_flow.gd, civilization_state.gd |
Непрерывные потоки цивилизаций, доли этик, целые квоты, лимиты и места обитания |
universe_environment.gd / environment |
Плотность, металличность, доля попаданий бластов, изменение параметров мира с сохранением возраста звёзд |
evolution_coordinator.gd / evolution |
Порядок фаз шага, последовательные поколения и публикация нового состояния |
В owniverse.gd остались создание состояния и модулей, скорость и проверка входного delta перед запуском эволюции. Дублирующее поле new_state и закомментированная старая реализация удалены. Единственный источник текущего состояния — world.state.
Внутри одной фазы снимок физических количеств переиспользуется для сверки
этик, звёздного бюджета и бюджета структур. После списания партий или переходов
создаётся новый снимок. Операции над одним типом объекта используют
physical_amount, не пересчитывая полную карту вселенной.
Порядок шага
- Определить обработанную десятую года. При продвижении времени восстановить недостающие партии жизни и проверить вместимость.
- Скопировать состояние, посчитать физические количества и производство за период.
- Интегрировать непрерывные потоки цивилизаций за весь интервал, затем обработать поколения звёзд и биологической жизни до конца интервала. Для каждого поколения: локальные разрушения → выбытие партий всех типов → план переходов → резервирование передачи привязок → зачисление преемников и их партий → производство новорождённых → применение привязок и округление → глобальные бласты → проверка вместимости.
- Обновить групповые количества, ограничить автоматические ресурсы и продвинуть параметры мира.
- Опубликовать новое состояние и обновить представление количеств.
Резервирование привязок использует замороженную таблицу, чтобы одновременные переходы не зависели от порядка обработки владельцев. Коммит передач происходит после зачисления преемников. Оплата производства остаётся атомарной: при нехватке ресурсов исходное состояние не меняется.
Зависимости и жизненный цикл
Модули симуляции получают свой Owniverse через simulation_module.gd. Они работают с переданным target либо с актуальным world.state; ссылка на старое состояние не кэшируется. Обращение к другим подсистемам явное, например world.ledger.credit(...) или world.batches.append_batch(...). Внутренние вызовы идут напрямую.
Ссылка модуля на мир слабая, поэтому цикл владения не возникает. Owniverse владеет модулями, каждый новый мир получает собственные экземпляры. Использовать модуль после освобождения его мира нельзя. В сохранение попадает только состояние; модули, каталог и UI туда не сериализуются. Определения OwniverseEntity по-прежнему освобождает владелец сцены.
Примеры нового API
var available = world.production.calculate_max_producible(world.catalog.entities["YD"])
world.production.produce("YD", 10.0)
var physical = world.ledger.physical_amounts(world.state)
var displayed = world.presentation.amounts(world.state, world.catalog)
world.environment.modify_world_parameter("Bur", 1.0)
world.evolute(delta)
Проверки проверяют прежние формулы через новый API; сравнение ускоренного и обычного путей выполняется через stellar.direct_completions. Дополнительный тест test_module_lifecycle.gd проверяет изоляцию миров и освобождение модулей.