Files
owniverse/world/owniverse
..

Модули 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, не пересчитывая полную карту вселенной.

Порядок шага

  1. Определить обработанную десятую года. При продвижении времени восстановить недостающие партии жизни и проверить вместимость.
  2. Скопировать состояние, посчитать физические количества и производство за период.
  3. Интегрировать непрерывные потоки цивилизаций за весь интервал, затем обработать поколения звёзд и биологической жизни до конца интервала. Для каждого поколения: локальные разрушения → выбытие партий всех типов → план переходов → резервирование передачи привязок → зачисление преемников и их партий → производство новорождённых → применение привязок и округление → глобальные бласты → проверка вместимости.
  4. Обновить групповые количества, ограничить автоматические ресурсы и продвинуть параметры мира.
  5. Опубликовать новое состояние и обновить представление количеств.

Резервирование привязок использует замороженную таблицу, чтобы одновременные переходы не зависели от порядка обработки владельцев. Коммит передач происходит после зачисления преемников. Оплата производства остаётся атомарной: при нехватке ресурсов исходное состояние не меняется.

Зависимости и жизненный цикл

Модули симуляции получают свой 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 проверяет изоляцию миров и освобождение модулей.