Implement civilization flow mechanics and profiling for resource allocation
- Added `civilization_flow.gd` to manage continuous expected flows and resource allocation within civilizations. - Introduced `allocate_profiled` and `whole_quotas` functions in `quantity_math.gd` for precise stock allocation based on float shares. - Enhanced `credit` logic in `object_ledger.gd` to handle production remainders more effectively. - Updated `append_batch` in `object_batches.gd` to prevent batch creation for invalid IDs. - Introduced `ratio_approx` function in `exact.gd` for better handling of float profiles. - Added a benchmark script `benchmark_civilization_flows.gd` to evaluate the performance of civilization flow mechanics. - Refactored various functions to improve clarity and efficiency in handling resource flows and allocations.
This commit is contained in:
+42
-17
@@ -122,7 +122,41 @@ godot --headless --path Owniverse.GI --script res://tests/test_time.gd
|
||||
|
||||
## Согласованные правила эволюции
|
||||
|
||||
Сохраняются постепенные интервальные окна GI: начало преобразования — через `lifespan`, длительность окна — `lifespan / 40` при `lifespan > 10`, иначе `lifespan`.
|
||||
Сохраняются постепенные интервальные окна GI: срок жизни делится на 40 возрастных групп; начало преобразования — через `lifespan`, длительность окна — `lifespan / 40` при `lifespan > 10`, иначе `lifespan`.
|
||||
|
||||
На скоростях 4–6 узкие звёздные партии могут объединяться по границе полного
|
||||
цикла смерти шириной 200/2000/20000 игровых лет. Прежнее окно шире цикла
|
||||
сохраняется: долгоживущие звёзды не дробятся. Из существующих партий сливаются
|
||||
только две или более одного типа, чей оставшийся переход полностью попадает
|
||||
в общий цикл; широкие и пересекающие границу партии сохраняются.
|
||||
`test_batch_boundaries` проверяет объединение, точные большие количества и
|
||||
остатки, однократное изъятие, сериализацию, сохранение широких окон,
|
||||
распределённые рождения и интеграл производства.
|
||||
|
||||
`benchmark_large_star_cohorts.gd` создаёт отдельные большие диагностические
|
||||
сохранения со старой и новой звёздной сеткой при одинаковых количествах и
|
||||
входных интервалах рождения. Переключатель `batches.cycle_stars` используется
|
||||
только для сравнительного замера, в игре он включён. Парные прогоны меняют
|
||||
порядок моделей и сбрасывают исходное состояние перед каждым запуском:
|
||||
|
||||
```sh
|
||||
godot --headless --path Owniverse.GI --script res://tests/benchmark_large_star_cohorts.gd -- cycles=50 repeats=2
|
||||
```
|
||||
|
||||
Сохранения и полные профили записываются в `tests/artifacts/large_star_cohorts_*`;
|
||||
сохранение игрока не затрагивается. `generate_only` проверяет запись/чтение и
|
||||
исходное равенство физических количеств без запуска замеров.
|
||||
|
||||
`benchmark_many_objects.gd` создаёт новую диагностическую вселенную со всеми
|
||||
типами объектов и цивилизаций и 4800 синтетическими звёздными партиями,
|
||||
попадающими группами в общие циклы. Это отдельный стресс-сценарий большого
|
||||
числа партий; старый и новый расчёты используют одинаковый исходный состав.
|
||||
|
||||
```sh
|
||||
godot --headless --path Owniverse.GI --script res://tests/benchmark_many_objects.gd -- cycles=40 repeats=2
|
||||
```
|
||||
|
||||
Файлы сценария: `tests/artifacts/many_objects_fragmented_stars_*`.
|
||||
|
||||
Вероятностные исходы используют накопление дробного остатка GI, без случайного округления. Этот же подход выбран для будущего создания планет. Шансы планет записаны долями (`0.01` = 1%), а альтернативные исходы звёзд — процентами (`%0.1` = 0.1%). Парсер планет сохраняет дроби и поддерживает один элемент без `&`.
|
||||
|
||||
@@ -209,8 +243,7 @@ godot --path Owniverse.GI --script res://tests/benchmark_civilizations.gd -- ui
|
||||
Stage вызывает `evolute_frame`: транзакция получает бюджет 40 мс и уступает
|
||||
следующему кадру внутри создания партий и обработки стадий. Расчёт остаётся
|
||||
на главном потоке, состояние публикуется только после полного завершения.
|
||||
Длительность одной транзакции ограничена обычным шагом 1/60 секунды выбранной
|
||||
скорости. Запрошенное время хранится отдельно, поэтому отставание не превращается
|
||||
Одна транзакция обрабатывает 0,2 реальной секунды на любой скорости. Запрошенное время хранится отдельно, поэтому отставание не превращается
|
||||
в один всё более тяжёлый шаг. При предельной нагрузке время симуляции может
|
||||
отставать от запрошенного; это не ограничение FPS интерфейса и не удаление событий.
|
||||
|
||||
@@ -259,20 +292,12 @@ Stage вызывает `evolute_frame`: транзакция получает б
|
||||
1.057. Замер включает сокращение накопленного отставания сохранения;
|
||||
это результат конкретного сценария на Mac, а не гарантия для Android.
|
||||
|
||||
Адаптивный шаг на скоростях 4–6 выбирает 0.1, 0.2 или 0.5 реальной секунды.
|
||||
Долг больше двух шагов повышает ступень, меньше половины шага понижает её.
|
||||
Шаг ограничен доступным запрошенным временем. Скорости 1–3 сохраняют 1/60;
|
||||
смена скорости сбрасывает ступень. Возобновляемая транзакция сохраняет точную
|
||||
границу из checkpoint, адаптация применяется к следующей транзакции.
|
||||
Бюджет кадра остаётся 40 мс; ширина временных партий не меняется.
|
||||
`test_frame_evolution` проверяет ступени, гистерезис, сохранение долга,
|
||||
переключение скорости, возобновление и совпадение с прямым расчётом того же шага.
|
||||
На свежей диагностической копии сохранения с долгом 407.79 млн лет:
|
||||
600 кадров реального UI на M4 Pro дали 18.05 FPS (p95 92.91 мс,
|
||||
максимум 122.45 мс), поступило 3.335 млн лет, обработано 6.480 млн:
|
||||
пропускная способность 1.943 вместо 0.787 при фиксированном шаге 0.1.
|
||||
Разбиение времени влияет на дискретные производство и глобальные параметры;
|
||||
адаптивные шаги не обещают совпадения результата с последовательностью 0.1.
|
||||
Полный шаг фиксирован: 0,2 реальной секунды на всех скоростях, пять циклов
|
||||
на секунду запрошенного времени. Неполный интервал накапливается. При отставании
|
||||
шаг сохраняется, долг не отбрасывается. Возобновляемая транзакция сохраняет
|
||||
границу из checkpoint. Бюджет кадра остаётся 40 мс. `test_frame_evolution`
|
||||
проверяет расписание всех шести скоростей, сохранение долга и пять циклов
|
||||
на одну секунду.
|
||||
|
||||
Дипломатический drift использует шесть взвешенных вкладов вместо матрицы
|
||||
пар этик: вес = сумма вкладов + 195 × свой вклад − противоположный вклад.
|
||||
|
||||
Reference in New Issue
Block a user