Add comprehensive tests and optimizations for simulation and UI performance

- Introduced a new benchmark save script to create a stress test scenario with extreme values for simulation performance.
- Added a full UI benchmark script to measure frame rates and performance metrics during UI interactions.
- Implemented tests for coarse generations to ensure population transitions are handled correctly.
- Created tests for extra parameters to validate the loading and application of configuration settings.
- Developed simulation optimization tests to verify the efficiency of population drift and rounding mechanisms.
- Added split optimization tests to ensure accurate allocation and rounding behavior in population management.
- Included startup parameter tests to confirm the correct initialization of global parameters before scene readiness.
- Enhanced the audit rounding ledger to compare selective and full rounding results for consistency.
This commit is contained in:
Kirill
2026-10-05 22:16:59 +03:00
parent 6f6a1be3bd
commit e48d4bbe88
57 changed files with 37279 additions and 784 deletions
+20 -3
View File
@@ -2,6 +2,7 @@ extends Node
const E = preload("res://world/owniverse/math/exact.gd")
const SPEED_LIMIT: int = 6
const SUPPORTED_LOCALES: PackedStringArray = ["en", "ru"]
# Write a readable diagnostic copy next to the encrypted save. Never used for loading.
var save_plaintext_copy: bool = true
@@ -15,16 +16,20 @@ var Settings: Dictionary = {
"language": "en",
}
# TODO getter setter for locale
#var Locales: Dictionary = {}
var Locale = "en"
var _locale: String = "en"
var Locale: String:
get:
return _locale
set(value):
set_locale(value)
var OwniverseEntities: Dictionary = {}
var OwniverseItems: Dictionary = {}
var Templates: Dictionary = {}
var LifeRules: Dictionary = {}
var CivilizationRules: Dictionary = {}
var ExtraParams: Dictionary = {}
var Music: Dictionary = {}
var Effects: Dictionary = {}
@@ -32,6 +37,12 @@ var Effects: Dictionary = {}
var batch_count: float = 40.0 # must be even not odd
func set_locale(locale: String) -> void:
_locale = locale if SUPPORTED_LOCALES.has(locale) else "en"
Settings.language = _locale
TranslationServer.set_locale(_locale)
#func get_localized_item_description(item_id: String, item: String) -> String:
#if Locales[Locale].has(item_id):
#return Locales[Locale][item_id][item]
@@ -68,7 +79,13 @@ func format_number(value, digits: int = 0) -> String:
return E.grouped(value, digits)
func _init() -> void:
# Stage constructs its world before autoload _ready callbacks run.
ExtraParams = preload("res://data/owniverse_extra_param_loader.gd").get_data()
func _ready() -> void:
set_locale(str(Settings.language))
LifeRules = OwniverseLifeRuleLoader.get_data()
OwniverseEntities = OwniverseEntityLoader.get_data()
+2
View File
@@ -374,8 +374,10 @@ func load_settings():
var config = ConfigFile.new()
var err = config.load(SAVE_PATH)
if E.ne(err, OK):
Global.set_locale(str(Global.Settings.language))
return false
for item in Global.Settings:
Global.Settings[item] = config.get_value(SETTING_SECTION, item, Global.Settings[item])
Global.set_locale(str(Global.Settings.language))
return true
#endregion
-318
View File
@@ -1,318 +0,0 @@
Civ|Stars|Home|Fall|ScaleLevel|Description|EthL|Lev|Eth|Wor|Pro|Deg|Col|War|Dip|WorC|ProC|DegC|ColC|WarC|DipC|Span|Ret
RP|||||Каменистая планета. Все умерли.||0|||||||||||||||
HP|||RP:1||Обитаемая планета. Абиогенез.||0|||1|1|||||0.00025|0.0025||||5E+06|5E-05
LP|||||На этой планете есть жизнь!||0|||||||||||||||
EON1|||HP:100^RP:1||Архей. Не сразу бросается в глаза, но на таких планетах полно археев и цианобактерий.||1|||1|1|||||0.00025|0.0025||||1E+07|1E-06
EON2|||EON1:1||Протерозой. Помимо вездесущих амёб, здесь присутствуют водоросли, губки и даже моллюски.||1|||1|1|||||0.00025|0.0025||||1E+07|1E-06
EON3|||EON2:1000^EON1:1||Палеозой. Папоротники, черви, трилобиты и рыбы.||1|||1|1|||||0.00025|0.0025||||1E+06|1E-05
EON4|||EON3:1000^EON1:1||Мезозой. Голосеменные, ящеры, динозавры и терапсиды.||1|||1|1|||||0.00025|0.0025||||1E+06|1E-05
EON5|||EON4:2000^EON1:1||Кайнозой. Покрытосеменные и разнообразные млекопитающие, из них некоторые проявляют признаки интеллекта.||1|||1|1|||||0.00025|0.0025||||5E+05|5E-04
C0|||||Докосмическая эпоха — от племени до федерации.||0|||||||||||||||
C0.0|||EON5:1||Нижний палеолит. Приручение огня, каменные орудия.||1|0|0|1|1|||||0.0175|0.025||||2E+03|1
C0.1|||C0.0:1||Средний палеолит. Развитые каменные орудия.||1|0|0|1|1|||||0.0175|0.025||||2E+03|1
C0.2|||||Верхний палеолит. Сложные каменные орудия, искусство.||1|1|1|1|1||||||||||2E+03|1
C0.2m|||C0.1:1||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.2b|||C0.1:1||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.2d|||C0.1:1||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.2l|||C0.1:1||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.2c|||C0.1:1||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.2w|||C0.1:1||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C0.3|||||Мезолит. Лук и стрелы, рыболовство, лодки.||1|1|1|1|1||||||||||2E+03|1
C0.3m|||C0.2:1||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.3b|||C0.2:1||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.3d|||C0.2:1||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.3l|||C0.2:1||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.3c|||C0.2:1||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.3w|||C0.2:1||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C0.4|||||Ранний неолит. Земледелие.||1|1|1|1|1||||||||||2E+03|1
C0.4m|||C0.3:1||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.4b|||C0.3:1||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.4d|||C0.3:1||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.4l|||C0.3:1||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.4c|||C0.3:1||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.4w|||C0.3:1||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C0.5|||||Средний неолит. Скотоводство, керамика.||1|1|1|1|1||||||||||2E+03|1
C0.5m|||C0.4:1||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.5b|||C0.4:1||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.5d|||C0.4:1||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.5l|||C0.4:1||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.5c|||C0.4:1||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.5w|||C0.4:1||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C0.6|||||Поздний неолит. Крупные поселения.||1|1|1|1|1||||||||||2E+03|1
C0.6m|||C0.5:1||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.6b|||C0.5:1||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.6d|||C0.5:1||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.6l|||C0.5:1||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.6c|||C0.5:1||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.6w|||C0.5:1||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C0.7|||||Первые царства медного и бронзового века. Колесо.||1|1|1|1|1||||||||||2E+03|1
C0.7m|||C0.6:1||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.7b|||C0.6:1||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.7d|||C0.6:1||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.7l|||C0.6:1||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.7c|||C0.6:1||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.7w|||C0.6:1||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C0.8|||||Античные империи железного века. Философия.||1|1|1|1|1||||||||||2E+03|1
C0.8m|||C0.7:1||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.8b|||C0.7:1||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.8d|||C0.7:1||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.8l|||C0.7:1||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.8c|||C0.7:1||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.8w|||C0.7:1||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C0.9|||||Промышленная эпоха. Электричество.||1|1|1|1|1||||||||||2E+03|1
C0.9m|||C0.8:512^C0.7:256^EON5:21^EON1:6||Мистики|m|2||||||||1.6|0.0084|0.01|0.0000625|0.001024|||
C0.9b|||C0.8:512^C0.7:256^EON5:43^EON1:9||Строители|b|2||||||||1|0.01859375|0.02|0.00003125|0.0025|||
C0.9d|||C0.8:512^C0.7:256^EON5:7^EON1:3||Дипломаты|d|2||||||||1|0.0112|0.01538461538|0.0005|0.00015625|||
C0.9l|||C0.8:512^C0.7:256^EON5:60^EON1:11||Логики|l|2||||||||0.5|0.0504|0.03571428571|0.0005|0.0025|||
C0.9c|||C0.8:512^C0.7:256^EON5:252^EON1:19||Колонисты|c|2||||||||0.8|0.021|0.02604166667|0.004096|0.006103515625|||
C0.9w|||C0.8:512^C0.7:256^EON5:260^EON1:26||Воины|w|2||||||||1.25|0.02625|0.03125|0.0005|0.016384|||
C1|||||Цивилизации, осваивающие родную солнечную систему.||0|||||||||||||||
C1.0|||||Цивилизация, освоившая родную планету. Сверхпроводимость, управляемый термоядерный синтез.||1|1|1|1|1||||||||||5E+03|1
C1.0m|||C0.9:1024^EON5:21^EON1:6||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.0b|||C0.9:1024^EON5:43^EON1:9||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.0d|||C0.9:1024^EON5:7^EON1:3||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.0l|||C0.9:1024^EON5:60^EON1:11||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.0c|||C0.9:1024^EON5:152^EON1:19||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.0w|||C0.9:1024^EON5:260^EON1:26||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.1|||||Научные базы на других телах родной системы. Пусковая петля, космический лифт.||1|1|1|1|1||||||||||5E+03|1
C1.1m|||C1.0:1024^C0.9:256^EON5:21^EON1:6||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.1b|||C1.0:1024^C0.9:256^EON5:43^EON1:9||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.1d|||C1.0:1024^C0.9:256^EON5:7^EON1:3||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.1l|||C1.0:1024^C0.9:256^EON5:60^EON1:11||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.1c|||C1.0:1024^C0.9:256^EON5:152^EON1:19||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.1w|||C1.0:1024^C0.9:256^EON5:260^EON1:26||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.2|||||Полное управление генетикой. Киборгизация.||1|1|1|1|1||||||||||5E+03|1
C1.2m|||C1.1:256^C1.0:1024^C0.9:256^EON5:21^EON1:6||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.2b|||C1.1:256^C1.0:1024^C0.9:256^EON5:43^EON1:9||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.2d|||C1.1:256^C1.0:1024^C0.9:256^EON5:7^EON1:3||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.2l|||C1.1:256^C1.0:1024^C0.9:256^EON5:60^EON1:11||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.2c|||C1.1:256^C1.0:1024^C0.9:256^EON5:152^EON1:19||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.2w|||C1.1:256^C1.0:1024^C0.9:256^EON5:260^EON1:26||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.3|||||Промышленная добыча астероидов. Колонии на других планетах родной системы.||1|1|1|1|1||||||||||5E+03|1
C1.3m|||C1.2:256^C1.0:1024^C0.9:64^EON5:13^EON1:13||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.3b|||C1.2:256^C1.0:1024^C0.9:64^EON5:22^EON1:22||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.3d|||C1.2:256^C1.0:1024^C0.9:64^EON5:5^EON1:5||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.3l|||C1.2:256^C1.0:1024^C0.9:64^EON5:30^EON1:30||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.3c|||C1.2:256^C1.0:1024^C0.9:64^EON5:64^EON1:64||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.3w|||C1.2:256^C1.0:1024^C0.9:64^EON5:100^EON1:100||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.4|||||Сбор вещества из атмосфер газовых гигантов.||1|1|1|1|1||||||||||5E+03|1
C1.4m|||C1.3:384^C1.0:896^EON5:6^EON1:21||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.4b|||C1.3:384^C1.0:896^EON5:9^EON1:43||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.4d|||C1.3:384^C1.0:896^EON5:3^EON1:7||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.4l|||C1.3:384^C1.0:896^EON5:11^EON1:60||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.4c|||C1.3:384^C1.0:896^EON5:19^EON1:152||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.4w|||C1.3:384^C1.0:896^EON5:26^EON1:260||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.5|||||Космические города. Пикотехнологии: управление отдельными атомами.||1|1|1|1|1||||||||||5E+03|1
C1.5m|||C1.4:512^C1.0:768^EON5:6^EON1:21||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.5b|||C1.4:512^C1.0:768^EON5:9^EON1:43||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.5d|||C1.4:512^C1.0:768^EON5:3^EON1:7||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.5l|||C1.4:512^C1.0:768^EON5:11^EON1:60||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.5c|||C1.4:512^C1.0:768^EON5:19^EON1:152||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.5w|||C1.4:512^C1.0:768^EON5:26^EON1:260||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.6|||||Промышленное производство антивещества. Первые звездолёты.||1|1|1|1|1|1|||||||||5E+03|1
C1.6m|||C1.5:768^C1.0:512^EON5:6^RP:21||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.6b|||C1.5:768^C1.0:512^EON5:9^RP:43||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.6d|||C1.5:768^C1.0:512^EON5:3^RP:7||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.6l|||C1.5:768^C1.0:512^EON5:11^RP:60||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.6c|||C1.5:768^C1.0:512^EON5:19^RP:152||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.6w|||C1.5:768^C1.0:512^EON5:26^RP:260||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.7|||||Терраформинг. Гамма-лазеры.||1|1|1|1|1|1|||||||||5E+03|1
C1.7m|||C1.6:896^C1.0:384^EON5:6^RP:21||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.7b|||C1.6:896^C1.0:384^EON5:9^RP:43||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.7d|||C1.6:896^C1.0:384^EON5:3^RP:7||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.7l|||C1.6:896^C1.0:384^EON5:11^RP:60||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.7c|||C1.6:896^C1.0:384^EON5:19^RP:152||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.7w|||C1.6:896^C1.0:384^EON5:26^RP:260||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.8|||||Космические станции континентального масштаба.||1|1|1|1|1|1|||||||||5E+03|1
C1.8m|||C1.7:1024^C1.0:256^EON5:6^RP:21||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.8b|||C1.7:1024^C1.0:256^EON5:9^RP:43||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.8d|||C1.7:1024^C1.0:256^EON5:3^RP:7||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.8l|||C1.7:1024^C1.0:256^EON5:11^RP:60||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.8c|||C1.7:1024^C1.0:256^EON5:19^RP:152||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.8w|||C1.7:1024^C1.0:256^EON5:26^RP:260||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C1.9|||||Частичный рой Дайсона.||1|1|1|1|1|1|||||||||5E+03|1
C1.9m|||C1.8:1024^C1.0:128^EON5:6^RP:21||Мистики|m|2||||||||1.6|0.009|0.01|0.0000625|0.001024|||
C1.9b|||C1.8:1024^C1.0:128^EON5:9^RP:43||Строители|b|2||||||||1|0.019921875|0.02|0.00003125|0.0025|||
C1.9d|||C1.8:1024^C1.0:128^EON5:3^RP:7||Дипломаты|d|2||||||||1|0.012|0.01538461538|0.0005|0.00015625|||
C1.9l|||C1.8:1024^C1.0:128^EON5:11^RP:60||Логики|l|2||||||||0.5|0.054|0.03571428571|0.0005|0.0025|||
C1.9c|||C1.8:1024^C1.0:128^EON5:19^RP:152||Колонисты|c|2||||||||0.8|0.0225|0.02604166667|0.004096|0.006103515625|||
C1.9w|||C1.8:1024^C1.0:128^EON5:26^RP:260||Воины|w|2||||||||1.25|0.028125|0.03125|0.0005|0.016384|||
C2|||||Цивилизации, ведущие экспансию к иным звёздам.||0|||||||||||||||
C2.0|1E+00|DwStar||Звезда|Цивилизация, освоившая энергию родного солнца.||1|1|1|1|1|1|1|1|||||||5E+03|1
C2.0m|||C1.9:1024^C1.0:128^RP:28||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.0b|||C1.9:1024^C1.0:128^EON5:9^RP:59||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.0d|||C1.9:1024^C1.0:128^EON5:3^RP:8||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.0l|||C1.9:1024^C1.0:128^EON5:11^RP:85||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.0c|||C1.9:1024^C1.0:128^EON5:19^RP:235||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.0w|||C1.9:1024^C1.0:128^EON5:26^RP:419||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.1|1E+01|DwStar|||Изменение планетарных орбит.||1|1|1|1|1|1|1|1|||||||5E+03|5.62E-01
C2.1m|||C2.0:1||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.1b|||C2.0:1||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.1d|||C2.0:1||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.1l|||C2.0:1||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.1c|||C2.0:1||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.1w|||C2.0:1||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.2|1E+02|DwStar|||Управление инерцией.||1|1|1|1|1|1|1|1|||||||1E+04|3.16E-01
C2.2m|||C2.1:1024^C2.0:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.2b|||C2.1:1024^C2.0:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.2d|||C2.1:1024^C2.0:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.2l|||C2.1:1024^C2.0:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.2c|||C2.1:1024^C2.0:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.2w|||C2.1:1024^C2.0:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.3|1E+03|DwStar||Рассеянное звёздное скопление|Сбор вещества со звёзд.||1|1|1|1|1|1|1|1|||||||2E+04|1.78E-01
C2.3m|||C2.2:1024^C2.1:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.3b|||C2.2:1024^C2.1:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.3d|||C2.2:1024^C2.1:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.3l|||C2.2:1024^C2.1:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.3c|||C2.2:1024^C2.1:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.3w|||C2.2:1024^C2.1:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.4|1E+04|DwStar||Малое звёздное скопление|Фемтотехнологии: управление отдельными фермионами.||1|1|1|1|1|1|1|1|||||||2E+04|1.00E-01
C2.4m|||C2.3:1024^C2.2:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.4b|||C2.3:1024^C2.2:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.4d|||C2.3:1024^C2.2:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.4l|||C2.3:1024^C2.2:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.4c|||C2.3:1024^C2.2:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.4w|||C2.3:1024^C2.2:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.5|1E+05|DwStar||Звёздное скопление|Деконструкция и сборка планет.||1|1|1|1|1|1|1|1|||||||3E+04|5.62E-02
C2.5m|||C2.4:1024^C2.3:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.5b|||C2.4:1024^C2.3:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.5d|||C2.4:1024^C2.3:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.5l|||C2.4:1024^C2.3:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.5c|||C2.4:1024^C2.3:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.5w|||C2.4:1024^C2.3:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.6|1E+06|DwStar||Большое звёздное скопление|Астроархитектурная доминанта.||1|1|1|1|1|1|1|1|||||||3E+04|3.16E-02
C2.6m|||C2.5:1024^C2.4:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.6b|||C2.5:1024^C2.4:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.6d|||C2.5:1024^C2.4:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.6l|||C2.5:1024^C2.4:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.6c|||C2.5:1024^C2.4:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.6w|||C2.5:1024^C2.4:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.7|1E+07|GiStar||Гигантское звёздное скопление|Освоение ресурсов звёзд-гигантов.||1|1|1|1|1|1|1|1|||||||4E+04|1.78E-02
C2.7m|||C2.6:1024^C2.5:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.7b|||C2.6:1024^C2.5:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.7d|||C2.6:1024^C2.5:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.7l|||C2.6:1024^C2.5:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.7c|||C2.6:1024^C2.5:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.7w|||C2.6:1024^C2.5:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.8|1E+08|GiStar|||Управление гравитацией.||1|1|1|1|1|1|1|1|||||||4E+04|1.00E-02
C2.8m|||C2.7:1024^C2.6:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.8b|||C2.7:1024^C2.6:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.8d|||C2.7:1024^C2.6:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.8l|||C2.7:1024^C2.6:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.8c|||C2.7:1024^C2.6:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.8w|||C2.7:1024^C2.6:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C2.9|1E+09|GiStar||Карликовая галактика|Перемещение звёзд.||1|1|1|1|1|1|1|1|||||||5E+04|5.62E-03
C2.9m|||C2.8:1024^C2.7:6||Мистики|m|2||||||||1.6|0.006|0.01|0.0005|0.00128|1||
C2.9b|||C2.8:1024^C2.7:9||Строители|b|2||||||||1|0.02125|0.015625|0.00003125|0.0025|0.64||
C2.9d|||C2.8:1024^C2.7:3||Дипломаты|d|2||||||||1|0.0128|0.01923076923|0.0009765625|0.0003125|2.56||
C2.9l|||C2.8:1024^C2.7:11||Логики|l|2||||||||0.5|0.0576|0.04464285714|0.0005|0.0025|1.5625||
C2.9c|||C2.8:1024^C2.7:19||Колонисты|c|2||||||||0.8|0.024|0.04166666667|0.004096|0.006103515625|1||
C2.9w|||C2.8:1024^C2.7:26||Воины|w|2||||||||1.25|0.03|0.025|0.000256|0.03072|0.25||
C3|||||Цивилизации галактического масштаба.||0|||||||||||||||
C3.0|1E+10|GiStar||Малая галактика|Экспансия в группу галактик.||1|1|1|1|1|1|1|1|||||||1E+05|3.16E-03
C3.0m|||C2.9:1024^C2.8:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.0b|||C2.9:1024^C2.8:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.0d|||C2.9:1024^C2.8:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.0l|||C2.9:1024^C2.8:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.0c|||C2.9:1024^C2.8:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.0w|||C2.9:1024^C2.8:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.1|1E+11|GiStar||Средняя галактика|Создание звёзд.||1|1|1|1|1|1|1|1|||||||1E+05|1.78E-03
C3.1m|||C3.0:1024^C2.9:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.1b|||C3.0:1024^C2.9:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.1d|||C3.0:1024^C2.9:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.1l|||C3.0:1024^C2.9:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.1c|||C3.0:1024^C2.9:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.1w|||C3.0:1024^C2.9:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.2|1E+12|WD||Большая галактика|Использование белых карликов.||1|1|1|1|1|1|1|1|||||||2E+05|1.00E-03
C3.2m|||C3.1:1024^C3.0:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.2b|||C3.1:1024^C3.0:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.2d|||C3.1:1024^C3.0:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.2l|||C3.1:1024^C3.0:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.2c|||C3.1:1024^C3.0:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.2w|||C3.1:1024^C3.0:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.3|1E+13|WD||Гигантская галактика|Создание чёрных дыр из концентрированного излучения.||1|1|1|1|1|1|1|1|||||||3E+05|5.62E-04
C3.3m|||C3.2:1024^C3.1:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.3b|||C3.2:1024^C3.1:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.3d|||C3.2:1024^C3.1:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.3l|||C3.2:1024^C3.1:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.3c|||C3.2:1024^C3.1:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.3w|||C3.2:1024^C3.1:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.4|1E+14|WD||Группа галактик|Экспансия в сверхскопление.||1|1|1|1|1|1|1|1|||||||4E+05|3.16E-04
C3.4m|||C3.3:1024^C3.2:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.4b|||C3.3:1024^C3.2:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.4d|||C3.3:1024^C3.2:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.4l|||C3.3:1024^C3.2:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.4c|||C3.3:1024^C3.2:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.4w|||C3.3:1024^C3.2:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.5|1E+15|NS|||Использование нейтронных звёзд.||1|1|1|1|1|1|1|1|||||||5E+05|1.78E-04
C3.5m|||C3.4:1024^C3.3:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.5b|||C3.4:1024^C3.3:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.5d|||C3.4:1024^C3.3:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.5l|||C3.4:1024^C3.3:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.5c|||C3.4:1024^C3.3:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.5w|||C3.4:1024^C3.3:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.6|1E+16|NS||Сверхскопление|Экспансия в нить.||1|1|1|1|1|1|1|1|||||||6E+05|1.00E-04
C3.6m|||C3.5:1024^C3.4:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.6b|||C3.5:1024^C3.4:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.6d|||C3.5:1024^C3.4:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.6l|||C3.5:1024^C3.4:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.6c|||C3.5:1024^C3.4:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.6w|||C3.5:1024^C3.4:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.7|1E+17|MGT|||Использование магнетаров.||1|1|1|1|1|1|1|1|||||||7E+05|5.62E-05
C3.7m|||C3.6:1024^C3.5:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.7b|||C3.6:1024^C3.5:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.7d|||C3.6:1024^C3.5:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.7l|||C3.6:1024^C3.5:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.7c|||C3.6:1024^C3.5:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.7w|||C3.6:1024^C3.5:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.8|1E+18|MGT||Галактическая нить|Экспансия в великую стену.||1|1|1|1|1|1|1|1|||||||8E+05|3.16E-05
C3.8m|||C3.7:1024^C3.6:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.8b|||C3.7:1024^C3.6:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.8d|||C3.7:1024^C3.6:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.8l|||C3.7:1024^C3.6:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.8c|||C3.7:1024^C3.6:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.8w|||C3.7:1024^C3.6:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C3.9|1E+19|BH|||Использование чёрных дыр.||1|1|1|1|1|1|1|1|||||||9E+05|1.78E-05
C3.9m|||C3.8:1024^C3.7:6||Мистики|m|2||||||||1.6|0.006375|0.01|0.0005|0.00128|1||
C3.9b|||C3.8:1024^C3.7:9||Строители|b|2||||||||1|0.022578125|0.015625|0.00003125|0.0025|0.64||
C3.9d|||C3.8:1024^C3.7:3||Дипломаты|d|2||||||||1|0.0136|0.01923076923|0.0009765625|0.0003125|2.56||
C3.9l|||C3.8:1024^C3.7:11||Логики|l|2||||||||0.5|0.0612|0.04464285714|0.0005|0.0025|1.5625||
C3.9c|||C3.8:1024^C3.7:19||Колонисты|c|2||||||||0.8|0.0255|0.04166666667|0.004096|0.006103515625|1||
C3.9w|||C3.8:1024^C3.7:26||Воины|w|2||||||||1.25|0.031875|0.025|0.000256|0.03072|0.25||
C4|||||Цивилизации вселенского масштаба.||0|||||||||||||||
C4.0|1E+20|BH|||Манипуляции со временем.||1|1|1|1|1|1|1|1|||||||2E+06|1.00E-05
C4.0m|||C3.9:1024^C3.8:6||Мистики|m|2||||||||1.6|0.00675|0.01|0.0005|0.00128|1||
C4.0b|||C3.9:1024^C3.8:9||Строители|b|2||||||||1|0.02390625|0.015625|0.00003125|0.0025|0.64||
C4.0d|||C3.9:1024^C3.8:3||Дипломаты|d|2||||||||1|0.0144|0.01923076923|0.0009765625|0.0003125|2.56||
C4.0l|||C3.9:1024^C3.8:11||Логики|l|2||||||||0.5|0.0648|0.04464285714|0.0005|0.0025|1.5625||
C4.0c|||C3.9:1024^C3.8:19||Колонисты|c|2||||||||0.8|0.027|0.04166666667|0.004096|0.006103515625|1||
C4.0w|||C3.9:1024^C3.8:26||Воины|w|2||||||||1.25|0.03375|0.025|0.000256|0.03072|0.25||
C4.1|1E+21|BH||Великая стена|Экспансия на масштабы всей вселенной.||1|1|1|1|1|1|1|1|||||||2E+06|5.62E-06
C4.1m|||C4.0:1024^C3.9:6||Мистики|m|2||||||||1.6|0.00675|0.01|0.0005|0.00128|1||
C4.1b|||C4.0:1024^C3.9:9||Строители|b|2||||||||1|0.02390625|0.015625|0.00003125|0.0025|0.64||
C4.1d|||C4.0:1024^C3.9:3||Дипломаты|d|2||||||||1|0.0144|0.01923076923|0.0009765625|0.0003125|2.56||
C4.1l|||C4.0:1024^C3.9:11||Логики|l|2||||||||0.5|0.0648|0.04464285714|0.0005|0.0025|1.5625||
C4.1c|||C4.0:1024^C3.9:19||Колонисты|c|2||||||||0.8|0.027|0.04166666667|0.004096|0.006103515625|1||
C4.1w|||C4.0:1024^C3.9:26||Воины|w|2||||||||1.25|0.03375|0.025|0.000256|0.03072|0.25||
C4.2|1E+22|SMBH|||Использование сверхмассивных чёрных дыр.||1|1|1|1|1|1|1|1|||||||4E+06|3.16E-06
C4.2m|||C4.1:1024^C4.0:6||Мистики|m|2||||||||1.6|0.00675|0.01|0.0005|0.00128|1||
C4.2b|||C4.1:1024^C4.0:9||Строители|b|2||||||||1|0.02390625|0.015625|0.00003125|0.0025|0.64||
C4.2d|||C4.1:1024^C4.0:3||Дипломаты|d|2||||||||1|0.0144|0.01923076923|0.0009765625|0.0003125|2.56||
C4.2l|||C4.1:1024^C4.0:11||Логики|l|2||||||||0.5|0.0648|0.04464285714|0.0005|0.0025|1.5625||
C4.2c|||C4.1:1024^C4.0:19||Колонисты|c|2||||||||0.8|0.027|0.04166666667|0.004096|0.006103515625|1||
C4.2w|||C4.1:1024^C4.0:26||Воины|w|2||||||||1.25|0.03375|0.025|0.000256|0.03072|0.25||
C4.3|1E+23|SMBH|||Складное пространство.||1|1|1|1|1|1|1|1|||||||6E+06|1.78E-06
C4.3m|||C4.2:1024^C4.1:6||Мистики|m|2||||||||1.6|0.00675|0.01|0.0005|0.00128|1||
C4.3b|||C4.2:1024^C4.1:9||Строители|b|2||||||||1|0.02390625|0.015625|0.00003125|0.0025|0.64||
C4.3d|||C4.2:1024^C4.1:3||Дипломаты|d|2||||||||1|0.0144|0.01923076923|0.0009765625|0.0003125|2.56||
C4.3l|||C4.2:1024^C4.1:11||Логики|l|2||||||||0.5|0.0648|0.04464285714|0.0005|0.0025|1.5625||
C4.3c|||C4.2:1024^C4.1:19||Колонисты|c|2||||||||0.8|0.027|0.04166666667|0.004096|0.006103515625|1||
C4.3w|||C4.2:1024^C4.1:26||Воины|w|2||||||||1.25|0.03375|0.025|0.000256|0.03072|0.25||
C4.4|1E+24|SMBH||Вселенский пузырь|Поле невероятности.||1|1|1|1|1|1|1|1|||||||8E+06|1.00E-06
C4.4m|||C4.3:1024^C4.2:6||Мистики|m|2||||||||1.6|0.00675|0.01|0.0005|0.00128|1||
C4.4b|||C4.3:1024^C4.2:9||Строители|b|2||||||||1|0.02390625|0.015625|0.00003125|0.0025|0.64||
C4.4d|||C4.3:1024^C4.2:3||Дипломаты|d|2||||||||1|0.0144|0.01923076923|0.0009765625|0.0003125|2.56||
C4.4l|||C4.3:1024^C4.2:11||Логики|l|2||||||||0.5|0.0648|0.04464285714|0.0005|0.0025|1.5625||
C4.4c|||C4.3:1024^C4.2:19||Колонисты|c|2||||||||0.8|0.027|0.04166666667|0.004096|0.006103515625|1||
C4.4w|||C4.3:1024^C4.2:26||Воины|w|2||||||||1.25|0.03375|0.025|0.000256|0.03072|0.25||
Ct|||||Трансцендентальность.||0|1||||||||||||||
1 Civ Stars Home Fall ScaleLevel Description EthL Lev Eth Wor Pro Deg Col War Dip WorC ProC DegC ColC WarC DipC Span Ret
2 RP Каменистая планета. Все умерли. 0
3 HP RP:1 Обитаемая планета. Абиогенез. 0 1 1 0.00025 0.0025 5E+06 5E-05
4 LP На этой планете есть жизнь! 0
5 EON1 HP:100^RP:1 Архей. Не сразу бросается в глаза, но на таких планетах полно археев и цианобактерий. 1 1 1 0.00025 0.0025 1E+07 1E-06
6 EON2 EON1:1 Протерозой. Помимо вездесущих амёб, здесь присутствуют водоросли, губки и даже моллюски. 1 1 1 0.00025 0.0025 1E+07 1E-06
7 EON3 EON2:1000^EON1:1 Палеозой. Папоротники, черви, трилобиты и рыбы. 1 1 1 0.00025 0.0025 1E+06 1E-05
8 EON4 EON3:1000^EON1:1 Мезозой. Голосеменные, ящеры, динозавры и терапсиды. 1 1 1 0.00025 0.0025 1E+06 1E-05
9 EON5 EON4:2000^EON1:1 Кайнозой. Покрытосеменные и разнообразные млекопитающие, из них некоторые проявляют признаки интеллекта. 1 1 1 0.00025 0.0025 5E+05 5E-04
10 C0 Докосмическая эпоха — от племени до федерации. 0
11 C0.0 EON5:1 Нижний палеолит. Приручение огня, каменные орудия. 1 0 0 1 1 0.0175 0.025 2E+03 1
12 C0.1 C0.0:1 Средний палеолит. Развитые каменные орудия. 1 0 0 1 1 0.0175 0.025 2E+03 1
13 C0.2 Верхний палеолит. Сложные каменные орудия, искусство. 1 1 1 1 1 2E+03 1
14 C0.2m C0.1:1 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
15 C0.2b C0.1:1 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
16 C0.2d C0.1:1 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
17 C0.2l C0.1:1 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
18 C0.2c C0.1:1 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
19 C0.2w C0.1:1 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
20 C0.3 Мезолит. Лук и стрелы, рыболовство, лодки. 1 1 1 1 1 2E+03 1
21 C0.3m C0.2:1 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
22 C0.3b C0.2:1 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
23 C0.3d C0.2:1 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
24 C0.3l C0.2:1 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
25 C0.3c C0.2:1 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
26 C0.3w C0.2:1 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
27 C0.4 Ранний неолит. Земледелие. 1 1 1 1 1 2E+03 1
28 C0.4m C0.3:1 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
29 C0.4b C0.3:1 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
30 C0.4d C0.3:1 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
31 C0.4l C0.3:1 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
32 C0.4c C0.3:1 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
33 C0.4w C0.3:1 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
34 C0.5 Средний неолит. Скотоводство, керамика. 1 1 1 1 1 2E+03 1
35 C0.5m C0.4:1 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
36 C0.5b C0.4:1 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
37 C0.5d C0.4:1 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
38 C0.5l C0.4:1 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
39 C0.5c C0.4:1 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
40 C0.5w C0.4:1 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
41 C0.6 Поздний неолит. Крупные поселения. 1 1 1 1 1 2E+03 1
42 C0.6m C0.5:1 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
43 C0.6b C0.5:1 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
44 C0.6d C0.5:1 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
45 C0.6l C0.5:1 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
46 C0.6c C0.5:1 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
47 C0.6w C0.5:1 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
48 C0.7 Первые царства медного и бронзового века. Колесо. 1 1 1 1 1 2E+03 1
49 C0.7m C0.6:1 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
50 C0.7b C0.6:1 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
51 C0.7d C0.6:1 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
52 C0.7l C0.6:1 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
53 C0.7c C0.6:1 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
54 C0.7w C0.6:1 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
55 C0.8 Античные империи железного века. Философия. 1 1 1 1 1 2E+03 1
56 C0.8m C0.7:1 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
57 C0.8b C0.7:1 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
58 C0.8d C0.7:1 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
59 C0.8l C0.7:1 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
60 C0.8c C0.7:1 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
61 C0.8w C0.7:1 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
62 C0.9 Промышленная эпоха. Электричество. 1 1 1 1 1 2E+03 1
63 C0.9m C0.8:512^C0.7:256^EON5:21^EON1:6 Мистики m 2 1.6 0.0084 0.01 0.0000625 0.001024
64 C0.9b C0.8:512^C0.7:256^EON5:43^EON1:9 Строители b 2 1 0.01859375 0.02 0.00003125 0.0025
65 C0.9d C0.8:512^C0.7:256^EON5:7^EON1:3 Дипломаты d 2 1 0.0112 0.01538461538 0.0005 0.00015625
66 C0.9l C0.8:512^C0.7:256^EON5:60^EON1:11 Логики l 2 0.5 0.0504 0.03571428571 0.0005 0.0025
67 C0.9c C0.8:512^C0.7:256^EON5:252^EON1:19 Колонисты c 2 0.8 0.021 0.02604166667 0.004096 0.006103515625
68 C0.9w C0.8:512^C0.7:256^EON5:260^EON1:26 Воины w 2 1.25 0.02625 0.03125 0.0005 0.016384
69 C1 Цивилизации, осваивающие родную солнечную систему. 0
70 C1.0 Цивилизация, освоившая родную планету. Сверхпроводимость, управляемый термоядерный синтез. 1 1 1 1 1 5E+03 1
71 C1.0m C0.9:1024^EON5:21^EON1:6 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
72 C1.0b C0.9:1024^EON5:43^EON1:9 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
73 C1.0d C0.9:1024^EON5:7^EON1:3 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
74 C1.0l C0.9:1024^EON5:60^EON1:11 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
75 C1.0c C0.9:1024^EON5:152^EON1:19 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
76 C1.0w C0.9:1024^EON5:260^EON1:26 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
77 C1.1 Научные базы на других телах родной системы. Пусковая петля, космический лифт. 1 1 1 1 1 5E+03 1
78 C1.1m C1.0:1024^C0.9:256^EON5:21^EON1:6 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
79 C1.1b C1.0:1024^C0.9:256^EON5:43^EON1:9 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
80 C1.1d C1.0:1024^C0.9:256^EON5:7^EON1:3 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
81 C1.1l C1.0:1024^C0.9:256^EON5:60^EON1:11 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
82 C1.1c C1.0:1024^C0.9:256^EON5:152^EON1:19 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
83 C1.1w C1.0:1024^C0.9:256^EON5:260^EON1:26 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
84 C1.2 Полное управление генетикой. Киборгизация. 1 1 1 1 1 5E+03 1
85 C1.2m C1.1:256^C1.0:1024^C0.9:256^EON5:21^EON1:6 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
86 C1.2b C1.1:256^C1.0:1024^C0.9:256^EON5:43^EON1:9 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
87 C1.2d C1.1:256^C1.0:1024^C0.9:256^EON5:7^EON1:3 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
88 C1.2l C1.1:256^C1.0:1024^C0.9:256^EON5:60^EON1:11 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
89 C1.2c C1.1:256^C1.0:1024^C0.9:256^EON5:152^EON1:19 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
90 C1.2w C1.1:256^C1.0:1024^C0.9:256^EON5:260^EON1:26 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
91 C1.3 Промышленная добыча астероидов. Колонии на других планетах родной системы. 1 1 1 1 1 5E+03 1
92 C1.3m C1.2:256^C1.0:1024^C0.9:64^EON5:13^EON1:13 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
93 C1.3b C1.2:256^C1.0:1024^C0.9:64^EON5:22^EON1:22 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
94 C1.3d C1.2:256^C1.0:1024^C0.9:64^EON5:5^EON1:5 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
95 C1.3l C1.2:256^C1.0:1024^C0.9:64^EON5:30^EON1:30 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
96 C1.3c C1.2:256^C1.0:1024^C0.9:64^EON5:64^EON1:64 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
97 C1.3w C1.2:256^C1.0:1024^C0.9:64^EON5:100^EON1:100 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
98 C1.4 Сбор вещества из атмосфер газовых гигантов. 1 1 1 1 1 5E+03 1
99 C1.4m C1.3:384^C1.0:896^EON5:6^EON1:21 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
100 C1.4b C1.3:384^C1.0:896^EON5:9^EON1:43 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
101 C1.4d C1.3:384^C1.0:896^EON5:3^EON1:7 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
102 C1.4l C1.3:384^C1.0:896^EON5:11^EON1:60 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
103 C1.4c C1.3:384^C1.0:896^EON5:19^EON1:152 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
104 C1.4w C1.3:384^C1.0:896^EON5:26^EON1:260 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
105 C1.5 Космические города. Пикотехнологии: управление отдельными атомами. 1 1 1 1 1 5E+03 1
106 C1.5m C1.4:512^C1.0:768^EON5:6^EON1:21 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
107 C1.5b C1.4:512^C1.0:768^EON5:9^EON1:43 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
108 C1.5d C1.4:512^C1.0:768^EON5:3^EON1:7 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
109 C1.5l C1.4:512^C1.0:768^EON5:11^EON1:60 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
110 C1.5c C1.4:512^C1.0:768^EON5:19^EON1:152 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
111 C1.5w C1.4:512^C1.0:768^EON5:26^EON1:260 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
112 C1.6 Промышленное производство антивещества. Первые звездолёты. 1 1 1 1 1 1 5E+03 1
113 C1.6m C1.5:768^C1.0:512^EON5:6^RP:21 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
114 C1.6b C1.5:768^C1.0:512^EON5:9^RP:43 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
115 C1.6d C1.5:768^C1.0:512^EON5:3^RP:7 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
116 C1.6l C1.5:768^C1.0:512^EON5:11^RP:60 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
117 C1.6c C1.5:768^C1.0:512^EON5:19^RP:152 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
118 C1.6w C1.5:768^C1.0:512^EON5:26^RP:260 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
119 C1.7 Терраформинг. Гамма-лазеры. 1 1 1 1 1 1 5E+03 1
120 C1.7m C1.6:896^C1.0:384^EON5:6^RP:21 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
121 C1.7b C1.6:896^C1.0:384^EON5:9^RP:43 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
122 C1.7d C1.6:896^C1.0:384^EON5:3^RP:7 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
123 C1.7l C1.6:896^C1.0:384^EON5:11^RP:60 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
124 C1.7c C1.6:896^C1.0:384^EON5:19^RP:152 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
125 C1.7w C1.6:896^C1.0:384^EON5:26^RP:260 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
126 C1.8 Космические станции континентального масштаба. 1 1 1 1 1 1 5E+03 1
127 C1.8m C1.7:1024^C1.0:256^EON5:6^RP:21 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
128 C1.8b C1.7:1024^C1.0:256^EON5:9^RP:43 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
129 C1.8d C1.7:1024^C1.0:256^EON5:3^RP:7 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
130 C1.8l C1.7:1024^C1.0:256^EON5:11^RP:60 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
131 C1.8c C1.7:1024^C1.0:256^EON5:19^RP:152 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
132 C1.8w C1.7:1024^C1.0:256^EON5:26^RP:260 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
133 C1.9 Частичный рой Дайсона. 1 1 1 1 1 1 5E+03 1
134 C1.9m C1.8:1024^C1.0:128^EON5:6^RP:21 Мистики m 2 1.6 0.009 0.01 0.0000625 0.001024
135 C1.9b C1.8:1024^C1.0:128^EON5:9^RP:43 Строители b 2 1 0.019921875 0.02 0.00003125 0.0025
136 C1.9d C1.8:1024^C1.0:128^EON5:3^RP:7 Дипломаты d 2 1 0.012 0.01538461538 0.0005 0.00015625
137 C1.9l C1.8:1024^C1.0:128^EON5:11^RP:60 Логики l 2 0.5 0.054 0.03571428571 0.0005 0.0025
138 C1.9c C1.8:1024^C1.0:128^EON5:19^RP:152 Колонисты c 2 0.8 0.0225 0.02604166667 0.004096 0.006103515625
139 C1.9w C1.8:1024^C1.0:128^EON5:26^RP:260 Воины w 2 1.25 0.028125 0.03125 0.0005 0.016384
140 C2 Цивилизации, ведущие экспансию к иным звёздам. 0
141 C2.0 1E+00 DwStar Звезда Цивилизация, освоившая энергию родного солнца. 1 1 1 1 1 1 1 1 5E+03 1
142 C2.0m C1.9:1024^C1.0:128^RP:28 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
143 C2.0b C1.9:1024^C1.0:128^EON5:9^RP:59 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
144 C2.0d C1.9:1024^C1.0:128^EON5:3^RP:8 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
145 C2.0l C1.9:1024^C1.0:128^EON5:11^RP:85 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
146 C2.0c C1.9:1024^C1.0:128^EON5:19^RP:235 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
147 C2.0w C1.9:1024^C1.0:128^EON5:26^RP:419 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
148 C2.1 1E+01 DwStar Изменение планетарных орбит. 1 1 1 1 1 1 1 1 5E+03 5.62E-01
149 C2.1m C2.0:1 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
150 C2.1b C2.0:1 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
151 C2.1d C2.0:1 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
152 C2.1l C2.0:1 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
153 C2.1c C2.0:1 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
154 C2.1w C2.0:1 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
155 C2.2 1E+02 DwStar Управление инерцией. 1 1 1 1 1 1 1 1 1E+04 3.16E-01
156 C2.2m C2.1:1024^C2.0:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
157 C2.2b C2.1:1024^C2.0:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
158 C2.2d C2.1:1024^C2.0:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
159 C2.2l C2.1:1024^C2.0:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
160 C2.2c C2.1:1024^C2.0:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
161 C2.2w C2.1:1024^C2.0:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
162 C2.3 1E+03 DwStar Рассеянное звёздное скопление Сбор вещества со звёзд. 1 1 1 1 1 1 1 1 2E+04 1.78E-01
163 C2.3m C2.2:1024^C2.1:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
164 C2.3b C2.2:1024^C2.1:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
165 C2.3d C2.2:1024^C2.1:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
166 C2.3l C2.2:1024^C2.1:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
167 C2.3c C2.2:1024^C2.1:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
168 C2.3w C2.2:1024^C2.1:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
169 C2.4 1E+04 DwStar Малое звёздное скопление Фемтотехнологии: управление отдельными фермионами. 1 1 1 1 1 1 1 1 2E+04 1.00E-01
170 C2.4m C2.3:1024^C2.2:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
171 C2.4b C2.3:1024^C2.2:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
172 C2.4d C2.3:1024^C2.2:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
173 C2.4l C2.3:1024^C2.2:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
174 C2.4c C2.3:1024^C2.2:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
175 C2.4w C2.3:1024^C2.2:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
176 C2.5 1E+05 DwStar Звёздное скопление Деконструкция и сборка планет. 1 1 1 1 1 1 1 1 3E+04 5.62E-02
177 C2.5m C2.4:1024^C2.3:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
178 C2.5b C2.4:1024^C2.3:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
179 C2.5d C2.4:1024^C2.3:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
180 C2.5l C2.4:1024^C2.3:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
181 C2.5c C2.4:1024^C2.3:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
182 C2.5w C2.4:1024^C2.3:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
183 C2.6 1E+06 DwStar Большое звёздное скопление Астроархитектурная доминанта. 1 1 1 1 1 1 1 1 3E+04 3.16E-02
184 C2.6m C2.5:1024^C2.4:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
185 C2.6b C2.5:1024^C2.4:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
186 C2.6d C2.5:1024^C2.4:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
187 C2.6l C2.5:1024^C2.4:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
188 C2.6c C2.5:1024^C2.4:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
189 C2.6w C2.5:1024^C2.4:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
190 C2.7 1E+07 GiStar Гигантское звёздное скопление Освоение ресурсов звёзд-гигантов. 1 1 1 1 1 1 1 1 4E+04 1.78E-02
191 C2.7m C2.6:1024^C2.5:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
192 C2.7b C2.6:1024^C2.5:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
193 C2.7d C2.6:1024^C2.5:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
194 C2.7l C2.6:1024^C2.5:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
195 C2.7c C2.6:1024^C2.5:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
196 C2.7w C2.6:1024^C2.5:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
197 C2.8 1E+08 GiStar Управление гравитацией. 1 1 1 1 1 1 1 1 4E+04 1.00E-02
198 C2.8m C2.7:1024^C2.6:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
199 C2.8b C2.7:1024^C2.6:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
200 C2.8d C2.7:1024^C2.6:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
201 C2.8l C2.7:1024^C2.6:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
202 C2.8c C2.7:1024^C2.6:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
203 C2.8w C2.7:1024^C2.6:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
204 C2.9 1E+09 GiStar Карликовая галактика Перемещение звёзд. 1 1 1 1 1 1 1 1 5E+04 5.62E-03
205 C2.9m C2.8:1024^C2.7:6 Мистики m 2 1.6 0.006 0.01 0.0005 0.00128 1
206 C2.9b C2.8:1024^C2.7:9 Строители b 2 1 0.02125 0.015625 0.00003125 0.0025 0.64
207 C2.9d C2.8:1024^C2.7:3 Дипломаты d 2 1 0.0128 0.01923076923 0.0009765625 0.0003125 2.56
208 C2.9l C2.8:1024^C2.7:11 Логики l 2 0.5 0.0576 0.04464285714 0.0005 0.0025 1.5625
209 C2.9c C2.8:1024^C2.7:19 Колонисты c 2 0.8 0.024 0.04166666667 0.004096 0.006103515625 1
210 C2.9w C2.8:1024^C2.7:26 Воины w 2 1.25 0.03 0.025 0.000256 0.03072 0.25
211 C3 Цивилизации галактического масштаба. 0
212 C3.0 1E+10 GiStar Малая галактика Экспансия в группу галактик. 1 1 1 1 1 1 1 1 1E+05 3.16E-03
213 C3.0m C2.9:1024^C2.8:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
214 C3.0b C2.9:1024^C2.8:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
215 C3.0d C2.9:1024^C2.8:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
216 C3.0l C2.9:1024^C2.8:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
217 C3.0c C2.9:1024^C2.8:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
218 C3.0w C2.9:1024^C2.8:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
219 C3.1 1E+11 GiStar Средняя галактика Создание звёзд. 1 1 1 1 1 1 1 1 1E+05 1.78E-03
220 C3.1m C3.0:1024^C2.9:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
221 C3.1b C3.0:1024^C2.9:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
222 C3.1d C3.0:1024^C2.9:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
223 C3.1l C3.0:1024^C2.9:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
224 C3.1c C3.0:1024^C2.9:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
225 C3.1w C3.0:1024^C2.9:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
226 C3.2 1E+12 WD Большая галактика Использование белых карликов. 1 1 1 1 1 1 1 1 2E+05 1.00E-03
227 C3.2m C3.1:1024^C3.0:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
228 C3.2b C3.1:1024^C3.0:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
229 C3.2d C3.1:1024^C3.0:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
230 C3.2l C3.1:1024^C3.0:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
231 C3.2c C3.1:1024^C3.0:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
232 C3.2w C3.1:1024^C3.0:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
233 C3.3 1E+13 WD Гигантская галактика Создание чёрных дыр из концентрированного излучения. 1 1 1 1 1 1 1 1 3E+05 5.62E-04
234 C3.3m C3.2:1024^C3.1:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
235 C3.3b C3.2:1024^C3.1:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
236 C3.3d C3.2:1024^C3.1:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
237 C3.3l C3.2:1024^C3.1:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
238 C3.3c C3.2:1024^C3.1:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
239 C3.3w C3.2:1024^C3.1:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
240 C3.4 1E+14 WD Группа галактик Экспансия в сверхскопление. 1 1 1 1 1 1 1 1 4E+05 3.16E-04
241 C3.4m C3.3:1024^C3.2:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
242 C3.4b C3.3:1024^C3.2:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
243 C3.4d C3.3:1024^C3.2:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
244 C3.4l C3.3:1024^C3.2:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
245 C3.4c C3.3:1024^C3.2:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
246 C3.4w C3.3:1024^C3.2:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
247 C3.5 1E+15 NS Использование нейтронных звёзд. 1 1 1 1 1 1 1 1 5E+05 1.78E-04
248 C3.5m C3.4:1024^C3.3:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
249 C3.5b C3.4:1024^C3.3:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
250 C3.5d C3.4:1024^C3.3:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
251 C3.5l C3.4:1024^C3.3:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
252 C3.5c C3.4:1024^C3.3:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
253 C3.5w C3.4:1024^C3.3:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
254 C3.6 1E+16 NS Сверхскопление Экспансия в нить. 1 1 1 1 1 1 1 1 6E+05 1.00E-04
255 C3.6m C3.5:1024^C3.4:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
256 C3.6b C3.5:1024^C3.4:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
257 C3.6d C3.5:1024^C3.4:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
258 C3.6l C3.5:1024^C3.4:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
259 C3.6c C3.5:1024^C3.4:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
260 C3.6w C3.5:1024^C3.4:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
261 C3.7 1E+17 MGT Использование магнетаров. 1 1 1 1 1 1 1 1 7E+05 5.62E-05
262 C3.7m C3.6:1024^C3.5:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
263 C3.7b C3.6:1024^C3.5:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
264 C3.7d C3.6:1024^C3.5:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
265 C3.7l C3.6:1024^C3.5:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
266 C3.7c C3.6:1024^C3.5:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
267 C3.7w C3.6:1024^C3.5:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
268 C3.8 1E+18 MGT Галактическая нить Экспансия в великую стену. 1 1 1 1 1 1 1 1 8E+05 3.16E-05
269 C3.8m C3.7:1024^C3.6:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
270 C3.8b C3.7:1024^C3.6:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
271 C3.8d C3.7:1024^C3.6:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
272 C3.8l C3.7:1024^C3.6:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
273 C3.8c C3.7:1024^C3.6:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
274 C3.8w C3.7:1024^C3.6:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
275 C3.9 1E+19 BH Использование чёрных дыр. 1 1 1 1 1 1 1 1 9E+05 1.78E-05
276 C3.9m C3.8:1024^C3.7:6 Мистики m 2 1.6 0.006375 0.01 0.0005 0.00128 1
277 C3.9b C3.8:1024^C3.7:9 Строители b 2 1 0.022578125 0.015625 0.00003125 0.0025 0.64
278 C3.9d C3.8:1024^C3.7:3 Дипломаты d 2 1 0.0136 0.01923076923 0.0009765625 0.0003125 2.56
279 C3.9l C3.8:1024^C3.7:11 Логики l 2 0.5 0.0612 0.04464285714 0.0005 0.0025 1.5625
280 C3.9c C3.8:1024^C3.7:19 Колонисты c 2 0.8 0.0255 0.04166666667 0.004096 0.006103515625 1
281 C3.9w C3.8:1024^C3.7:26 Воины w 2 1.25 0.031875 0.025 0.000256 0.03072 0.25
282 C4 Цивилизации вселенского масштаба. 0
283 C4.0 1E+20 BH Манипуляции со временем. 1 1 1 1 1 1 1 1 2E+06 1.00E-05
284 C4.0m C3.9:1024^C3.8:6 Мистики m 2 1.6 0.00675 0.01 0.0005 0.00128 1
285 C4.0b C3.9:1024^C3.8:9 Строители b 2 1 0.02390625 0.015625 0.00003125 0.0025 0.64
286 C4.0d C3.9:1024^C3.8:3 Дипломаты d 2 1 0.0144 0.01923076923 0.0009765625 0.0003125 2.56
287 C4.0l C3.9:1024^C3.8:11 Логики l 2 0.5 0.0648 0.04464285714 0.0005 0.0025 1.5625
288 C4.0c C3.9:1024^C3.8:19 Колонисты c 2 0.8 0.027 0.04166666667 0.004096 0.006103515625 1
289 C4.0w C3.9:1024^C3.8:26 Воины w 2 1.25 0.03375 0.025 0.000256 0.03072 0.25
290 C4.1 1E+21 BH Великая стена Экспансия на масштабы всей вселенной. 1 1 1 1 1 1 1 1 2E+06 5.62E-06
291 C4.1m C4.0:1024^C3.9:6 Мистики m 2 1.6 0.00675 0.01 0.0005 0.00128 1
292 C4.1b C4.0:1024^C3.9:9 Строители b 2 1 0.02390625 0.015625 0.00003125 0.0025 0.64
293 C4.1d C4.0:1024^C3.9:3 Дипломаты d 2 1 0.0144 0.01923076923 0.0009765625 0.0003125 2.56
294 C4.1l C4.0:1024^C3.9:11 Логики l 2 0.5 0.0648 0.04464285714 0.0005 0.0025 1.5625
295 C4.1c C4.0:1024^C3.9:19 Колонисты c 2 0.8 0.027 0.04166666667 0.004096 0.006103515625 1
296 C4.1w C4.0:1024^C3.9:26 Воины w 2 1.25 0.03375 0.025 0.000256 0.03072 0.25
297 C4.2 1E+22 SMBH Использование сверхмассивных чёрных дыр. 1 1 1 1 1 1 1 1 4E+06 3.16E-06
298 C4.2m C4.1:1024^C4.0:6 Мистики m 2 1.6 0.00675 0.01 0.0005 0.00128 1
299 C4.2b C4.1:1024^C4.0:9 Строители b 2 1 0.02390625 0.015625 0.00003125 0.0025 0.64
300 C4.2d C4.1:1024^C4.0:3 Дипломаты d 2 1 0.0144 0.01923076923 0.0009765625 0.0003125 2.56
301 C4.2l C4.1:1024^C4.0:11 Логики l 2 0.5 0.0648 0.04464285714 0.0005 0.0025 1.5625
302 C4.2c C4.1:1024^C4.0:19 Колонисты c 2 0.8 0.027 0.04166666667 0.004096 0.006103515625 1
303 C4.2w C4.1:1024^C4.0:26 Воины w 2 1.25 0.03375 0.025 0.000256 0.03072 0.25
304 C4.3 1E+23 SMBH Складное пространство. 1 1 1 1 1 1 1 1 6E+06 1.78E-06
305 C4.3m C4.2:1024^C4.1:6 Мистики m 2 1.6 0.00675 0.01 0.0005 0.00128 1
306 C4.3b C4.2:1024^C4.1:9 Строители b 2 1 0.02390625 0.015625 0.00003125 0.0025 0.64
307 C4.3d C4.2:1024^C4.1:3 Дипломаты d 2 1 0.0144 0.01923076923 0.0009765625 0.0003125 2.56
308 C4.3l C4.2:1024^C4.1:11 Логики l 2 0.5 0.0648 0.04464285714 0.0005 0.0025 1.5625
309 C4.3c C4.2:1024^C4.1:19 Колонисты c 2 0.8 0.027 0.04166666667 0.004096 0.006103515625 1
310 C4.3w C4.2:1024^C4.1:26 Воины w 2 1.25 0.03375 0.025 0.000256 0.03072 0.25
311 C4.4 1E+24 SMBH Вселенский пузырь Поле невероятности. 1 1 1 1 1 1 1 1 8E+06 1.00E-06
312 C4.4m C4.3:1024^C4.2:6 Мистики m 2 1.6 0.00675 0.01 0.0005 0.00128 1
313 C4.4b C4.3:1024^C4.2:9 Строители b 2 1 0.02390625 0.015625 0.00003125 0.0025 0.64
314 C4.4d C4.3:1024^C4.2:3 Дипломаты d 2 1 0.0144 0.01923076923 0.0009765625 0.0003125 2.56
315 C4.4l C4.3:1024^C4.2:11 Логики l 2 0.5 0.0648 0.04464285714 0.0005 0.0025 1.5625
316 C4.4c C4.3:1024^C4.2:19 Колонисты c 2 0.8 0.027 0.04166666667 0.004096 0.006103515625 1
317 C4.4w C4.3:1024^C4.2:26 Воины w 2 1.25 0.03375 0.025 0.000256 0.03072 0.25
318 Ct Трансцендентальность. 0 1
-3
View File
@@ -1,3 +0,0 @@
ID | Name | Age | Email
1 | John | 30 | john@example.com
2 | Jane | 25 | jane@example.com
1 ID Name Age Email
2 1 John 30 john@example.com
3 2 Jane 25 jane@example.com
-130
View File
@@ -1,130 +0,0 @@
Owniverse||interface||||
MM-Create||interface||||Menu/en/CreateUniverse
MM-Help||interface||||Menu/en/Tutorial
MM-Achievments||interface||||Menu/en/Achievements
MM-Credits||interface||||Menu/en/Credits
MM-LanguageEn||interface||||Menu/en/EnglishActive
MM-LanguageRu||interface||||Menu/en/Russian
MM-SoundActive||interface||||Menu/en/SoundActive
MM-SoundNonActive||interface||||Menu/en/SoundNonActive
MM-MusicActive||interface||||Menu/en/MusicActive
MM-MusicNonActive||interface||||Menu/en/MusicNonActive
MM-LeaveReality||interface||||Menu/en/LeaveReality
CreditsTitle||interface||||Credits/en/Credits
CreditsRoles||interface||Unitizer <br> Python Tamer <br> Painter <br> Original Score by||
CreditsNames||interface||Kirill Ivlev <br> Ilya Konovalov <br> Dmitry Uvarov <br> Tatyana Stepanenko||
Achievement-Header||interface||||Achievements/en/Achievements
Achievement-Status-Template||interface||Unlocked %Count% of %Total%||
ReportTitle||interface||||Report/en/Title
ReportNewWarning||interface||||Report/en/NewWarning
ReportNewButton||interface||||Report/en/NewButton
ReportWipeWarning||interface||||Report/en/WipeWarning
ReportWipeButton||interface||||Report/en/WipeButton
MF-FBV-ReturnButton||interface||||Dashboard/Indicators/ForceBoxes/En/Return
MF-FBV-OpenBoxButton||interface||||Dashboard/Indicators/ForceBoxes/En/OpenBox
MF-FBV-AcquireButton||interface||||Dashboard/Indicators/ForceBoxes/En/Acquire
MF-FBV-NoAdsDeliveredSign||interface||||Dashboard/Indicators/ForceBoxes/En/NoAds
Universe||interface||||
Time|Time|indicator|AboutTheGame|Time|Change the speed as you like.|
Energy|Enr|indicator|EnergyAndDensity|Energy|Spend on hydrogen and space.|
Density|Den|indicator|EnergyAndDensity|Density|Maintain balance.|
DensityRip|DenR|indicator|EnergyAndDensity|Big Rip|Increase density!|
DensityCrunch|DenC|indicator|EnergyAndDensity|Big Crunch|Decrease density!|
BurnabilityIndicator|Bur|indicator|BurnabilityAndExplosiveness|Burnability|Burning intensity of stars.|
ExplosivenessIndicator|Exp|indicator|BurnabilityAndExplosiveness|Explosiveness|Power of stellar explosions.|
AggressionIndicator|Agg|indicator|AggressionAndTrends|Aggression|Evolution and competition.|
||||1 year per second||
||||10 years per second||
||||100 years per second||
||||1 000 years per second||
||||10 000 years per second||
||||100 000 years per second||
||||1 000 000 years per second||
||||10 000 000 years per second||
||||100 000 000 years per second||
||||1 000 000 000 years per second||
||logtext||Summary of changes in the last 100 seconds.<br>Average values for the year are shown.||
ForceNavigationImage||interface||||BigBang/Dashboard/en/Forces
1-1-1-NavigationResourceImage||interface||||BigBang/Dashboard/en/Resources
Space|S|entity|SpaceAndHydrogen|Space|Needed for placing objects.|
Hydrogen|H|entity|SpaceAndHydrogen|Hydrogen|Used to create clouds and stars.|
Helium|He|entity|HeliumAndMetals|Helium|Saves hydrogen.|
Metals|Met|entity|HeliumAndMetals|Metals|Needed to create planets.|
||||Metallicity||
NavigationStarImage||interface||||BigBang/Dashboard/en/Stars
Nebula|N|entity|Clouds|Nebula|Produces hydrogen.|
Globula|G|entity|Clouds|Globula|Produces more hydrogen.|
StarNursery|STN|entity|Clouds|Star Nursery|Produces hydrogen and stars.|
MolecularCloud|MC|entity|Clouds|Molecular Cloud|Produces a lot of hydrogen.|
ActiveStarNursery|ASTN|entity|Clouds|Active Star Nursery|Produces a lot of hydrogen and stars.|
BrownDwarf|BD|entity|DwarfStars|Brown Dwarf|Useless, but doesn't take up space.|
RedDwarf|RD|entity|DwarfStars|Red Dwarf|The simplest star.|
OrangeDwarf|OD|entity|DwarfStars|Orange Dwarf|Star with planets.|
YellowDwarf|YD|entity|DwarfStars|Yellow Dwarf|Star similar to the Sun.|
WhiteYellowDwarf|WYD|entity|DwarfStars|White-Yellow Dwarf|Star with many planets.|
RedGiant|RG|entity|GiantStars|Red Giant|Degrading old star.|
YellowGiant|YG|entity|GiantStars|Yellow Giant|Optimal for metals production.|
BlueGiant|BG|entity|GiantStars|Blue Giant|Produces metals and space in a balanced manner.|
Supergiant|SG|entity|GiantStars|Supergiant|Produces space and a bit of metals quickly.|
Hypergiant|HG|entity|GiantStars|Hypergiant|Burns violently, creating a lot of space.|
WhiteDwarf|WD|entity|DegenerateObjects|White Dwarf|Remnant of a dwarf star.|
NeutronStar|NS|entity|DegenerateObjects|Neutron Star|Remnant of a burned-out giant.|
Magnetar|MGT|entity|DegenerateObjects|Magnetar|Remnant of a large giant.|
BlackHole|BH|entity|DegenerateObjects|Black Hole|The result of a stellar catastrophe. Needed for structures.|
SupermassiveBlackHole|SMBH|entity|DegenerateObjects|Supermassive Black Hole|Merged from black holes. Needed for galaxies.|
1-3-1-NavigationStructureImage||interface||||BigBang/Dashboard/en/Structures
StarClusterScattered|SCD|entity|StarClusters|Scattered Star Cluster|A little structure of irregular shape.<br>Space: +10%.|
StarClusterSmall|SCS|entity|StarClusters|Small Star Cluster|Has globular shape.<br>Space: +20%.|
StarClusterMedium|SCM|entity|StarClusters|Medium Star Cluster|Noticeable from afar off.<br>Space: +30%.|
StarClusterLarge|SCL|entity|StarClusters|Large Star Cluster|Makes an impression.<br>Space: +50%.|
StarClusterGiant|SCG|entity|StarClusters|Giant Star Cluster|Causes awe.<br>Space: +80%.|
GalaxyEllipticalDwarf|GED|entity|Galaxies|Dwarf Elliptical Galaxy|The size of the Small Magellanic Cloud.<br>Space: +100%.|
GalaxyEllipticalSmall|GES|entity|Galaxies|Small Elliptical Galaxy|The size of the Large Magellanic Cloud.<br>Space: +150%.|
GalaxyEllipticalMedium|GEM|entity|Galaxies|Medium Elliptical Galaxy|The size of the Milky Way.<br>Space: +200%.|
GalaxyEllipticalLarge|GEL|entity|Galaxies|Large Elliptical Galaxy|The size of the Andromeda Galaxy.<br>Space: +300%.|
GalaxyEllipticalGiant|GEG|entity|Galaxies|Giant Elliptical Galaxy|Similar to the IC 1101.<br>Space: +450%.|
GalaxySpiralDwarf|GSD|entity|Galaxies|Dwarf Spiral Galaxy|Similar to the Small Magellanic Cloud.|
GalaxySpiralSmall|GSS|entity|Galaxies|Small Spiral Galaxy|Similar to the Large Magellanic Cloud.|
GalaxySpiralMedium|GSM|entity|Galaxies|Medium Spiral Galaxy|Similar to the Milky Way.|
GalaxySpiralLarge|GSL|entity|Galaxies|Large Spiral Galaxy|Similar to the Andromeda Galaxy.|
GalaxySpiralGiant|GSG|entity|Galaxies|Giant Spiral Galaxy|The size of the IC 1101.|
GalacticGroup|LGG|entity|LargeStructures|Galactic Group|Aggregates galaxies.|
GalacticSupercluster|LSC|entity|LargeStructures|Galactic Supercluster|Basis for the structure of the universe.|
GalacticFilament|LGF|entity|LargeStructures|Galactic Filament|Balances density with voids.|
GalacticWall|LGW|entity|LargeStructures|Great Wall|Creates the structure of the universe.|
UniverseBubble|LUB|entity|LargeStructures|Universe Bubble|That's the extent of it.|
1-4-1-NavigationLifeImage||interface||||BigBang/Dashboard/en/Planets
GasGiant|GG|entity|Planets|Gas Giant|Too big.|
AsteroidBelt|AB|entity|Planets|Asteroids|A bunch of rocks.|
RockyPlanet|RP|entity|Planets|Rocky Planet|Not suitable for life.|
HabitablePlanet|HP|entity|Planets|Habitable Planet|Has the potential for life.|
LivingPlanet|LP|entity|Planets|Living Planet|There is life on this planet!|
|Star|||Star||
|SC|||Star Cluster||
|GAL|||Galaxy||
AboutTheGame||help||About The Game|In this game you can <b>create a universe</b> and control its development. The final goal is designated by yourself. Don't forget to check out the list of game achievements and try to reach some of the ones that seem interesting. Read hints, explore possibilities and don't be afraid to experiment. In the worst case you can always start from scratch.<br><br>Numbers greater than 1 000 are displayed using <b>scientific notation</b>. 1e4 – this is a 10 000, meaning “one with 4 zeroes”. 1e6 – a million, 1e9 – a billion and so on. 13.77e9 – this is 13 billions 770 millions.<br><br>The game plays in <b>real time</b> with changeable scaling. One second of real time can pass a year, a decade, a century and so on. Change the pace of time by using buttons “−” and “+”.|Help/en/AboutTheGame
GameplayBasics||help||Gameplay Basics|You have access to a very large, but still limited <b>cache of energy</b> that is used to create the whole matter in the universe and the expanse of the universe's space itself. At the start of the game the vast majority of this energy is not in your direct control. But during the game you will take more and more energy from the cache. The less filled the cache is, the harder it is to obtain new energy. The energy shortage won’t become an urgent problem in the first billion years or so: the cache is really very large.<br><br>The matter is harvested from the energy cache in the form of <b>hydrogen</b> by clouds. Hydrogen may be spent to create new clouds and also to create stars. During their burning stars create <b>space</b> that can be used to place additional stars and clouds. This creation of space also spends some energy from the cache.|Help/en/GameplayBasics
StarsAndStructures||help||Stars and Structures|The heavier the star is, the faster it burns and the more space it produces. However, on the contrary, the most cost-efficient way of spending hydrogen to obtain new space, is investment into the smallest stars. Unfortunately they burn for a very long time and produce space very slowly. Also each star takes a unit of space, no matter which type the star is.<br><br>There is a reason to arrange stars and nebulae of the growing universe into galaxies and even larger <b>structures</b>. The production of space by stars is increased inside structures.<br><br>The proportion between universe matter and space is called density. The universe is only stable when the <b>density</b> is inside a certain range. If it is too packed or too empty, problems come into being.|Help/en/StarsAndStructures
LifeAndForces||help||Life and Forces|<b>Planets</b> form around certain stars, and life may emerge there. In specific circumstances life can evolve to sapience, and sapience can advance to high technology. Life's next step is to try to reclaim the universe, which she assumes as her own.<br><br>There are many events in the universe that don't happen all the time, only with certain probability. You have access to special <b>forces</b>, which you can use to “tweak” chances of events that are important to you, changing the laws of nature in the process.|Help/en/LifeAndForces
Achievements||help||Achievements|During the gameplay you will definitely be able to reach certain <b>achievements</b>. While simpler ones come by themselves, ones that are more complex may be more tricky. You can use the achievements list as a roadmap of hints and suggestions for possible next steps.<br><br>It is unnecessary to try to finish each and every achievement. This is your own universe and you can do whatever you like with it. However, achievements are a nice thing in general, and besides just having a personal feeling of pride and accomplishment you can easily <b>share</b> it with friends!|Help/en/Achievements
Karma||help||Karma|Each obtained achievement grants you a certain number of <b>karmic points</b>. During the new universe creation you may spend these points to gain some small bonuses that will definitely help you to gain better results.<br><br>Spent karmic points are not lost: they will be <b>available</b> for spending again in the next universe. There is a chance that there will be even more of them at that moment.|Help/en/Karma
Gauges||help||Gauges|<b>Gauges</b> of measures that are especially important for an active objects page are located on the dashboard. To check other gauges just swipe the page.|Help/en/Gauges
EnergyAndDensity||help||Energy and Density|<b>Energy</b> from the cache is converted into hydrogen and space. The lower the proportion of remaining cache, indicated in the middle of the bar, the lower is the efficiency of the resource generators, such as clouds for hydrogen and stars for space.<br>The energy cache really is immense, however it is not infinite.<br><br>Average <b>density</b> of the universe is the ratio of total matter mass, meaning all stars, clouds and so on, to the empty space. It increases alongside the mass and decreases when the space grows. If the “ρ” gauge will leave the “middle zone” and become inclined to any of the two extremeties, then the outcome might surprise you in a bad way.|Help/en/EnergyAndDensity
BurnabilityAndExplosiveness||help||Burnability and Explosiveness|<b>Burnability</b> displays the current burning rate of stars. It can be influenced by the universe density (the denser the greater), the actions of superadvanced civilizations and the forces used by the player.<br><br><b>Explosiveness</b> displays the current probability of the gamma-ray bursts and the space yield produced by any sort of star collapses. It can be influenced by universe density (the denser the lower), actions of superadvanced civilizations and forces used by the player.|Help/en/BurnabilityAndExplosiveness
AggressionAndTrends||help||Aggression and Trends|<b>Aggression</b> displays the intensity of competition between species, civilizations and their inner factions. It governs the progress and stability of life and societies. It can be influenced by universal trends and forces used by the player.<br>By default the average universal aggression is shown. But you can select any civilization level and observe the average aggression for this level, which can be different from the universal one.<br><br><b>Trends</b> are the results of prolonged civilization influences. There are five trends in total.|Help/en/AggressionAndTrends
SpaceAndHydrogen||help||Space and Hydrogen|The majority of creative actions require spending <b>resources</b>.<br><br><b>Space</b> is needed to place everything you are creating. To add new space lit up some stars! Also don't forget to combine the created stars into structures to get even more space.<br><br><b>Hydrogen</b> is required to create nebulae and stars. Nebulae allow you to obtain more hydrogen. Stars are used to make more space and also to harbor planets. Both of these object types also serve as building blocks to create more complex structures.|Help/en/SpaceAndHydrogen
HeliumAndMetals||help||Helium and Metals|Helium and metals are obtained when stars finish their life cycle.<br><b>Helium</b> is not especially useful, but it is inevitable. It is automatically spent in a line of hydrogen if possible, conserving the more valuable resource.<br><br><b>Metals</b> “contaminate” your hydrogen and helium by heavier elements. And usually it is a good thing, because the high proportion of metals to hydrogen and helium, also known as “metallicity”, provides for a greater chance for planets to emerge near new stars.<br>Metals are added when stars burn out, especially larger ones. But total metellicity may shrink down when the universe is filled by new objects made from pure hydrogen and helium, such as nebulae and stars.|Help/en/HeliumAndMetals
Clouds||help||Clouds|Clouds are used to produce hydrogen, which is required to construct the universe. Simplest nebulae can be arranged into more complex cloud structures.<br><br><b>Nebula:</b> the simplest of clouds.<br><b>Globula:</b> provides hydrogen at a slower rate than nebulae, but persists for longer, and also takes less space. Used in creation of larger clouds.<br><b>Star nursery:</b> automatically creates stars from a fraction of provided hydrogen.<br><b>Molecular cloud:</b> large and long-lasting hydrogen generator.<br><b>Active star nursery:</b> very large automatic hydrogen and stars generator.|Help/en/Clouds
DwarfStars||help||Dwarf Stars|Dwarf stars are cheap, they last for a long time and produce space efficiently. They can have planets that sometimes may harbor life at some point.<br><br><b>Brown dwarf:</b> useless rejects that happen during the star creation process. They appear by themselves and do not take space as opposed to all the other stars. Can’t be created manually, and you don’t need to.<br><b>Red dwarf:</b> It is cost-effective in space creation, but works very slowly.<br><b>Orange dwarf:</b> perfect for the development of life.<br><b>Yellow dwarf:</b> good for the emergence of life.<br><b>White-yellow dwarf:</b> has a largest habitable zone, but burns out rapidly.|Help/en/DwarfStars
GiantStars||help||Giant Stars|Giant stars burn rapidly and produce a lot of space. At the end of their existence they collapse. These events can damage planets at nearby stars, but they produce metals.<br><br><b>Red giant:</b> a star that has consumed the majority of its fuel. You can’t create these manually, they emerge themselves.<br><b>Yellow giant:</b> the most modest of giant stars. Produces a lot of metals, collapse is weak.<br><b>Blue giant:</b> a common giant star. Produces a good amount of space and metals. Collapse is average.<br><b>Supergiant:</b> huge giant star. Lives short, collapses violently, produces a lot of space and few metals.<br><b>Hypergiant:</b> extremely giant star. Always collapses into a black hole, producing a huge amount of space, which is accompanied by insane destruction.|Help/en/GiantStars
DegenerateObjects||help||Degenerate Objects|Stars that have exhausted their fusion fuel. They occupy space and do not produce anything, but can be used in forming structures.<br><br><b>White dwarf:</b> the remains of a dwarf star.<br><b>Neutron star:</b> exceptionally compact remains of a giant star.<br><b>Magnetar:</b> the most dense object that is not a black hole.<br><b>Black hole:</b> the remains of a giant star that experienced a destructive collapse. They may be merged into supermassive black holes.<br><b>Supermassive black hole:</b> the result of multitudes of the stellar mass black holes merged into one. Required for galactic formation. They do grow in time, consuming other stars, but do so very slowly.|Help/en/DegenerateObjects
StarClusters||help||Star Clusters|Star clusters are the most modest of available structures. As a matter of fact these are just a lot of stars which are co-located closer to each other than usual, and therefore they are gravitationally bound. But even such simple lumps already bring noticeable variety into the homogenous landscape of the universe.<br><br><b>Scattered:</b> little structure of irregular shape.<br><b>Small:</b> globular shape.<br><b>Medium:</b> noticeable from afar off.<br><b>Large:</b> makes an impression.<br><b>Giant:</b> causes awe.<br><br>Clusters, like other structures, increase the production of space for their constituent stars. Stars in structures exist as usual. Over time, the clusters disintegrate, releasing the stars they are composed of. Large clusters last longer than small ones and provide a larger bonus to space production.|Help/en/StarClusters
Galaxies||help||Galaxies|<b>Elliptical galaxies</b> resemble colossal star clusters. They have lenticular shapes, rotate slowly and look very much alike to each other. The stars in them produce more space than in spiral galaxies. Gradually, elliptical galaxies disintegrate into separate stars.<br><br><b>Spiral galaxies</b> spin faster than elliptical ones, they have diverse structures with arms and keep active star formation. They are better fit for the emergence and development of life. In time spiral galaxies exhaust their storage of free gas, they slow down and become more stable and boring ellipticals.<br><br>As in the case of other structures, the stars included in the composition of galaxies continue to function as usual. They produce space, and dwarf stars can have planets.|Help/en/Galaxies
LargeStructures||help||Large Structures|<b>Large structures</b> are called that for a reason: whole galaxies are used there as building blocks. They are needed to arrange the universe on the largest scales. Without them the space, uniformly filled by stars and galaxies, becomes too monotonous and sparse, meanwile these structures create a packing gradient with more and less dense regions. This arrangement is better fit for being claimed and developed by superadvanced sapient beings.<br><br>Over time, large structures disintegrate into their components, but this does not happen very soon.|Help/en/LargeStructures
Planets||help||Planets|Planets emerge around dwarf stars when metals are sufficient. In a sense all this space construction is being made with a purpose of making planets with potential of bearing life.<br><br><b>Gas giant:</b> large planet with a very thick atmosphere, unsuitable for life.<br><b>Asteroid belt:</b> a bunch of rocks that lacks mass to form a planet.<br><b>Rocky planet:</b> a planet unsuitable for life. Too cold, hot or wrong chemical makeup.<br><b>Habitable planet:</b> there is liquid water here and life may emerge in the long run.<br><b>Living planet:</b> denizens of this planet show great promise!|Help/en/Planets
Eons||help||Eons|Life slowly evolves through eons from the most primitive one to the one with sapience potential. Not all planets are successful in completing this process to the end, because stars do not burn forever.<br><br><b>Archean:</b> it is difficult to notice, but these planets are full of archaea and cyanobacteria.<br><b>Paleozoic:</b> alongside ubiquitous amoeba these planets host algae, sponges and even molluscs.<br><b>Proterozoic:</b> ferns, worms, trilobites and fishes.<br><b>Mezozoic:</b> conifers, lizards, dinosaurs and therapsids.<br><b>Cenozoic:</b> flowering plants and various mammals, some of which show signs of sapience.|Help/en/Eons
Type0Civilizations||help||Type 0 Civilizations|Pre-space epoch – from a tribe to a federation.<br><br><b>c0.0:</b> Lower Paleolithic. Control of fire, stone tools.<br><b>c0.1:</b> Middle Paleolithic. Developed stone tools.<br><b>c0.2:</b> Upper Paleolithic. Advanced stone tools, art.<br><b>c0.3:</b> Mesolithic. Bow and arrows, fishing, boats.<br><b>c0.4:</b> Early Neolithic. Agriculture.<br><b>c0.5:</b> Middle Neolithic. Animal husbandry, ceramics.<br><b>c0.6:</b> Late Neolithic. Large settlements.<br><b>c0.7:</b> First kingdoms of copper and bronze ages. Wheel.<br><b>c0.8:</b> Ancient empires of the iron age. Philosophy.<br><b>c0.9:</b> Industrial age. Electronics and nuclear energy.|Help/en/Type0Civilizations
Type1Civilizations||help||Type 1 Civilizations|Civilizations are busy with settling their own solar system.<br><br><b>c1.0:</b> A civilization that has completely mastered its home planet. Superconductivity, controlled nuclear fusion.<br><b>c1.1:</b> Research compounds in the home system. Launch loop, space elevator.<br><b>c1.2:</b> Complete genetic tailoring. Cyborgization.<br><b>c1.3:</b> Industrial asteroid mining. Colonies on the other planets of the home system.<br><b>c1.4:</b> Harvesting of matter from atmospheres of gas giants.<br><b>c1.5:</b> Space cities. Picotechnologies.<br><b>c1.6:</b> Industrial manufacturing of antimatter. First starships.<br><b>c1.7:</b> Terraforming. Gamma-lasers.<br><b>c1.8:</b> Space stations of continental scale.<br><b>c1.9:</b> Partial Dyson swarm.|Help/en/Type1Civilizations
Type2Civilizations||help||Type 2 Civilizations|Civilizations that can expand to other stars.<br><br><b>c2.0:</b> A civilization that completely exploits the energy output of its own sun.<br><b>c2.1:</b> Change of planetary orbits.<br><b>c2.2:</b> Control over inertia.<br><b>c2.3:</b> Starlifting, harvesting matter from stars.<br><b>c2.4:</b> Femtotechnologies: manipulations on individual fermions.<br><b>c2.5:</b> Deconstruction and creation of planets.<br><b>c2.6:</b> Complete domination of astroarchitecture over planets.<br><b>c2.7:</b> Giant stars resources exploitation.<br><b>c2.8:</b> Control over gravity.<br><b>c2.9:</b> Movement of stars.|Help/en/Type2Civilizations
Type3Civilizations||help||Type 3 Civilizations|Civilizations of galactic scale.<br><br><b>c3.0:</b> Expansion into a galactic group is available.<br><b>c3.1:</b> Creation of stars.<br><b>c3.2:</b> Utilization of white dwarfs.<br><b>c3.3:</b> Creation of black holes by focused radiation.<br><b>c3.4:</b> Expansion into a galactic supercluster is available.<br><b>c3.5:</b> Utilization of neutron stars.<br><b>c3.6:</b> Expansion into a galactic filament is available.<br><b>c3.7:</b> Utilization of magnetars.<br><b>c3.8:</b> Expansion into a great wall is available.<br><b>c3.9:</b> Utilization of black holes.|Help/en/Type3Civilizations
Type4Civilizations||help||Type 4 Civilizations|Civilizations of the universe scale.<br><br><b>c4.0:</b> Temporal manipulations.<br><b>c4.1:</b> Expansion into the whole universe scale is available.<br><b>c4.2:</b> Utilization of supermassive black holes.<br><b>c4.3:</b> Folding space.<br><b>c4.4:</b> Improbability field.<br><br>And so on, bigger and bigger, so long as there is space.|Help/en/Type4Civilizations
1 Owniverse interface
2 MM-Create interface Menu/en/CreateUniverse
3 MM-Help interface Menu/en/Tutorial
4 MM-Achievments interface Menu/en/Achievements
5 MM-Credits interface Menu/en/Credits
6 MM-LanguageEn interface Menu/en/EnglishActive
7 MM-LanguageRu interface Menu/en/Russian
8 MM-SoundActive interface Menu/en/SoundActive
9 MM-SoundNonActive interface Menu/en/SoundNonActive
10 MM-MusicActive interface Menu/en/MusicActive
11 MM-MusicNonActive interface Menu/en/MusicNonActive
12 MM-LeaveReality interface Menu/en/LeaveReality
13 CreditsTitle interface Credits/en/Credits
14 CreditsRoles interface Unitizer <br> Python Tamer <br> Painter <br> Original Score by
15 CreditsNames interface Kirill Ivlev <br> Ilya Konovalov <br> Dmitry Uvarov <br> Tatyana Stepanenko
16 Achievement-Header interface Achievements/en/Achievements
17 Achievement-Status-Template interface Unlocked %Count% of %Total%
18 ReportTitle interface Report/en/Title
19 ReportNewWarning interface Report/en/NewWarning
20 ReportNewButton interface Report/en/NewButton
21 ReportWipeWarning interface Report/en/WipeWarning
22 ReportWipeButton interface Report/en/WipeButton
23 MF-FBV-ReturnButton interface Dashboard/Indicators/ForceBoxes/En/Return
24 MF-FBV-OpenBoxButton interface Dashboard/Indicators/ForceBoxes/En/OpenBox
25 MF-FBV-AcquireButton interface Dashboard/Indicators/ForceBoxes/En/Acquire
26 MF-FBV-NoAdsDeliveredSign interface Dashboard/Indicators/ForceBoxes/En/NoAds
27 Universe interface
28 Time Time indicator AboutTheGame Time Change the speed as you like.
29 Energy Enr indicator EnergyAndDensity Energy Spend on hydrogen and space.
30 Density Den indicator EnergyAndDensity Density Maintain balance.
31 DensityRip DenR indicator EnergyAndDensity Big Rip Increase density!
32 DensityCrunch DenC indicator EnergyAndDensity Big Crunch Decrease density!
33 BurnabilityIndicator Bur indicator BurnabilityAndExplosiveness Burnability Burning intensity of stars.
34 ExplosivenessIndicator Exp indicator BurnabilityAndExplosiveness Explosiveness Power of stellar explosions.
35 AggressionIndicator Agg indicator AggressionAndTrends Aggression Evolution and competition.
36 1 year per second
37 10 years per second
38 100 years per second
39 1 000 years per second
40 10 000 years per second
41 100 000 years per second
42 1 000 000 years per second
43 10 000 000 years per second
44 100 000 000 years per second
45 1 000 000 000 years per second
46 logtext Summary of changes in the last 100 seconds.<br>Average values for the year are shown.
47 ForceNavigationImage interface BigBang/Dashboard/en/Forces
48 1-1-1-NavigationResourceImage interface BigBang/Dashboard/en/Resources
49 Space S entity SpaceAndHydrogen Space Needed for placing objects.
50 Hydrogen H entity SpaceAndHydrogen Hydrogen Used to create clouds and stars.
51 Helium He entity HeliumAndMetals Helium Saves hydrogen.
52 Metals Met entity HeliumAndMetals Metals Needed to create planets.
53 Metallicity
54 NavigationStarImage interface BigBang/Dashboard/en/Stars
55 Nebula N entity Clouds Nebula Produces hydrogen.
56 Globula G entity Clouds Globula Produces more hydrogen.
57 StarNursery STN entity Clouds Star Nursery Produces hydrogen and stars.
58 MolecularCloud MC entity Clouds Molecular Cloud Produces a lot of hydrogen.
59 ActiveStarNursery ASTN entity Clouds Active Star Nursery Produces a lot of hydrogen and stars.
60 BrownDwarf BD entity DwarfStars Brown Dwarf Useless, but doesn't take up space.
61 RedDwarf RD entity DwarfStars Red Dwarf The simplest star.
62 OrangeDwarf OD entity DwarfStars Orange Dwarf Star with planets.
63 YellowDwarf YD entity DwarfStars Yellow Dwarf Star similar to the Sun.
64 WhiteYellowDwarf WYD entity DwarfStars White-Yellow Dwarf Star with many planets.
65 RedGiant RG entity GiantStars Red Giant Degrading old star.
66 YellowGiant YG entity GiantStars Yellow Giant Optimal for metals production.
67 BlueGiant BG entity GiantStars Blue Giant Produces metals and space in a balanced manner.
68 Supergiant SG entity GiantStars Supergiant Produces space and a bit of metals quickly.
69 Hypergiant HG entity GiantStars Hypergiant Burns violently, creating a lot of space.
70 WhiteDwarf WD entity DegenerateObjects White Dwarf Remnant of a dwarf star.
71 NeutronStar NS entity DegenerateObjects Neutron Star Remnant of a burned-out giant.
72 Magnetar MGT entity DegenerateObjects Magnetar Remnant of a large giant.
73 BlackHole BH entity DegenerateObjects Black Hole The result of a stellar catastrophe. Needed for structures.
74 SupermassiveBlackHole SMBH entity DegenerateObjects Supermassive Black Hole Merged from black holes. Needed for galaxies.
75 1-3-1-NavigationStructureImage interface BigBang/Dashboard/en/Structures
76 StarClusterScattered SCD entity StarClusters Scattered Star Cluster A little structure of irregular shape.<br>Space: +10%.
77 StarClusterSmall SCS entity StarClusters Small Star Cluster Has globular shape.<br>Space: +20%.
78 StarClusterMedium SCM entity StarClusters Medium Star Cluster Noticeable from afar off.<br>Space: +30%.
79 StarClusterLarge SCL entity StarClusters Large Star Cluster Makes an impression.<br>Space: +50%.
80 StarClusterGiant SCG entity StarClusters Giant Star Cluster Causes awe.<br>Space: +80%.
81 GalaxyEllipticalDwarf GED entity Galaxies Dwarf Elliptical Galaxy The size of the Small Magellanic Cloud.<br>Space: +100%.
82 GalaxyEllipticalSmall GES entity Galaxies Small Elliptical Galaxy The size of the Large Magellanic Cloud.<br>Space: +150%.
83 GalaxyEllipticalMedium GEM entity Galaxies Medium Elliptical Galaxy The size of the Milky Way.<br>Space: +200%.
84 GalaxyEllipticalLarge GEL entity Galaxies Large Elliptical Galaxy The size of the Andromeda Galaxy.<br>Space: +300%.
85 GalaxyEllipticalGiant GEG entity Galaxies Giant Elliptical Galaxy Similar to the IC 1101.<br>Space: +450%.
86 GalaxySpiralDwarf GSD entity Galaxies Dwarf Spiral Galaxy Similar to the Small Magellanic Cloud.
87 GalaxySpiralSmall GSS entity Galaxies Small Spiral Galaxy Similar to the Large Magellanic Cloud.
88 GalaxySpiralMedium GSM entity Galaxies Medium Spiral Galaxy Similar to the Milky Way.
89 GalaxySpiralLarge GSL entity Galaxies Large Spiral Galaxy Similar to the Andromeda Galaxy.
90 GalaxySpiralGiant GSG entity Galaxies Giant Spiral Galaxy The size of the IC 1101.
91 GalacticGroup LGG entity LargeStructures Galactic Group Aggregates galaxies.
92 GalacticSupercluster LSC entity LargeStructures Galactic Supercluster Basis for the structure of the universe.
93 GalacticFilament LGF entity LargeStructures Galactic Filament Balances density with voids.
94 GalacticWall LGW entity LargeStructures Great Wall Creates the structure of the universe.
95 UniverseBubble LUB entity LargeStructures Universe Bubble That's the extent of it.
96 1-4-1-NavigationLifeImage interface BigBang/Dashboard/en/Planets
97 GasGiant GG entity Planets Gas Giant Too big.
98 AsteroidBelt AB entity Planets Asteroids A bunch of rocks.
99 RockyPlanet RP entity Planets Rocky Planet Not suitable for life.
100 HabitablePlanet HP entity Planets Habitable Planet Has the potential for life.
101 LivingPlanet LP entity Planets Living Planet There is life on this planet!
102 Star Star
103 SC Star Cluster
104 GAL Galaxy
105 AboutTheGame help About The Game In this game you can <b>create a universe</b> and control its development. The final goal is designated by yourself. Don't forget to check out the list of game achievements and try to reach some of the ones that seem interesting. Read hints, explore possibilities and don't be afraid to experiment. In the worst case you can always start from scratch.<br><br>Numbers greater than 1 000 are displayed using <b>scientific notation</b>. 1e4 – this is a 10 000, meaning “one with 4 zeroes”. 1e6 – a million, 1e9 – a billion and so on. 13.77e9 – this is 13 billions 770 millions.<br><br>The game plays in <b>real time</b> with changeable scaling. One second of real time can pass a year, a decade, a century and so on. Change the pace of time by using buttons “−” and “+”. Help/en/AboutTheGame
106 GameplayBasics help Gameplay Basics You have access to a very large, but still limited <b>cache of energy</b> that is used to create the whole matter in the universe and the expanse of the universe's space itself. At the start of the game the vast majority of this energy is not in your direct control. But during the game you will take more and more energy from the cache. The less filled the cache is, the harder it is to obtain new energy. The energy shortage won’t become an urgent problem in the first billion years or so: the cache is really very large.<br><br>The matter is harvested from the energy cache in the form of <b>hydrogen</b> by clouds. Hydrogen may be spent to create new clouds and also to create stars. During their burning stars create <b>space</b> that can be used to place additional stars and clouds. This creation of space also spends some energy from the cache. Help/en/GameplayBasics
107 StarsAndStructures help Stars and Structures The heavier the star is, the faster it burns and the more space it produces. However, on the contrary, the most cost-efficient way of spending hydrogen to obtain new space, is investment into the smallest stars. Unfortunately they burn for a very long time and produce space very slowly. Also each star takes a unit of space, no matter which type the star is.<br><br>There is a reason to arrange stars and nebulae of the growing universe into galaxies and even larger <b>structures</b>. The production of space by stars is increased inside structures.<br><br>The proportion between universe matter and space is called density. The universe is only stable when the <b>density</b> is inside a certain range. If it is too packed or too empty, problems come into being. Help/en/StarsAndStructures
108 LifeAndForces help Life and Forces <b>Planets</b> form around certain stars, and life may emerge there. In specific circumstances life can evolve to sapience, and sapience can advance to high technology. Life's next step is to try to reclaim the universe, which she assumes as her own.<br><br>There are many events in the universe that don't happen all the time, only with certain probability. You have access to special <b>forces</b>, which you can use to “tweak” chances of events that are important to you, changing the laws of nature in the process. Help/en/LifeAndForces
109 Achievements help Achievements During the gameplay you will definitely be able to reach certain <b>achievements</b>. While simpler ones come by themselves, ones that are more complex may be more tricky. You can use the achievements list as a roadmap of hints and suggestions for possible next steps.<br><br>It is unnecessary to try to finish each and every achievement. This is your own universe and you can do whatever you like with it. However, achievements are a nice thing in general, and besides just having a personal feeling of pride and accomplishment you can easily <b>share</b> it with friends! Help/en/Achievements
110 Karma help Karma Each obtained achievement grants you a certain number of <b>karmic points</b>. During the new universe creation you may spend these points to gain some small bonuses that will definitely help you to gain better results.<br><br>Spent karmic points are not lost: they will be <b>available</b> for spending again in the next universe. There is a chance that there will be even more of them at that moment. Help/en/Karma
111 Gauges help Gauges <b>Gauges</b> of measures that are especially important for an active objects page are located on the dashboard. To check other gauges just swipe the page. Help/en/Gauges
112 EnergyAndDensity help Energy and Density <b>Energy</b> from the cache is converted into hydrogen and space. The lower the proportion of remaining cache, indicated in the middle of the bar, the lower is the efficiency of the resource generators, such as clouds for hydrogen and stars for space.<br>The energy cache really is immense, however it is not infinite.<br><br>Average <b>density</b> of the universe is the ratio of total matter mass, meaning all stars, clouds and so on, to the empty space. It increases alongside the mass and decreases when the space grows. If the “ρ” gauge will leave the “middle zone” and become inclined to any of the two extremeties, then the outcome might surprise you in a bad way. Help/en/EnergyAndDensity
113 BurnabilityAndExplosiveness help Burnability and Explosiveness <b>Burnability</b> displays the current burning rate of stars. It can be influenced by the universe density (the denser the greater), the actions of superadvanced civilizations and the forces used by the player.<br><br><b>Explosiveness</b> displays the current probability of the gamma-ray bursts and the space yield produced by any sort of star collapses. It can be influenced by universe density (the denser the lower), actions of superadvanced civilizations and forces used by the player. Help/en/BurnabilityAndExplosiveness
114 AggressionAndTrends help Aggression and Trends <b>Aggression</b> displays the intensity of competition between species, civilizations and their inner factions. It governs the progress and stability of life and societies. It can be influenced by universal trends and forces used by the player.<br>By default the average universal aggression is shown. But you can select any civilization level and observe the average aggression for this level, which can be different from the universal one.<br><br><b>Trends</b> are the results of prolonged civilization influences. There are five trends in total. Help/en/AggressionAndTrends
115 SpaceAndHydrogen help Space and Hydrogen The majority of creative actions require spending <b>resources</b>.<br><br><b>Space</b> is needed to place everything you are creating. To add new space lit up some stars! Also don't forget to combine the created stars into structures to get even more space.<br><br><b>Hydrogen</b> is required to create nebulae and stars. Nebulae allow you to obtain more hydrogen. Stars are used to make more space and also to harbor planets. Both of these object types also serve as building blocks to create more complex structures. Help/en/SpaceAndHydrogen
116 HeliumAndMetals help Helium and Metals Helium and metals are obtained when stars finish their life cycle.<br><b>Helium</b> is not especially useful, but it is inevitable. It is automatically spent in a line of hydrogen if possible, conserving the more valuable resource.<br><br><b>Metals</b> “contaminate” your hydrogen and helium by heavier elements. And usually it is a good thing, because the high proportion of metals to hydrogen and helium, also known as “metallicity”, provides for a greater chance for planets to emerge near new stars.<br>Metals are added when stars burn out, especially larger ones. But total metellicity may shrink down when the universe is filled by new objects made from pure hydrogen and helium, such as nebulae and stars. Help/en/HeliumAndMetals
117 Clouds help Clouds Clouds are used to produce hydrogen, which is required to construct the universe. Simplest nebulae can be arranged into more complex cloud structures.<br><br><b>Nebula:</b> the simplest of clouds.<br><b>Globula:</b> provides hydrogen at a slower rate than nebulae, but persists for longer, and also takes less space. Used in creation of larger clouds.<br><b>Star nursery:</b> automatically creates stars from a fraction of provided hydrogen.<br><b>Molecular cloud:</b> large and long-lasting hydrogen generator.<br><b>Active star nursery:</b> very large automatic hydrogen and stars generator. Help/en/Clouds
118 DwarfStars help Dwarf Stars Dwarf stars are cheap, they last for a long time and produce space efficiently. They can have planets that sometimes may harbor life at some point.<br><br><b>Brown dwarf:</b> useless rejects that happen during the star creation process. They appear by themselves and do not take space as opposed to all the other stars. Can’t be created manually, and you don’t need to.<br><b>Red dwarf:</b> It is cost-effective in space creation, but works very slowly.<br><b>Orange dwarf:</b> perfect for the development of life.<br><b>Yellow dwarf:</b> good for the emergence of life.<br><b>White-yellow dwarf:</b> has a largest habitable zone, but burns out rapidly. Help/en/DwarfStars
119 GiantStars help Giant Stars Giant stars burn rapidly and produce a lot of space. At the end of their existence they collapse. These events can damage planets at nearby stars, but they produce metals.<br><br><b>Red giant:</b> a star that has consumed the majority of its fuel. You can’t create these manually, they emerge themselves.<br><b>Yellow giant:</b> the most modest of giant stars. Produces a lot of metals, collapse is weak.<br><b>Blue giant:</b> a common giant star. Produces a good amount of space and metals. Collapse is average.<br><b>Supergiant:</b> huge giant star. Lives short, collapses violently, produces a lot of space and few metals.<br><b>Hypergiant:</b> extremely giant star. Always collapses into a black hole, producing a huge amount of space, which is accompanied by insane destruction. Help/en/GiantStars
120 DegenerateObjects help Degenerate Objects Stars that have exhausted their fusion fuel. They occupy space and do not produce anything, but can be used in forming structures.<br><br><b>White dwarf:</b> the remains of a dwarf star.<br><b>Neutron star:</b> exceptionally compact remains of a giant star.<br><b>Magnetar:</b> the most dense object that is not a black hole.<br><b>Black hole:</b> the remains of a giant star that experienced a destructive collapse. They may be merged into supermassive black holes.<br><b>Supermassive black hole:</b> the result of multitudes of the stellar mass black holes merged into one. Required for galactic formation. They do grow in time, consuming other stars, but do so very slowly. Help/en/DegenerateObjects
121 StarClusters help Star Clusters Star clusters are the most modest of available structures. As a matter of fact these are just a lot of stars which are co-located closer to each other than usual, and therefore they are gravitationally bound. But even such simple lumps already bring noticeable variety into the homogenous landscape of the universe.<br><br><b>Scattered:</b> little structure of irregular shape.<br><b>Small:</b> globular shape.<br><b>Medium:</b> noticeable from afar off.<br><b>Large:</b> makes an impression.<br><b>Giant:</b> causes awe.<br><br>Clusters, like other structures, increase the production of space for their constituent stars. Stars in structures exist as usual. Over time, the clusters disintegrate, releasing the stars they are composed of. Large clusters last longer than small ones and provide a larger bonus to space production. Help/en/StarClusters
122 Galaxies help Galaxies <b>Elliptical galaxies</b> resemble colossal star clusters. They have lenticular shapes, rotate slowly and look very much alike to each other. The stars in them produce more space than in spiral galaxies. Gradually, elliptical galaxies disintegrate into separate stars.<br><br><b>Spiral galaxies</b> spin faster than elliptical ones, they have diverse structures with arms and keep active star formation. They are better fit for the emergence and development of life. In time spiral galaxies exhaust their storage of free gas, they slow down and become more stable and boring ellipticals.<br><br>As in the case of other structures, the stars included in the composition of galaxies continue to function as usual. They produce space, and dwarf stars can have planets. Help/en/Galaxies
123 LargeStructures help Large Structures <b>Large structures</b> are called that for a reason: whole galaxies are used there as building blocks. They are needed to arrange the universe on the largest scales. Without them the space, uniformly filled by stars and galaxies, becomes too monotonous and sparse, meanwile these structures create a packing gradient with more and less dense regions. This arrangement is better fit for being claimed and developed by superadvanced sapient beings.<br><br>Over time, large structures disintegrate into their components, but this does not happen very soon. Help/en/LargeStructures
124 Planets help Planets Planets emerge around dwarf stars when metals are sufficient. In a sense all this space construction is being made with a purpose of making planets with potential of bearing life.<br><br><b>Gas giant:</b> large planet with a very thick atmosphere, unsuitable for life.<br><b>Asteroid belt:</b> a bunch of rocks that lacks mass to form a planet.<br><b>Rocky planet:</b> a planet unsuitable for life. Too cold, hot or wrong chemical makeup.<br><b>Habitable planet:</b> there is liquid water here and life may emerge in the long run.<br><b>Living planet:</b> denizens of this planet show great promise! Help/en/Planets
125 Eons help Eons Life slowly evolves through eons from the most primitive one to the one with sapience potential. Not all planets are successful in completing this process to the end, because stars do not burn forever.<br><br><b>Archean:</b> it is difficult to notice, but these planets are full of archaea and cyanobacteria.<br><b>Paleozoic:</b> alongside ubiquitous amoeba these planets host algae, sponges and even molluscs.<br><b>Proterozoic:</b> ferns, worms, trilobites and fishes.<br><b>Mezozoic:</b> conifers, lizards, dinosaurs and therapsids.<br><b>Cenozoic:</b> flowering plants and various mammals, some of which show signs of sapience. Help/en/Eons
126 Type0Civilizations help Type 0 Civilizations Pre-space epoch – from a tribe to a federation.<br><br><b>c0.0:</b> Lower Paleolithic. Control of fire, stone tools.<br><b>c0.1:</b> Middle Paleolithic. Developed stone tools.<br><b>c0.2:</b> Upper Paleolithic. Advanced stone tools, art.<br><b>c0.3:</b> Mesolithic. Bow and arrows, fishing, boats.<br><b>c0.4:</b> Early Neolithic. Agriculture.<br><b>c0.5:</b> Middle Neolithic. Animal husbandry, ceramics.<br><b>c0.6:</b> Late Neolithic. Large settlements.<br><b>c0.7:</b> First kingdoms of copper and bronze ages. Wheel.<br><b>c0.8:</b> Ancient empires of the iron age. Philosophy.<br><b>c0.9:</b> Industrial age. Electronics and nuclear energy. Help/en/Type0Civilizations
127 Type1Civilizations help Type 1 Civilizations Civilizations are busy with settling their own solar system.<br><br><b>c1.0:</b> A civilization that has completely mastered its home planet. Superconductivity, controlled nuclear fusion.<br><b>c1.1:</b> Research compounds in the home system. Launch loop, space elevator.<br><b>c1.2:</b> Complete genetic tailoring. Cyborgization.<br><b>c1.3:</b> Industrial asteroid mining. Colonies on the other planets of the home system.<br><b>c1.4:</b> Harvesting of matter from atmospheres of gas giants.<br><b>c1.5:</b> Space cities. Picotechnologies.<br><b>c1.6:</b> Industrial manufacturing of antimatter. First starships.<br><b>c1.7:</b> Terraforming. Gamma-lasers.<br><b>c1.8:</b> Space stations of continental scale.<br><b>c1.9:</b> Partial Dyson swarm. Help/en/Type1Civilizations
128 Type2Civilizations help Type 2 Civilizations Civilizations that can expand to other stars.<br><br><b>c2.0:</b> A civilization that completely exploits the energy output of its own sun.<br><b>c2.1:</b> Change of planetary orbits.<br><b>c2.2:</b> Control over inertia.<br><b>c2.3:</b> Starlifting, harvesting matter from stars.<br><b>c2.4:</b> Femtotechnologies: manipulations on individual fermions.<br><b>c2.5:</b> Deconstruction and creation of planets.<br><b>c2.6:</b> Complete domination of astroarchitecture over planets.<br><b>c2.7:</b> Giant stars resources exploitation.<br><b>c2.8:</b> Control over gravity.<br><b>c2.9:</b> Movement of stars. Help/en/Type2Civilizations
129 Type3Civilizations help Type 3 Civilizations Civilizations of galactic scale.<br><br><b>c3.0:</b> Expansion into a galactic group is available.<br><b>c3.1:</b> Creation of stars.<br><b>c3.2:</b> Utilization of white dwarfs.<br><b>c3.3:</b> Creation of black holes by focused radiation.<br><b>c3.4:</b> Expansion into a galactic supercluster is available.<br><b>c3.5:</b> Utilization of neutron stars.<br><b>c3.6:</b> Expansion into a galactic filament is available.<br><b>c3.7:</b> Utilization of magnetars.<br><b>c3.8:</b> Expansion into a great wall is available.<br><b>c3.9:</b> Utilization of black holes. Help/en/Type3Civilizations
130 Type4Civilizations help Type 4 Civilizations Civilizations of the universe scale.<br><br><b>c4.0:</b> Temporal manipulations.<br><b>c4.1:</b> Expansion into the whole universe scale is available.<br><b>c4.2:</b> Utilization of supermassive black holes.<br><b>c4.3:</b> Folding space.<br><b>c4.4:</b> Improbability field.<br><br>And so on, bigger and bigger, so long as there is space. Help/en/Type4Civilizations
-130
View File
@@ -1,130 +0,0 @@
Owniverse||interface||||
MM-Create||interface||||Menu/ru/CreateUniverse
MM-Help||interface||||Menu/ru/Tutorial
MM-Achievments||interface||||Menu/ru/Achievements
MM-Credits||interface||||Menu/ru/Credits
MM-LanguageEn||interface||||Menu/ru/English
MM-LanguageRu||interface||||Menu/ru/RussianActive
MM-SoundActive||interface||||Menu/ru/SoundActive
MM-SoundNonActive||interface||||Menu/ru/SoundNonActive
MM-MusicActive||interface||||Menu/ru/MusicActive
MM-MusicNonActive||interface||||Menu/ru/MusicNonActive
MM-LeaveReality||interface||||Menu/ru/LeaveReality
CreditsTitle||interface||||Credits/ru/Credits
CreditsRoles||interface||Объединитель <br> Укротитель питона <br> Рисователь <br> Композитор||
CreditsNames||interface||Кирилл Ивлев <br> Илья Коновалов <br> Дмитрий Уваров <br> Татьяна Степаненко||
Achievement-Header||interface||||Achievements/ru/Achievements
Achievement-Status-Template||interface||Открыто %Count% из %Total%||
ReportTitle||interface||||Report/ru/Title
ReportNewWarning||interface||||Report/ru/NewWarning
ReportNewButton||interface||||Report/ru/NewButton
ReportWipeWarning||interface||||Report/ru/WipeWarning
ReportWipeButton||interface||||Report/ru/WipeButton
MF-FBV-ReturnButton||interface||||Dashboard/Indicators/ForceBoxes/Ru/Return
MF-FBV-OpenBoxButton||interface||||Dashboard/Indicators/ForceBoxes/Ru/OpenBox
MF-FBV-AcquireButton||interface||||Dashboard/Indicators/ForceBoxes/Ru/Acquire
MF-FBV-NoAdsDeliveredSign||interface||||Dashboard/Indicators/ForceBoxes/Ru/NoAds
Universe||interface||||
Time|Time|indicator|AboutTheGame|Время|Меняйте скорость как хотите.|
Energy|Enr|indicator|EnergyAndDensity|Энергия|Расходуйте на водород и пространство.|
Density|Den|indicator|EnergyAndDensity|Плотность|Поддерживайте баланс.|
DensityRip|DenR|indicator|EnergyAndDensity|Большой разрыв|Повышайте плотность!|
DensityCrunch|DenC|indicator|EnergyAndDensity|Большое сжатие|Понижайте плотность!|
BurnabilityIndicator|Bur|indicator|BurnabilityAndExplosiveness|Горючесть|Интенсивность горения звёзд.|
ExplosivenessIndicator|Exp|indicator|BurnabilityAndExplosiveness|Взрвычатость|Мощность звёздных взрывов.|
AggressionIndicator|Agg|indicator|AggressionAndTrends|Агрессия|Эволюция и конкуренция.|
||||1 год в секунду||
||||10 лет в секунду||
||||100 лет в секунду||
||||1 000 лет в секунду||
||||10 000 лет в секунду||
||||100 000 лет в секунду||
||||1 000 000 лет в секунду||
||||10 000 000 лет в секунду||
||||100 000 000 лет в секунду||
||||1 000 000 000 лет в секунду||
||logtext||Сводка изменений за последние 100 секунд.<br>Указаны средние значения за год.||
ForceNavigationImage||interface||||BigBang/Dashboard/ru/Forces
1-1-1-NavigationResourceImage||interface||||BigBang/Dashboard/ru/Resources
Space|S|entity|SpaceAndHydrogen|Пространство|Нужно для размещения объектов.|
Hydrogen|H|entity|SpaceAndHydrogen|Водород|Нужен для создания облаков и звёзд.|
Helium|He|entity|HeliumAndMetals|Гелий|Экономит водород.|
Metals|Met|entity|HeliumAndMetals|Металлы|Нужны для создания планет.|
||||Металличность||
NavigationStarImage||interface||||BigBang/Dashboard/ru/Stars
Nebula|N|entity|Clouds|Туманность|Производит водород.|
Globula|G|entity|Clouds|Глобула|Производит больше водорода.|
StarNursery|STN|entity|Clouds|Звёздная колыбель|Производит водород и звёзды.|
MolecularCloud|MC|entity|Clouds|Молекулярное облако|Производит много водорода.|
ActiveStarNursery|ASTN|entity|Clouds|Активная звёздная колыбель|Производит очень много водорода и звёзд.|
BrownDwarf|BD|entity|DwarfStars|Бурый карлик|Бесполезен, но не занимает место.|
RedDwarf|RD|entity|DwarfStars|Красный карлик|Простейшая звезда.|
OrangeDwarf|OD|entity|DwarfStars|Оранжевый карлик|Звезда с планетами.|
YellowDwarf|YD|entity|DwarfStars|Жёлтый карлик|Звезда похожая на Солнце.|
WhiteYellowDwarf|WYD|entity|DwarfStars|Бело-жёлтый карлик|Звезда со множеством планет.|
RedGiant|RG|entity|GiantStars|Красный гигант|Деградирующая старая звезда.|
YellowGiant|YG|entity|GiantStars|Жёлтый гигант|Оптимальна для производства металлов.|
BlueGiant|BG|entity|GiantStars|Голубой гигант|Сбалансированно производит металлы и пространство.|
Supergiant|SG|entity|GiantStars|Сверхгигант|Быстро производит пространство и чуть-чуть металлов.|
Hypergiant|HG|entity|GiantStars|Гипергигант|Бурно сгорает, создавая много пространства.|
WhiteDwarf|WD|entity|DegenerateObjects|Белый карлик|Остаток сгоревшего карлика.|
NeutronStar|NS|entity|DegenerateObjects|Нейтронная звезда|Остаток сгоревшего гиганта.|
Magnetar|MGT|entity|DegenerateObjects|Магнетар|Остаток большого гиганта.|
BlackHole|BH|entity|DegenerateObjects|Чёрная дыра|Результат звёздной катастрофы. Нужна для структур.|
SupermassiveBlackHole|SMBH|entity|DegenerateObjects|Сверхмассивная чёрная дыра|Собирается из чёрных дыр. Нужна для галактик.|
1-3-1-NavigationStructureImage||interface||||BigBang/Dashboard/ru/Structures
StarClusterScattered|SCD|entity|StarClusters|Рассеянное звёздное скопление|Небольшая структура неправильной формы.<br>Пространство: +10%.|
StarClusterSmall|SCS|entity|StarClusters|Малое звёздное скопление|Имеет шарообразную форму.<br>Пространство: +20%.|
StarClusterMedium|SCM|entity|StarClusters|Среднее звёздное скопление|Заметно издалека.<br>Пространство: +30%.|
StarClusterLarge|SCL|entity|StarClusters|Большое звёздное скопление|Производит впечатление.<br>Пространство: +50%.|
StarClusterGiant|SCG|entity|StarClusters|Гигантское звёздное скопление|Вызывает трепет.<br>Пространство: +80%.|
GalaxyEllipticalDwarf|GED|entity|Galaxies|Карликовая эллиптическая галактика|Размером с Малое Магелланово Облако.<br>Пространство: +100%.|
GalaxyEllipticalSmall|GES|entity|Galaxies|Малая эллиптическая галактика|Размером с Большое Магелланово Облако.<br>Пространство: +150%.|
GalaxyEllipticalMedium|GEM|entity|Galaxies|Средняя эллиптическая галактика|Размером с Млечный Путь.<br>Пространство: +200%.|
GalaxyEllipticalLarge|GEL|entity|Galaxies|Большая эллиптическая галактика|Размером с Туманность Андромеды.<br>Пространство: +300%.|
GalaxyEllipticalGiant|GEG|entity|Galaxies|Гигантская эллиптическая галактика|Похожа на IC 1101.<br>Пространство: +450%.|
GalaxySpiralDwarf|GSD|entity|Galaxies|Карликовая спиральная галактика|Похожа на Малое Магелланово Облако.|
GalaxySpiralSmall|GSS|entity|Galaxies|Малая спиральная галактика|Похожа на Большое Магелланово Облако.|
GalaxySpiralMedium|GSM|entity|Galaxies|Средняя спиральная галактика|Похожа на Млечный Путь.|
GalaxySpiralLarge|GSL|entity|Galaxies|Большая спиральная галактика|Похожа на Туманность Андромеды.|
GalaxySpiralGiant|GSG|entity|Galaxies|Гигантская спиральная галактика|Размером с IC 1101.|
GalacticGroup|LGG|entity|LargeStructures|Группа галактик|Объединяет галактики.|
GalacticSupercluster|LSC|entity|LargeStructures|Сверхскопление галактик|Основа для структуры вселенной.|
GalacticFilament|LGF|entity|LargeStructures|Галактическая нить|Балансирует плотность воидами.|
GalacticWall|LGW|entity|LargeStructures|Великая стена|Создаёт структуру вселенной.|
UniverseBubble|LUB|entity|LargeStructures|Вселенский пузырь|Больше некуда.|
1-4-1-NavigationLifeImage||interface||||BigBang/Dashboard/ru/Planets
GasGiant|GG|entity|Planets|Газовый гигант|Слишком велика.|
AsteroidBelt|AB|entity|Planets|Астероиды|Куча камней.|
RockyPlanet|RP|entity|Planets|Каменистая планета|Не подходит для жизни.|
HabitablePlanet|HP|entity|Planets|Обитаемая планета|Имеет потенциал для жизни.|
LivingPlanet|LP|entity|Planets|Живая планета|На этой планете есть жизнь!|
|Star|||Звезда||
|SC|||Звёздное скопление||
|GAL|||Галактика||
AboutTheGame||help||Об игре|В этой игре вы можете <b>создать вселенную</b> и управлять её развитием. Конечную цель вы определяете для себя самостоятельно. Попробуйте получить те достижения, которые вам понравятся. Читайте подсказки, исследуйте возможности и не бойтесь экспериментировать. Всегда можно начать всё заново.<br><br>Числа больше 1 000 записаны <b>экспоненциально</b>. 1e4 — это 10 000, то есть «единица, у которой 4 нуля». 1е6 — миллион, 1е9 — миллиард и так далее. 13,77е9 — это 13 миллиардов 770 миллионов.<br><br>Игра идёт в реальном времени с изменяемым масштабированием. За одну секунду может пройти год, десять лет, век и так далее. Меняйте скорость течения времени кнопками «−» и «+».|Help/ru/AboutTheGame
GameplayBasics||help||Основы игры|Вам доступен большой, но конечный <b>запас энергии</b>, нужной для создания всего вещества во вселенной и самого её пространства. В начале подавляющая часть этой энергии вам напрямую недоступна. Но в ходе игры вы будете забирать всё больше энергии, и чем меньше её останется в запасе, тем сложнее будет брать новую. Нехватка энергии не станет острой проблемой в ближайший миллиард лет или около того: запас действительно очень велик.<br><br>Из энергии с помощью облаков производится вещество в виде <b>водорода</b>. Он тратится на создание новых облаков и звёзд. Звёзды в процессе горения создают <b>пространство</b>, в котором могут быть размещены новые звёзды и облака. Создание пространства также расходует некоторую часть энергии из общего запаса.|Help/ru/GameplayBasics
StarsAndStructures||help||Звёзды и структуры|Чем массивнее звезда, тем быстрее она сгорает и больше пространства производит. Самым выгодным вложением водорода на полученное пространство являются самые маленькие звёзды. Но они горят очень долго и медленно производят пространство. Также каждая звезда сама занимает единицу пространства.<br><br>Звёзды и туманности растущей вселенной есть смысл организовывать в галактики и более крупные <b>структуры</b>. В структурах производство пространства звёздами увеличивается.<br><br>Соотношение между веществом и свободным пространством называется <b>плотностью</b>. Вселенная стабильна только в определённом диапазоне плотности. При выходе за его рамки возникают проблемы.|Help/ru/StarsAndStructures
LifeAndForces||help||Жизнь и силы|Возле некоторых звёзд возникают <b>планеты</b>, на которых может появиться жизнь. При определённых обстоятельствах жизнь эволюционирует до разумной, а разумная развивается до высокотехнологичной. Далее она пытается освоить вселенную, которую считает своей.<br><br>Многие события во вселенной случаются не всегда, а лишь с некоторой вероятностью. У вас есть доступ к особым <b>силам</b>, с помощью которых вы можете «подкручивать» вероятности интересующих вас событий, влияя на законы природы.|Help/ru/LifeAndForces
Achievements||help||Достижения|В ходе игры вам совершенно точно удастся выполнить некоторые <b>достижения</b>. Простые получаются сами собой, а вот над более сложными может понадобиться призадуматься. Можно использовать список достижений в качестве карты подсказок возможных следующих шагов.<br><br>Гнаться за всеми достижениями необязательно. Это ваша вселенная и вы можете делать с ней что угодно. Однако достижение есть достижение, и помимо личной гордости о проделанной работе вы сможете с лёгкостью <b>поделиться</b> им с друзьями!|Help/ru/Achievements
Karma||help||Карма|Каждое полученное достижение даёт вам некоторое число <b>кармических очков</b>. При создании новой вселенной вы можете потратить полученные очки на получение небольших бонусов, с помощью которых вам непременно удастся добиться лучших результатов.<br><br>Потраченные кармические очки никуда не деваются: они <b>остаются</b> с вами и вы снова сможете их потратить в следующей вселенной. Скорее всего, к этому моменту их станет ещё больше.|Help/ru/Karma
Gauges||help||Индикаторы|На приборной панели расположены <b>индикаторы</b> тех показателей, которые особенно важны для выбранной страницы с объектами.|Help/ru/Gauges
EnergyAndDensity||help||Энергия и плотность|<b>Энергия</b> из запаса конвертируется в водород и пространство. Чем ниже доля оставшегося запаса, указанная в середине полоски, тем с меньшей эффективностью работают источники создания ресурсов, такие как облака для водорода и звёзды для пространства.<br>Запас энергии правда очень велик, хоть и не бесконечен.<br><br>Средняя <b>плотность</b> вселенной это отношение общей массы вещества, то есть всех звёзд, облаков и так далее, к пустому пространству. Она растёт вместе с массой и уменьшается с ростом пространства. Если индикатор «ρ» выйдет из «средней зоны» и склонится к одной из крайностей, то последствия могут вас неприятно удивить.|Help/ru/EnergyAndDensity
BurnabilityAndExplosiveness||help||Горючесть и взрывчатость|<b>Горючесть</b> показывает текущую скорость горения звёзд. На неё могут влиять плотность вселенной (чем больше, тем выше), действия сверхразвитых цивилизаций и силы игрока.<br><br><b>Взрывчатость</b> показывает текущую вероятность гамма-всплесков и мощность взрыва при любом коллапсе звезды-гиганта. На неё могут влиять плотность вселенной (чем больше, тем ниже), действия сверхразвитых цивилизаций и силы игрока.|Help/ru/BurnabilityAndExplosiveness
AggressionAndTrends||help||Агрессия и тенденции|<b>Агрессия</b> показывает интенсивность конкурентной борьбы между видами, цивилизациями и их внутренними фракциями. Она влияет на развитие и стабильность жизни и обществ. Изменяется под воздействием вселенских тенденций и сил игрока.<br>По умолчанию показывается средняя вселенская агрессия. Но можно выделить какой-либо цивилизационный уровень и увидеть среднюю агрессию именно для этого уровня.<br><br><b>Тенденциями</b> называются результаты долговременных действий цивилизаций. Всего их пять.|Help/ru/AggressionAndTrends
SpaceAndHydrogen||help||Пространство и водород|Большинство созидательных действий требует траты ресурсов.<br><br><b>Пространство</b> нужно для размещения всего того, что вы создаёте. Для создания нового пространства зажигайте звёзды! Также не забывайте объединять созданные звёзды в структуры, чтобы получать ещё больше пространства.<br><br><b>Водород</b> требуется для создания туманностей и звёзд. Туманности позволяют получать больше водорода. Звёзды создают пространство и используются для базирования планет. Эти объекты также служат кирпичиками для возведения сложных структур.|Help/ru/SpaceAndHydrogen
HeliumAndMetals||help||Гелий и металлы|Гелий и металлы остаются, когда звёзды завершают своё существование.<br><b>Гелий</b> не особенно полезен, но от него никуда не деться. Он расходуется автоматически, по возможности замещая водород, экономя более полезный ресурс.<br><br><b>Металлы</b> «загрязняют» ваш запас водорода и гелия более тяжёлыми элементами. Это хорошо, поскольку высокая «металличность», отношение металлов к водороду и гелию, увеличивает вероятность возникновения планет у новых звёзд.<br>Металлы добавляются от сгорания звёзд, особенно больших, но общая металличность может уменьшаться, когда вселенная наполняется новыми объектами из чистого водорода и гелия, такими как туманности и звёзды.|Help/ru/HeliumAndMetals
Clouds||help||Облака|Облака нужны для создания водорода, из которого впоследствии можно построить вселенную. Из базовых туманностей можно собирать более сложные облачные структуры.<br><br><b>Туманность:</b> самое простое облако.<br><b>Глобула:</b> даёт водород медленнее туманности, но существует дольше, а также занимает меньше места. Используется в создании более крупных облаков.<br><b>Звёздная колыбель:</b> автоматически создаёт звёзды из части выданного водорода.<br><b>Молекулярное облако:</b> большой и долговременный генератор водорода.<br><b>Активная звёздная колыбель:</b> очень большой автоматический генератор водорода и звёзд.|Help/ru/Clouds
DwarfStars||help||Звёзды-карлики|Звёзды-карлики дёшевы, существуют долго и производят пространство эффективно. У них бывают планеты, на которых впоследствии может развиться жизнь.<br><br><b>Бурый карлик:</b> брак, бесполезный побочный эффект от создания звёзд. Они возникают сами и не занимают пространство в отличие от остальных звёзд. Производить их специально нельзя, да и не нужно.<br><b>Красный карлик:</b> экономически выгоден для производства пространства, но работает очень медленно.<br><b>Оранжевый карлик:</b> идеален для развития жизни.<br><b>Жёлтый карлик:</b> подходит для возникновения жизни.<br><b>Бело-жёлтый карлик:</b> имеет самую большую зону обитания, но быстро выгорает.|Help/ru/DwarfStars
GiantStars||help||Звёзды-гиганты|Звёзды-гиганты быстро сгорают и производят много пространства. Коллапс в конце существования повреждает планеты у соседних звёзд, но производит металлы.<br><br><b>Красный гигант:</b> деградирующая звезда на закате существования.<br><b>Жёлтый гигант:</b> малая звезда-гигант. Производит много металлов, коллапс слаб.<br><b>Голубой гигант:</b> обычная звезда-гигант. Производит пространство и металлы. Средний коллапс.<br><b>Сверхгигант:</b> огромная звезда-гигант. Живёт недолго, производит множество пространства и немного металлов.<br><b>Гипергигант:</b> экстремальная звезда-гигант. Всегда коллапсирует в чёрную дыру, выделяя множество пространства с сумасшедшими разрушениями.|Help/ru/GiantStars
DegenerateObjects||help||Вырожденные объекты|Звёзды, выработавшие своё термоядерное топливо. Они занимают пространство и ничего не производят, но из них можно собирать структуры.<br><br><b>Белый карлик:</b> остаток сгоревшего карлика.<br><b>Нейтронная звезда:</b> исключительно компактный остаток звезды-гиганта.<br><b>Магнетар:</b> самый плотный объект, не являющийся чёрной дырой.<br><b>Чёрная дыра:</b> остаток огромной звезды, прошедшей разрушительный коллапс. Их можно объединять в сверхмассивные чёрные дыры.<br><b>Сверхмассивная чёрная дыра:</b> результат слияния множества чёрных дыр звёздной массы. Необходимы для создания галактик. Растут самостоятельно за счёт прочих звёзд, хотя и очень медленно.|Help/ru/DegenerateObjects
StarClusters||help||Звёздные скопления|Звёздные скопления являются самыми скромными из структур. Это некоторое количество звёзд, расположенных близко друг к другу и связанных гравитационно. Подобные комки вносят разнообразие в однородный вселенский ландшафт.<br><br><b>Рассеянное:</b> небольшая структура неправильной формы.<br><b>Малое:</b> имеет шарообразную форму.<br><b>Среднее:</b> заметно издалека.<br><b>Большое:</b> производит впечатление.<br><b>Гигантское:</b> вызывает трепет.<br><br>Звёзды в структурах ведут себя как обычно, но получают бонус к производству пространства. Со временем скопления рассыпаются, высвобождая звёзды. Крупные скопления существуют дольше, чем мелкие, и дают больший бонус пространства.|Help/ru/StarClusters
Galaxies||help||Галактики|<b>Эллиптические галактики</b> имеют линзовидную форму и вращаются медленно. Звёзды в них производят больше пространства, чем в спиральных галактиках. Постепенно эллиптические галактики рассыпаются на отдельные звёзды.<br><br><b>Спиральные галактики</b> имеют неоднородную структуру с рукавами и поддерживают активное звездообразование. Они лучше подходят для зарождения и развития жизни. Со временем в спиральных галактиках заканчивается запас газа, они замедляются и превращаются в более стабильные и скучные эллиптические.<br><br>Звёзды, вошедшие в состав галактик, продолжают функционировать как обычно. Они производят пространство, а у карликов могут быть планеты.|Help/ru/Galaxies
LargeStructures||help||Большие структуры|<b>Большие структуры</b> не зря так называются: в качестве строительных кирпичиков в них используются целые галактики. Они нужны для организации вселенной на самых больших масштабах. Без них пространство, равномерно заполненное звёздами и галактиками, оказывается слишком однообразным и разреженным, тогда как они создают градиент заполнения с более и менее плотными областями, более подходящий для освоения сверхразвитыми разумными существами.<br><br>Со временем большие структуры рассыпаются на составляющие, но это происходит очень нескоро.|Help/ru/LargeStructures
Planets||help||Планеты|Планеты возникают у звёзд-карликов при наличии металлов. В некотором смысле всё это космическое строительство проводится ради тех планет, у которых есть потенциал для зарождения жизни.<br><br><b>Газовый гигант:</b> большая планета с чрезвычайно плотной атмосферой, непригодная для жизни.<br><b>Пояс астероидов:</b> куча камней недостаточной массы, чтобы собраться в планету.<br><b>Каменистая планета:</b> непригодная для жизни планета. Слишком холодно, жарко или не тот химический состав.<br><b>Обитаемая планета:</b> здесь есть жидкая вода и в перспективе может образоваться жизнь.<br><b>Живая планета:</b> обитатели этой планеты подают большие надежды!|Help/ru/Planets
Eons||help||Эоны|Жизнь медленно эволюционирует через эоны от самой примитивной до способной к появлению разума. Не всем планетам удаётся довести этот процесс до победного конца, потому что звёзды горят не вечно.<br><br><b>Архей:</b> не сразу бросается в глаза, но на таких планетах полно археев и цианобактерий.<br><b>Палеозой:</b> помимо вездесущих амёб, здесь присутствуют водоросли, губки и даже моллюски.<br><b>Протерозой:</b> папоротники, черви, трилобиты и рыбы.<br><b>Мезозой:</b> голосеменные, ящеры, динозавры и терапсиды.<br><b>Кайнозой:</b> покрытосеменные и разнообразные млекопитающие, некоторые из которых проявляют признаки интеллекта.|Help/ru/Eons
Type0Civilizations||help||Цивилизации типа 0|Докосмическая эпоха — от племени до федерации.<br><br><b>ц0.0:</b> нижний палеолит. Приручение огня, каменные орудия.<br><b>ц0.1:</b> средний палеолит. Развитые каменные орудия.<br><b>ц0.2:</b> верхний палеолит. Сложные каменные орудия, искусство.<br><b>ц0.3:</b> мезолит. Лук и стрелы, рыболовство, лодки.<br><b>ц0.4:</b> ранний неолит. Земледелие.<br><b>ц0.5:</b> средний неолит. Скотоводство, керамика.<br><b>ц0.6:</b> поздний неолит. Крупные поселения.<br><b>ц0.7:</b> первые царства медного и бронзового века. Колесо.<br><b>ц0.8:</b> античные империи железного века. Философия.<br><b>ц0.9:</b> промышленная эпоха. Электричество.|Help/ru/Type0Civilizations
Type1Civilizations||help||Цивилизации типа 1|Цивилизации, заселяющие родную солнечную систему.<br><br><b>ц1.0:</b> цивилизация, освоившая родную планету. Сверхпроводимость, термоядерный синтез.<br><b>ц1.1:</b> научные базы в родной системе. Пусковая петля, космический лифт.<br><b>ц1.2:</b> полное управление генетикой. Киборгизация.<br><b>ц1.3:</b> промышленная добыча астероидов. Поселения в родной системе.<br><b>ц1.4:</b> сбор вещества из атмосфер газовых гигантов.<br><b>ц1.5:</b> космические города. Пикотехнологии.<br><b>ц1.6:</b> промышленное антивещество. Первые звездолёты.<br><b>ц1.7:</b> терраформинг. Гамма-лазеры.<br><b>ц1.8:</b> космические станции континентального масштаба.<br><b>ц1.9:</b> частичный рой Дайсона.|Help/ru/Type1Civilizations
Type2Civilizations||help||Цивилизации типа 2|Цивилизации, ведущие экспансию к иным звёздам.<br><br><b>ц2.0:</b> цивилизация, освоившая энергию родного солнца.<br><b>ц2.1:</b> изменение планетарных орбит.<br><b>ц2.2:</b> управление инерцией.<br><b>ц2.3:</b> сбор вещества со звёзд.<br><b>ц2.4:</b> фемтотехнологии: управление отдельными фермионами.<br><b>ц2.5:</b> деконструкция и сборка планет.<br><b>ц2.6:</b> окончательное переселение с планет в космос.<br><b>ц2.7:</b> освоение ресурсов звёзд-гигантов.<br><b>ц2.8:</b> управление гравитацией.<br><b>ц2.9:</b> перемещение звёзд.|Help/ru/Type2Civilizations
Type3Civilizations||help||Цивилизации типа 3|Цивилизации галактического масштаба.<br><br><b>ц3.0:</b> возможна экспансия в группу галактик.<br><b>ц3.1:</b> создание звёзд.<br><b>ц3.2:</b> использование белых карликов.<br><b>ц3.3:</b> создание чёрных дыр из концентрированного излучения.<br><b>ц3.4:</b> возможна экспансия в сверхскопление.<br><b>ц3.5:</b> использование нейтронных звёзд.<br><b>ц3.6:</b> возможна экспансия в галактическую нить.<br><b>ц3.7:</b> использование магнетаров.<br><b>ц3.8:</b> возможна экспансия в великую стену.<br><b>ц3.9:</b> использование чёрных дыр.|Help/ru/Type3Civilizations
Type4Civilizations||help||Цивилизации типа 4|Цивилизации вселенского масштаба.<br><br><b>ц4.0:</b> манипуляции со временем.<br><b>ц4.1:</b> возможна экспансия на масштабы всей вселенной.<br><b>ц4.2:</b> использование сверхмассивных чёрных дыр.<br><b>ц4.3:</b> складное пространство.<br><b>ц4.4:</b> поле невероятности.<br><br>И так далее, всё больше и больше, пока есть место.|Help/ru/Type4Civilizations
1 Owniverse interface
2 MM-Create interface Menu/ru/CreateUniverse
3 MM-Help interface Menu/ru/Tutorial
4 MM-Achievments interface Menu/ru/Achievements
5 MM-Credits interface Menu/ru/Credits
6 MM-LanguageEn interface Menu/ru/English
7 MM-LanguageRu interface Menu/ru/RussianActive
8 MM-SoundActive interface Menu/ru/SoundActive
9 MM-SoundNonActive interface Menu/ru/SoundNonActive
10 MM-MusicActive interface Menu/ru/MusicActive
11 MM-MusicNonActive interface Menu/ru/MusicNonActive
12 MM-LeaveReality interface Menu/ru/LeaveReality
13 CreditsTitle interface Credits/ru/Credits
14 CreditsRoles interface Объединитель <br> Укротитель питона <br> Рисователь <br> Композитор
15 CreditsNames interface Кирилл Ивлев <br> Илья Коновалов <br> Дмитрий Уваров <br> Татьяна Степаненко
16 Achievement-Header interface Achievements/ru/Achievements
17 Achievement-Status-Template interface Открыто %Count% из %Total%
18 ReportTitle interface Report/ru/Title
19 ReportNewWarning interface Report/ru/NewWarning
20 ReportNewButton interface Report/ru/NewButton
21 ReportWipeWarning interface Report/ru/WipeWarning
22 ReportWipeButton interface Report/ru/WipeButton
23 MF-FBV-ReturnButton interface Dashboard/Indicators/ForceBoxes/Ru/Return
24 MF-FBV-OpenBoxButton interface Dashboard/Indicators/ForceBoxes/Ru/OpenBox
25 MF-FBV-AcquireButton interface Dashboard/Indicators/ForceBoxes/Ru/Acquire
26 MF-FBV-NoAdsDeliveredSign interface Dashboard/Indicators/ForceBoxes/Ru/NoAds
27 Universe interface
28 Time Time indicator AboutTheGame Время Меняйте скорость как хотите.
29 Energy Enr indicator EnergyAndDensity Энергия Расходуйте на водород и пространство.
30 Density Den indicator EnergyAndDensity Плотность Поддерживайте баланс.
31 DensityRip DenR indicator EnergyAndDensity Большой разрыв Повышайте плотность!
32 DensityCrunch DenC indicator EnergyAndDensity Большое сжатие Понижайте плотность!
33 BurnabilityIndicator Bur indicator BurnabilityAndExplosiveness Горючесть Интенсивность горения звёзд.
34 ExplosivenessIndicator Exp indicator BurnabilityAndExplosiveness Взрвычатость Мощность звёздных взрывов.
35 AggressionIndicator Agg indicator AggressionAndTrends Агрессия Эволюция и конкуренция.
36 1 год в секунду
37 10 лет в секунду
38 100 лет в секунду
39 1 000 лет в секунду
40 10 000 лет в секунду
41 100 000 лет в секунду
42 1 000 000 лет в секунду
43 10 000 000 лет в секунду
44 100 000 000 лет в секунду
45 1 000 000 000 лет в секунду
46 logtext Сводка изменений за последние 100 секунд.<br>Указаны средние значения за год.
47 ForceNavigationImage interface BigBang/Dashboard/ru/Forces
48 1-1-1-NavigationResourceImage interface BigBang/Dashboard/ru/Resources
49 Space S entity SpaceAndHydrogen Пространство Нужно для размещения объектов.
50 Hydrogen H entity SpaceAndHydrogen Водород Нужен для создания облаков и звёзд.
51 Helium He entity HeliumAndMetals Гелий Экономит водород.
52 Metals Met entity HeliumAndMetals Металлы Нужны для создания планет.
53 Металличность
54 NavigationStarImage interface BigBang/Dashboard/ru/Stars
55 Nebula N entity Clouds Туманность Производит водород.
56 Globula G entity Clouds Глобула Производит больше водорода.
57 StarNursery STN entity Clouds Звёздная колыбель Производит водород и звёзды.
58 MolecularCloud MC entity Clouds Молекулярное облако Производит много водорода.
59 ActiveStarNursery ASTN entity Clouds Активная звёздная колыбель Производит очень много водорода и звёзд.
60 BrownDwarf BD entity DwarfStars Бурый карлик Бесполезен, но не занимает место.
61 RedDwarf RD entity DwarfStars Красный карлик Простейшая звезда.
62 OrangeDwarf OD entity DwarfStars Оранжевый карлик Звезда с планетами.
63 YellowDwarf YD entity DwarfStars Жёлтый карлик Звезда похожая на Солнце.
64 WhiteYellowDwarf WYD entity DwarfStars Бело-жёлтый карлик Звезда со множеством планет.
65 RedGiant RG entity GiantStars Красный гигант Деградирующая старая звезда.
66 YellowGiant YG entity GiantStars Жёлтый гигант Оптимальна для производства металлов.
67 BlueGiant BG entity GiantStars Голубой гигант Сбалансированно производит металлы и пространство.
68 Supergiant SG entity GiantStars Сверхгигант Быстро производит пространство и чуть-чуть металлов.
69 Hypergiant HG entity GiantStars Гипергигант Бурно сгорает, создавая много пространства.
70 WhiteDwarf WD entity DegenerateObjects Белый карлик Остаток сгоревшего карлика.
71 NeutronStar NS entity DegenerateObjects Нейтронная звезда Остаток сгоревшего гиганта.
72 Magnetar MGT entity DegenerateObjects Магнетар Остаток большого гиганта.
73 BlackHole BH entity DegenerateObjects Чёрная дыра Результат звёздной катастрофы. Нужна для структур.
74 SupermassiveBlackHole SMBH entity DegenerateObjects Сверхмассивная чёрная дыра Собирается из чёрных дыр. Нужна для галактик.
75 1-3-1-NavigationStructureImage interface BigBang/Dashboard/ru/Structures
76 StarClusterScattered SCD entity StarClusters Рассеянное звёздное скопление Небольшая структура неправильной формы.<br>Пространство: +10%.
77 StarClusterSmall SCS entity StarClusters Малое звёздное скопление Имеет шарообразную форму.<br>Пространство: +20%.
78 StarClusterMedium SCM entity StarClusters Среднее звёздное скопление Заметно издалека.<br>Пространство: +30%.
79 StarClusterLarge SCL entity StarClusters Большое звёздное скопление Производит впечатление.<br>Пространство: +50%.
80 StarClusterGiant SCG entity StarClusters Гигантское звёздное скопление Вызывает трепет.<br>Пространство: +80%.
81 GalaxyEllipticalDwarf GED entity Galaxies Карликовая эллиптическая галактика Размером с Малое Магелланово Облако.<br>Пространство: +100%.
82 GalaxyEllipticalSmall GES entity Galaxies Малая эллиптическая галактика Размером с Большое Магелланово Облако.<br>Пространство: +150%.
83 GalaxyEllipticalMedium GEM entity Galaxies Средняя эллиптическая галактика Размером с Млечный Путь.<br>Пространство: +200%.
84 GalaxyEllipticalLarge GEL entity Galaxies Большая эллиптическая галактика Размером с Туманность Андромеды.<br>Пространство: +300%.
85 GalaxyEllipticalGiant GEG entity Galaxies Гигантская эллиптическая галактика Похожа на IC 1101.<br>Пространство: +450%.
86 GalaxySpiralDwarf GSD entity Galaxies Карликовая спиральная галактика Похожа на Малое Магелланово Облако.
87 GalaxySpiralSmall GSS entity Galaxies Малая спиральная галактика Похожа на Большое Магелланово Облако.
88 GalaxySpiralMedium GSM entity Galaxies Средняя спиральная галактика Похожа на Млечный Путь.
89 GalaxySpiralLarge GSL entity Galaxies Большая спиральная галактика Похожа на Туманность Андромеды.
90 GalaxySpiralGiant GSG entity Galaxies Гигантская спиральная галактика Размером с IC 1101.
91 GalacticGroup LGG entity LargeStructures Группа галактик Объединяет галактики.
92 GalacticSupercluster LSC entity LargeStructures Сверхскопление галактик Основа для структуры вселенной.
93 GalacticFilament LGF entity LargeStructures Галактическая нить Балансирует плотность воидами.
94 GalacticWall LGW entity LargeStructures Великая стена Создаёт структуру вселенной.
95 UniverseBubble LUB entity LargeStructures Вселенский пузырь Больше некуда.
96 1-4-1-NavigationLifeImage interface BigBang/Dashboard/ru/Planets
97 GasGiant GG entity Planets Газовый гигант Слишком велика.
98 AsteroidBelt AB entity Planets Астероиды Куча камней.
99 RockyPlanet RP entity Planets Каменистая планета Не подходит для жизни.
100 HabitablePlanet HP entity Planets Обитаемая планета Имеет потенциал для жизни.
101 LivingPlanet LP entity Planets Живая планета На этой планете есть жизнь!
102 Star Звезда
103 SC Звёздное скопление
104 GAL Галактика
105 AboutTheGame help Об игре В этой игре вы можете <b>создать вселенную</b> и управлять её развитием. Конечную цель вы определяете для себя самостоятельно. Попробуйте получить те достижения, которые вам понравятся. Читайте подсказки, исследуйте возможности и не бойтесь экспериментировать. Всегда можно начать всё заново.<br><br>Числа больше 1 000 записаны <b>экспоненциально</b>. 1e4 — это 10 000, то есть «единица, у которой 4 нуля». 1е6 — миллион, 1е9 — миллиард и так далее. 13,77е9 — это 13 миллиардов 770 миллионов.<br><br>Игра идёт в реальном времени с изменяемым масштабированием. За одну секунду может пройти год, десять лет, век и так далее. Меняйте скорость течения времени кнопками «−» и «+». Help/ru/AboutTheGame
106 GameplayBasics help Основы игры Вам доступен большой, но конечный <b>запас энергии</b>, нужной для создания всего вещества во вселенной и самого её пространства. В начале подавляющая часть этой энергии вам напрямую недоступна. Но в ходе игры вы будете забирать всё больше энергии, и чем меньше её останется в запасе, тем сложнее будет брать новую. Нехватка энергии не станет острой проблемой в ближайший миллиард лет или около того: запас действительно очень велик.<br><br>Из энергии с помощью облаков производится вещество в виде <b>водорода</b>. Он тратится на создание новых облаков и звёзд. Звёзды в процессе горения создают <b>пространство</b>, в котором могут быть размещены новые звёзды и облака. Создание пространства также расходует некоторую часть энергии из общего запаса. Help/ru/GameplayBasics
107 StarsAndStructures help Звёзды и структуры Чем массивнее звезда, тем быстрее она сгорает и больше пространства производит. Самым выгодным вложением водорода на полученное пространство являются самые маленькие звёзды. Но они горят очень долго и медленно производят пространство. Также каждая звезда сама занимает единицу пространства.<br><br>Звёзды и туманности растущей вселенной есть смысл организовывать в галактики и более крупные <b>структуры</b>. В структурах производство пространства звёздами увеличивается.<br><br>Соотношение между веществом и свободным пространством называется <b>плотностью</b>. Вселенная стабильна только в определённом диапазоне плотности. При выходе за его рамки возникают проблемы. Help/ru/StarsAndStructures
108 LifeAndForces help Жизнь и силы Возле некоторых звёзд возникают <b>планеты</b>, на которых может появиться жизнь. При определённых обстоятельствах жизнь эволюционирует до разумной, а разумная развивается до высокотехнологичной. Далее она пытается освоить вселенную, которую считает своей.<br><br>Многие события во вселенной случаются не всегда, а лишь с некоторой вероятностью. У вас есть доступ к особым <b>силам</b>, с помощью которых вы можете «подкручивать» вероятности интересующих вас событий, влияя на законы природы. Help/ru/LifeAndForces
109 Achievements help Достижения В ходе игры вам совершенно точно удастся выполнить некоторые <b>достижения</b>. Простые получаются сами собой, а вот над более сложными может понадобиться призадуматься. Можно использовать список достижений в качестве карты подсказок возможных следующих шагов.<br><br>Гнаться за всеми достижениями необязательно. Это ваша вселенная и вы можете делать с ней что угодно. Однако достижение есть достижение, и помимо личной гордости о проделанной работе вы сможете с лёгкостью <b>поделиться</b> им с друзьями! Help/ru/Achievements
110 Karma help Карма Каждое полученное достижение даёт вам некоторое число <b>кармических очков</b>. При создании новой вселенной вы можете потратить полученные очки на получение небольших бонусов, с помощью которых вам непременно удастся добиться лучших результатов.<br><br>Потраченные кармические очки никуда не деваются: они <b>остаются</b> с вами и вы снова сможете их потратить в следующей вселенной. Скорее всего, к этому моменту их станет ещё больше. Help/ru/Karma
111 Gauges help Индикаторы На приборной панели расположены <b>индикаторы</b> тех показателей, которые особенно важны для выбранной страницы с объектами. Help/ru/Gauges
112 EnergyAndDensity help Энергия и плотность <b>Энергия</b> из запаса конвертируется в водород и пространство. Чем ниже доля оставшегося запаса, указанная в середине полоски, тем с меньшей эффективностью работают источники создания ресурсов, такие как облака для водорода и звёзды для пространства.<br>Запас энергии правда очень велик, хоть и не бесконечен.<br><br>Средняя <b>плотность</b> вселенной это отношение общей массы вещества, то есть всех звёзд, облаков и так далее, к пустому пространству. Она растёт вместе с массой и уменьшается с ростом пространства. Если индикатор «ρ» выйдет из «средней зоны» и склонится к одной из крайностей, то последствия могут вас неприятно удивить. Help/ru/EnergyAndDensity
113 BurnabilityAndExplosiveness help Горючесть и взрывчатость <b>Горючесть</b> показывает текущую скорость горения звёзд. На неё могут влиять плотность вселенной (чем больше, тем выше), действия сверхразвитых цивилизаций и силы игрока.<br><br><b>Взрывчатость</b> показывает текущую вероятность гамма-всплесков и мощность взрыва при любом коллапсе звезды-гиганта. На неё могут влиять плотность вселенной (чем больше, тем ниже), действия сверхразвитых цивилизаций и силы игрока. Help/ru/BurnabilityAndExplosiveness
114 AggressionAndTrends help Агрессия и тенденции <b>Агрессия</b> показывает интенсивность конкурентной борьбы между видами, цивилизациями и их внутренними фракциями. Она влияет на развитие и стабильность жизни и обществ. Изменяется под воздействием вселенских тенденций и сил игрока.<br>По умолчанию показывается средняя вселенская агрессия. Но можно выделить какой-либо цивилизационный уровень и увидеть среднюю агрессию именно для этого уровня.<br><br><b>Тенденциями</b> называются результаты долговременных действий цивилизаций. Всего их пять. Help/ru/AggressionAndTrends
115 SpaceAndHydrogen help Пространство и водород Большинство созидательных действий требует траты ресурсов.<br><br><b>Пространство</b> нужно для размещения всего того, что вы создаёте. Для создания нового пространства зажигайте звёзды! Также не забывайте объединять созданные звёзды в структуры, чтобы получать ещё больше пространства.<br><br><b>Водород</b> требуется для создания туманностей и звёзд. Туманности позволяют получать больше водорода. Звёзды создают пространство и используются для базирования планет. Эти объекты также служат кирпичиками для возведения сложных структур. Help/ru/SpaceAndHydrogen
116 HeliumAndMetals help Гелий и металлы Гелий и металлы остаются, когда звёзды завершают своё существование.<br><b>Гелий</b> не особенно полезен, но от него никуда не деться. Он расходуется автоматически, по возможности замещая водород, экономя более полезный ресурс.<br><br><b>Металлы</b> «загрязняют» ваш запас водорода и гелия более тяжёлыми элементами. Это хорошо, поскольку высокая «металличность», отношение металлов к водороду и гелию, увеличивает вероятность возникновения планет у новых звёзд.<br>Металлы добавляются от сгорания звёзд, особенно больших, но общая металличность может уменьшаться, когда вселенная наполняется новыми объектами из чистого водорода и гелия, такими как туманности и звёзды. Help/ru/HeliumAndMetals
117 Clouds help Облака Облака нужны для создания водорода, из которого впоследствии можно построить вселенную. Из базовых туманностей можно собирать более сложные облачные структуры.<br><br><b>Туманность:</b> самое простое облако.<br><b>Глобула:</b> даёт водород медленнее туманности, но существует дольше, а также занимает меньше места. Используется в создании более крупных облаков.<br><b>Звёздная колыбель:</b> автоматически создаёт звёзды из части выданного водорода.<br><b>Молекулярное облако:</b> большой и долговременный генератор водорода.<br><b>Активная звёздная колыбель:</b> очень большой автоматический генератор водорода и звёзд. Help/ru/Clouds
118 DwarfStars help Звёзды-карлики Звёзды-карлики дёшевы, существуют долго и производят пространство эффективно. У них бывают планеты, на которых впоследствии может развиться жизнь.<br><br><b>Бурый карлик:</b> брак, бесполезный побочный эффект от создания звёзд. Они возникают сами и не занимают пространство в отличие от остальных звёзд. Производить их специально нельзя, да и не нужно.<br><b>Красный карлик:</b> экономически выгоден для производства пространства, но работает очень медленно.<br><b>Оранжевый карлик:</b> идеален для развития жизни.<br><b>Жёлтый карлик:</b> подходит для возникновения жизни.<br><b>Бело-жёлтый карлик:</b> имеет самую большую зону обитания, но быстро выгорает. Help/ru/DwarfStars
119 GiantStars help Звёзды-гиганты Звёзды-гиганты быстро сгорают и производят много пространства. Коллапс в конце существования повреждает планеты у соседних звёзд, но производит металлы.<br><br><b>Красный гигант:</b> деградирующая звезда на закате существования.<br><b>Жёлтый гигант:</b> малая звезда-гигант. Производит много металлов, коллапс слаб.<br><b>Голубой гигант:</b> обычная звезда-гигант. Производит пространство и металлы. Средний коллапс.<br><b>Сверхгигант:</b> огромная звезда-гигант. Живёт недолго, производит множество пространства и немного металлов.<br><b>Гипергигант:</b> экстремальная звезда-гигант. Всегда коллапсирует в чёрную дыру, выделяя множество пространства с сумасшедшими разрушениями. Help/ru/GiantStars
120 DegenerateObjects help Вырожденные объекты Звёзды, выработавшие своё термоядерное топливо. Они занимают пространство и ничего не производят, но из них можно собирать структуры.<br><br><b>Белый карлик:</b> остаток сгоревшего карлика.<br><b>Нейтронная звезда:</b> исключительно компактный остаток звезды-гиганта.<br><b>Магнетар:</b> самый плотный объект, не являющийся чёрной дырой.<br><b>Чёрная дыра:</b> остаток огромной звезды, прошедшей разрушительный коллапс. Их можно объединять в сверхмассивные чёрные дыры.<br><b>Сверхмассивная чёрная дыра:</b> результат слияния множества чёрных дыр звёздной массы. Необходимы для создания галактик. Растут самостоятельно за счёт прочих звёзд, хотя и очень медленно. Help/ru/DegenerateObjects
121 StarClusters help Звёздные скопления Звёздные скопления являются самыми скромными из структур. Это некоторое количество звёзд, расположенных близко друг к другу и связанных гравитационно. Подобные комки вносят разнообразие в однородный вселенский ландшафт.<br><br><b>Рассеянное:</b> небольшая структура неправильной формы.<br><b>Малое:</b> имеет шарообразную форму.<br><b>Среднее:</b> заметно издалека.<br><b>Большое:</b> производит впечатление.<br><b>Гигантское:</b> вызывает трепет.<br><br>Звёзды в структурах ведут себя как обычно, но получают бонус к производству пространства. Со временем скопления рассыпаются, высвобождая звёзды. Крупные скопления существуют дольше, чем мелкие, и дают больший бонус пространства. Help/ru/StarClusters
122 Galaxies help Галактики <b>Эллиптические галактики</b> имеют линзовидную форму и вращаются медленно. Звёзды в них производят больше пространства, чем в спиральных галактиках. Постепенно эллиптические галактики рассыпаются на отдельные звёзды.<br><br><b>Спиральные галактики</b> имеют неоднородную структуру с рукавами и поддерживают активное звездообразование. Они лучше подходят для зарождения и развития жизни. Со временем в спиральных галактиках заканчивается запас газа, они замедляются и превращаются в более стабильные и скучные эллиптические.<br><br>Звёзды, вошедшие в состав галактик, продолжают функционировать как обычно. Они производят пространство, а у карликов могут быть планеты. Help/ru/Galaxies
123 LargeStructures help Большие структуры <b>Большие структуры</b> не зря так называются: в качестве строительных кирпичиков в них используются целые галактики. Они нужны для организации вселенной на самых больших масштабах. Без них пространство, равномерно заполненное звёздами и галактиками, оказывается слишком однообразным и разреженным, тогда как они создают градиент заполнения с более и менее плотными областями, более подходящий для освоения сверхразвитыми разумными существами.<br><br>Со временем большие структуры рассыпаются на составляющие, но это происходит очень нескоро. Help/ru/LargeStructures
124 Planets help Планеты Планеты возникают у звёзд-карликов при наличии металлов. В некотором смысле всё это космическое строительство проводится ради тех планет, у которых есть потенциал для зарождения жизни.<br><br><b>Газовый гигант:</b> большая планета с чрезвычайно плотной атмосферой, непригодная для жизни.<br><b>Пояс астероидов:</b> куча камней недостаточной массы, чтобы собраться в планету.<br><b>Каменистая планета:</b> непригодная для жизни планета. Слишком холодно, жарко или не тот химический состав.<br><b>Обитаемая планета:</b> здесь есть жидкая вода и в перспективе может образоваться жизнь.<br><b>Живая планета:</b> обитатели этой планеты подают большие надежды! Help/ru/Planets
125 Eons help Эоны Жизнь медленно эволюционирует через эоны от самой примитивной до способной к появлению разума. Не всем планетам удаётся довести этот процесс до победного конца, потому что звёзды горят не вечно.<br><br><b>Архей:</b> не сразу бросается в глаза, но на таких планетах полно археев и цианобактерий.<br><b>Палеозой:</b> помимо вездесущих амёб, здесь присутствуют водоросли, губки и даже моллюски.<br><b>Протерозой:</b> папоротники, черви, трилобиты и рыбы.<br><b>Мезозой:</b> голосеменные, ящеры, динозавры и терапсиды.<br><b>Кайнозой:</b> покрытосеменные и разнообразные млекопитающие, некоторые из которых проявляют признаки интеллекта. Help/ru/Eons
126 Type0Civilizations help Цивилизации типа 0 Докосмическая эпоха — от племени до федерации.<br><br><b>ц0.0:</b> нижний палеолит. Приручение огня, каменные орудия.<br><b>ц0.1:</b> средний палеолит. Развитые каменные орудия.<br><b>ц0.2:</b> верхний палеолит. Сложные каменные орудия, искусство.<br><b>ц0.3:</b> мезолит. Лук и стрелы, рыболовство, лодки.<br><b>ц0.4:</b> ранний неолит. Земледелие.<br><b>ц0.5:</b> средний неолит. Скотоводство, керамика.<br><b>ц0.6:</b> поздний неолит. Крупные поселения.<br><b>ц0.7:</b> первые царства медного и бронзового века. Колесо.<br><b>ц0.8:</b> античные империи железного века. Философия.<br><b>ц0.9:</b> промышленная эпоха. Электричество. Help/ru/Type0Civilizations
127 Type1Civilizations help Цивилизации типа 1 Цивилизации, заселяющие родную солнечную систему.<br><br><b>ц1.0:</b> цивилизация, освоившая родную планету. Сверхпроводимость, термоядерный синтез.<br><b>ц1.1:</b> научные базы в родной системе. Пусковая петля, космический лифт.<br><b>ц1.2:</b> полное управление генетикой. Киборгизация.<br><b>ц1.3:</b> промышленная добыча астероидов. Поселения в родной системе.<br><b>ц1.4:</b> сбор вещества из атмосфер газовых гигантов.<br><b>ц1.5:</b> космические города. Пикотехнологии.<br><b>ц1.6:</b> промышленное антивещество. Первые звездолёты.<br><b>ц1.7:</b> терраформинг. Гамма-лазеры.<br><b>ц1.8:</b> космические станции континентального масштаба.<br><b>ц1.9:</b> частичный рой Дайсона. Help/ru/Type1Civilizations
128 Type2Civilizations help Цивилизации типа 2 Цивилизации, ведущие экспансию к иным звёздам.<br><br><b>ц2.0:</b> цивилизация, освоившая энергию родного солнца.<br><b>ц2.1:</b> изменение планетарных орбит.<br><b>ц2.2:</b> управление инерцией.<br><b>ц2.3:</b> сбор вещества со звёзд.<br><b>ц2.4:</b> фемтотехнологии: управление отдельными фермионами.<br><b>ц2.5:</b> деконструкция и сборка планет.<br><b>ц2.6:</b> окончательное переселение с планет в космос.<br><b>ц2.7:</b> освоение ресурсов звёзд-гигантов.<br><b>ц2.8:</b> управление гравитацией.<br><b>ц2.9:</b> перемещение звёзд. Help/ru/Type2Civilizations
129 Type3Civilizations help Цивилизации типа 3 Цивилизации галактического масштаба.<br><br><b>ц3.0:</b> возможна экспансия в группу галактик.<br><b>ц3.1:</b> создание звёзд.<br><b>ц3.2:</b> использование белых карликов.<br><b>ц3.3:</b> создание чёрных дыр из концентрированного излучения.<br><b>ц3.4:</b> возможна экспансия в сверхскопление.<br><b>ц3.5:</b> использование нейтронных звёзд.<br><b>ц3.6:</b> возможна экспансия в галактическую нить.<br><b>ц3.7:</b> использование магнетаров.<br><b>ц3.8:</b> возможна экспансия в великую стену.<br><b>ц3.9:</b> использование чёрных дыр. Help/ru/Type3Civilizations
130 Type4Civilizations help Цивилизации типа 4 Цивилизации вселенского масштаба.<br><br><b>ц4.0:</b> манипуляции со временем.<br><b>ц4.1:</b> возможна экспансия на масштабы всей вселенной.<br><b>ц4.2:</b> использование сверхмассивных чёрных дыр.<br><b>ц4.3:</b> складное пространство.<br><b>ц4.4:</b> поле невероятности.<br><br>И так далее, всё больше и больше, пока есть место. Help/ru/Type4Civilizations
@@ -4,6 +4,8 @@ const E = preload("res://world/owniverse/math/exact.gd")
static func get_data() -> Dictionary:
var result: Dictionary = {}
for row: Dictionary in CSVLoader.load(DATA).values():
for field in ["span", "stars", "progress", "degradation", "colonization", "war", "diplomacy_rate", "worship"]:
row[field] = E.of(row[field])
if not result.has(row.stage):
result[row.stage] = {
"home": row.home,
@@ -1,3 +1,14 @@
class_name OwniverseExtraParamLoader
const E = preload("res://world/owniverse/math/exact.gd")
static func get_data() -> Dictionary:
var result: Dictionary = {}
for row: Dictionary in CSVLoader.load(DATA).values():
result[row["param name"]] = E.of(row["param export"])
return result
#region Data
const DATA := """
param name|param value|param export|comment
E|1.00E+27|1.00E+27|количество энергии во вселенной
G|6.67E-11|6.67E-11|
@@ -25,3 +36,5 @@ ForceBox0Weight| 24|24|Вес вероятности появления зелё
ForceBox1Weight| 6|6|Вес вероятности появления синего ящика
ForceBox2Weight| 2|2|Вес вероятности появления фиолетового ящика
ForceBox3Weight| 1|1|Вес вероятности появления оранжевого ящика
"""
#endregion
+1
View File
@@ -0,0 +1 @@
uid://0sukoduq5ghq
+11 -6
View File
@@ -1,18 +1,23 @@
class_name OwniverseLifeRuleLoader
const E = preload("res://world/owniverse/math/exact.gd")
static func get_data() -> Dictionary:
return CSVLoader.load(DATA)
var result: Dictionary = CSVLoader.load(DATA)
for row: Dictionary in result.values():
for field in ["span", "progress", "degradation"]:
row[field] = E.of(row[field])
return result
#region Data Items
const DATA := """
id|span|progress|degradation|next|fall
HP|5E+06|0.00025|0.0025|EON1|RP:1
EON1|1E+07|0.00025|0.0025|EON2|HP:100^RP:1
EON2|1E+07|0.00025|0.0025|EON3|EON1:1
EON3|1E+06|0.00025|0.0025|EON4|EON2:1000^EON1:1
EON4|1E+06|0.00025|0.0025|EON5|EON3:1000^EON1:1
EON5|5E+05|0.00025|0.0025|C0.0|EON4:2000^EON1:1
EON1|1E+06|0.025|0.0025|EON2|HP:100^RP:1
EON2|1E+06|0.025|0.0025|EON3|EON1:1
EON3|1E+05|0.025|0.0025|EON4|EON2:1000^EON1:1
EON4|1E+05|0.025|0.0025|EON5|EON3:1000^EON1:1
EON5|5E+05|0.025|0.0025|C0.0|EON4:2000^EON1:1
C0.0|2E+03|0.0175|0.025|C0.1|EON5:1
C0.1|2E+03|0.0175|0.025|C0.2|C0.0:1
"""
+33 -4
View File
@@ -46,6 +46,8 @@ float. Весь порядок E27 сохраняет целые единицы.
### Общие окна рождения и эволюции
Обработка кадров на скоростях 4–6 использует адаптивный шаг 0.1 → 0.2 → 0.5 реальной секунды: накопленное отставание больше двух текущих шагов повышает ступень, меньше половины шага понижает её. Граница ограничивается запрошенным временем, долг не отбрасывается. Скорости 1–3 используют 1/60 секунды. При смене скорости ступень сбрасывается. Сохранённая незавершённая транзакция сначала возобновляется с прежней границей. Кооперативный бюджет кадра остаётся 40 мс. Изменение шага не изменяет ширину временных партий, но может влиять на результаты дискретных расчётов производства и глобальных параметров.
Окно рождения шириной `w = lifespan / 40` при `lifespan > 10`, иначе `w = lifespan`. Окно превращения сдвинуто на `lifespan`. При частичном списании:
```
@@ -73,10 +75,10 @@ remainder = expected - planets_created
GI не хранит накопленные счётчики первичной материи Unity. Поэтому `stellar_environment()` вычисляет среду из текущего физического состава, включая связанные объекты, без суммирующих групп интерфейса. Это приближение для баланса GI, а не побитовое воспроизведение Unity.
- `M` — свободные и связанные H/He/Met плюс табличная масса конкретных объектов и масса SMBH.
- `V` — физическое S плюс табличный объём объектов и `voids * 1e22`.
- `V` — физическое S плюс табличный объём объектов и `voids * ExtraParams.VoidSize`.
- `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)`.
- `B = ExtraParams.DA * f(M)`, где `f(0)=1`, `f(M)=M^0.1` при `0<M<1e10`, иначе `10`.
- `density = ExtraParams.NPC * sqrt(B + M) / max(1, V)^(1/6)`.
- `blast_factor = clamp(free_S / V, 0, 1)`; при нулевом объёме `1`.
Планетные бонусы сил пока не перенесены. Параметры мира Bur/Exp/Agg имеют собственные сохраняемые шкалы и эффективные множители (см. раздел индикаторов ниже). Металличность для производства фиксируется до расходования ресурсов на звёзды. Среда бласта фиксируется для поколения до добавления его продуктов.
@@ -143,7 +145,11 @@ HP деградирует в RP. У эонов возможен откат к п
5. При флаге `colonizes` создаются колонии на две стадии ниже отправителя. Цели — существующие GG, AB, RP, HP; колонизация заменяет цель и сохраняет её звёздную привязку. Веса дрейфа колонистов — 960/4/9. Исходная цивилизация не расходуется. Новая партия начинается в текущий игровой момент.
6. После применения переходов пересчитываются этики, поклонение (`Σ population × worship`), бласты и ограничения среды. Число операций зависит от числа типов и партий, а не от числа цивилизаций.
Окна исходных партий сохраняют время переходов; несколько частей одного типа обрабатываются агрегированно между минимальным и максимальным временем. Побочный ущерб неистёкшим партиям применяется в текущий момент. Все остатки округления сохраняются в `civilization_remainders`, счётчики — в `civilization_stats`.
На скоростях 1–3 размер временной партии равен сроку жизни / 40. На скоростях 4–6 он равен максимуму этого значения и 100, 1000, 10000 игровых лет соответственно (0,1 реальной секунды). Близкие существующие партии объединяются при следующем шаге: целые количества и остатки изъятия складываются, временной интервал охватывает исходные партии. Это приближает моменты переходов внутри объединённого интервала. События со сроком жизни до 10 лет сохраняют прежние окна. При снижении скорости ранее объединённые партии не разделяются; новые получают меньшие окна. Шаг публикации на скоростях 4–6 ограничен 0,1 реальной секунды; накопленное отставание сохраняется.
Несколько частей одного типа обрабатываются агрегированно между минимальным и максимальным временем. На скоростях 4–6 новые партии жизни и цивилизаций после перехода создаются на ближайшей следующей границе интервала 100/1000/10000 лет. Начало сетки этих новых партий равно нулю независимо от старого `batch_origins`: округлённое время рождения не попадает обратно в раннюю часть старого окна. Это исключает повторные попытки эволюции той же выходящей популяции внутри её временного интервала; следующие интервалы продолжают обрабатываться. На скоростях 1–3 сохраняются исходные интервалы рождения и последовательные поколения. Звёздные события используют прежнюю схему.
Побочный ущерб неистёкшим партиям применяется в текущий момент. Все остатки округления сохраняются в `civilization_remainders`, счётчики — в `civilization_stats`.
### Структуры и периоды
@@ -206,3 +212,26 @@ Ct не получает часы. Инициализация отсутству
При достижении 1 учитываются все целые срабатывания, дробный остаток сохраняется. Только Integration имеет последствия в исходной Unity: равновероятно выбирается Federation (+0,1 и Agg −1), Enlightenment (+0,2 и Agg −1) или Order (+0,1). Генератор сохраняет своё состояние. До 256 событий за шаг выбор выполняется по одному; для больших количеств используется нормальная аппроксимация мультиномиального распределения с сохранением точного суммарного числа событий, чтобы высокие скорости не блокировали кадр. Она может менять последовательность исходов при другом разбиении больших интервалов.
Federation сохраняется и увеличивается как в Unity, но в исходном коде не применяется к дипломатии. Дополнительное правило для него не придумано. Остальные четыре тенденции имеют счётчики срабатываний и сброс, но не последствия — так же, как в исходной реализации. Параметры и остатки тенденций сохраняются; у существующего сохранения текущего формата без этих полей используются нейтральные значения и нулевые тенденции, без изменения ресурсов или возраста.
## Дополнительные параметры
Рабочая таблица встроена в `data/owniverse_extra_param_loader.gd` как `const DATA`,
по аналогии с остальными таблицами. В `Global._init()` вызывается get_data() до создания главной сцены:
CSVLoader разбирает строки, колонка `param export` преобразуется через E.of.
Результат хранится только в `Global.ExtraParams`. После редактирования таблицы
требуется перезапуск игры; отдельного CSV и статического кэша загрузчика нет.
Из таблицы берутся начальная энергия E, добавочная масса DA, коэффициент NPC,
размер пустот VoidSize, показатель степени combustibility_bonus для горючести
выше единицы, пороги bigrip1–3 и bigcrunch1–3. Интервалы индикатора плотности
вычисляются из тех же порогов, без дублирующих числовых констант.
Начальная энергия относится к новым вселенным; запас энергии существующей
вселенной остаётся частью её сохранения.
G, C, PI, helium_multiplier, helium_bonus_limit, space_generation, ChatPerTick
и параметры ForceBox загружаются, но пока не используются в GI: соответствующие
формулы и механики старой Unity-версии здесь отсутствуют. Производство объектов
в GI задаётся их собственной таблицей life_product и lifespan.
`tests/test_extra_params.gd` проверяет загрузку точных чисел и изменение энергии,
плотности, объёма пустот, порогов индикатора и бонуса горючести.
+21 -4
View File
@@ -9,6 +9,10 @@ const ItemDescription = preload("res://world/owniverse/item_description.gd")
const WorldIndicators = preload("res://ui/indicators/world_indicators.gd")
var world_indicators: RefCounted
var indicator_elapsed: float = 0.0
var indicator_revision: int = -1
var actions_revision: int = -1
var descriptions_revision: int = -1
var displayed_year: Variant = null
var description_targets: Dictionary = {}
var description_samples: Dictionary = {}
var description_rates: Dictionary = {}
@@ -159,6 +163,11 @@ func _update_descriptions(delta: float) -> void:
description_elapsed += delta
if description_elapsed < 0.25:
return
if descriptions_revision == owniverse.presentation.revision:
var has_rate: bool = false
for rate in description_rates.values(): has_rate = has_rate or E.ne(rate, 0)
if not has_rate: return
descriptions_revision = owniverse.presentation.revision
for page in description_targets:
var id: String = description_targets[page].id
var total = ItemDescription.quantities(owniverse, id).total
@@ -347,6 +356,10 @@ func create_new_universe() -> void:
g_tween.kill()
g_active_items.clear()
description_targets.clear()
indicator_revision = -1
actions_revision = -1
descriptions_revision = -1
displayed_year = null
description_samples.clear()
description_rates.clear()
description_elapsed = 0.0
@@ -380,12 +393,15 @@ func _process(delta: float) -> void:
owniverse.evolute_frame(delta, get_tree())
indicator_elapsed += delta
if indicator_elapsed >= 0.1:
if indicator_elapsed >= 0.1 and indicator_revision != owniverse.presentation.revision:
indicator_elapsed = 0.0
world_indicators.update(owniverse)
indicator_revision = owniverse.presentation.revision
_update_descriptions(delta)
set_owniverse_item_value()
set_datetime(owniverse.state.time.year)
if not owniverse.presentation.pending_amounts.is_empty(): set_owniverse_item_value()
if displayed_year == null or E.ne(displayed_year, owniverse.state.time.year):
set_datetime(owniverse.state.time.year)
displayed_year = owniverse.state.time.year
#owniverse.cycle(delta)
@@ -397,10 +413,11 @@ func _process(delta: float) -> void:
# them when selection changes and at a modest cadence instead of every
# rendered frame. The simulation itself continues to run every frame.
active_actions_elapsed += delta
if active_actions_dirty or active_actions_elapsed >= 0.1:
if active_actions_dirty or (active_actions_elapsed >= 0.1 and actions_revision != owniverse.presentation.revision):
active_actions_elapsed = 0.0
active_actions_dirty = false
_set_active_page_actions()
actions_revision = owniverse.presentation.revision
func _change_speed(delta: int) -> void:
+109
View File
@@ -1,5 +1,24 @@
# Проверки поэтапного переноса из Owniverse.U
`test_simulation_optimizations.gd` сравнивает прямые формулы дрейфа с прежней
матрицей, включая целые количества больше E27 и накопленные остатки.
Тестовый ledger сверяет выборочное округление с полным на каждом поколении
нагруженной симуляции. `test_ui_updates.gd` проверяет обновление по публикации,
выбору объекта и изменению параметров мира, а также пропуск повторных расчётов
для неизменившегося состояния.
Динамический размер партий проверяется в `test_batch_boundaries.gd`: скорости
1–6, сохранение больших целых количеств и дробных остатков, повторное
укрупнение и снижение скорости. Высокие скорости допускают приближение
времени переходов; сравнение со старым состоянием целиком не является
проверкой эквивалентности такого режима.
`test_coarse_generations.gd` проверяет отсутствие повторного перехода C0.0,
C0.1 и C0.2 внутри одного интервала, старое смещение сетки партий,
продолжение эволюции в следующем интервале, большие целые количества и
дробные остатки. `test_frame_evolution.gd` сравнивает целый и разбитый по
кадрам расчёт, включая возобновление сохранённого незавершённого шага.
## Производительность на сохранении
```sh
@@ -205,3 +224,93 @@ Stage вызывает `evolute_frame`: транзакция получает б
15.9 FPS (максимальный кадр 98 мс), большие количества 17.5 FPS (106 мс),
много партий 16.3 FPS (97 мс).
Это FPS отрисовки, а не число завершённых транзакций симуляции в секунду.
Индекс партий переиспользуется внутри одной транзакции, отдельно для каждого
массива партий. Замена массива при изъятии или переход к другому состоянию
сбрасывает индекс. Сортировка выполняется при нарушении порядка новых окон,
а не после каждого добавления в уже существующее окно. `test_batch_boundaries`
проверяет объединение, раннюю вставку, замену массива и изоляцию состояний.
На копии текущего сохранения с 785 партиями шесть шагов на скорости 6:
среднее время 167 → 145 мс; полное состояние после шести шагов совпало точно.
Следующий этап исключает арифметическую работу при прибавлении нуля,
временные знаменатели при умножении целых блоков и нулевые вклады этик.
На той же копии сохранения среднее время шага скорости 6 снизилось с 145
до 138 мс; полный результат после шести шагов совпал с исходным состоянием.
Тест появления разума задаёт свой progress явно, поскольку проверяет
сохранение хозяина планеты, а не актуальное значение коэффициента баланса.
Следующие шесть оптимизаций: однократное изъятие умирающих партий;
поверхностные снимки неизменяемых таблиц связей; пропуск планирования
цивилизаций без переходов; кэш нормализованных этик и произведений поклонения;
пропуск укрупнения для нуля/одной партии; кэш вероятностей переходов.
Кэши принадлежат миру и не входят в сохранение. Изменение количества,
этик, коэффициентов правил или модификаторов обнаруживается по значениям.
Суммирование поклонения сохраняет прежний порядок дробных операций.
`test_simulation_optimizations` проверяет также обновление этих кэшей.
Полное состояние совпало с реализацией до этих шести изменений после каждого
из восьми шагов на скоростях 1, 4 и 6, отдельно на большом фрагментированном
сценарии и на диагностической копии сохранения (48 сравнений).
На M4 Pro шесть шагов по 0.1 секунды скорости 6: 103.3 мс первый,
70.9–76.0 мс последующие; пропускная способность без UI 1.278.
Замер 600 кадров с реальным UI: 12.24 FPS, p95 97.16 мс, максимум 104.86 мс,
520 завершённых транзакций, отношение обработанного времени к поступившему
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.
Дипломатический drift использует шесть взвешенных вкладов вместо матрицы
пар этик: вес = сумма вкладов + 195 × свой вклад − противоположный вклад.
Для колониальной матрицы коэффициенты 9, 951 и 5 соответственно.
Целая численность и механизм сохранения ошибок распределения не меняются,
но порядок операций над дробными весами отличается от матричного варианта.
Тест сравнивает с матрицей на точно представимых коэффициентах и проверяет
целочисленное сохранение популяций до 1e40 на десятичных коэффициентах.
Пустые популяции пропускают drift; численность выходов суммируется один раз.
На профильной копии при шаге 0.5 число вызовов снизилось 1038 → 849
за шесть шагов, но время drift осталось около 303 мс суммарно;
заметного ускорения полного расчёта в этом сценарии не зафиксировано.
`test_split_optimizations.gd` сравнивает распределение и все сохранённые
остатки с прежним scalar split в последовательных вызовах: пустые ветви,
единственная ветвь, равные веса, десятичные веса, положительные/отрицательные
остатки, количества до 1e80. Также проверяет grouped mul_div против scalar.
Split переиспользует разложение количества и знаменателя между ветвями,
кэширует ключи остатков (не более 512 наборов) и получает веса дрифта массивом.
Вторая нормализация пропускается только при целых долях с нужной суммой:
при дробях даже единичное отношение может изменить округление, поэтому
прежний путь сохраняется. Единственная положительная ветвь обрабатывается
напрямую только при целом количестве, неотрицательных весах и нулевых остатках.
На профильной копии время drift за шесть шагов 0.5 снизилось примерно
303 → 287 мс, но общее время осталось около 1.31 секунды.
Обычный drift сокращает целое количество из отношения
count*weight/(200*count), колониальный — из отношения с 1000.
Целая часть делится на малый знаменатель; для дроби используются исходные
масштабированные числитель и знаменатель, чтобы сохранить float округление.
`test_split_optimizations` проверяет совпадение со scalar mul_div до 1e80.
Производство новорождённых сохраняет только created_from → amount вместо
глубокой копии партий. Повторное мгновенное рождение с теми же сроками,
длительностью и сеткой сразу добавляется в найденную партию.
Индекс ближайшей границы позволяет повторным проходам пропускать будущие
партии; замена массива, добавление и масштабирование сбрасывают индекс.
Тест границ проверяет объединение и сброс обоих индексов.
Адаптивный шаг дополнительно учитывает сглаженное отношение реальной
длительности транзакции к обработанному времени. Если отношение выше 0.85
и долг больше одного шага, ступень увеличивается раньше порога двух шагов.
Долг и граница сохраняются как прежде; измерения являются временным кэшем.
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,63 @@
# Все объекты, скорость 6
Создано скриптом `tests/create_full_benchmark_save.gd`. Пароль нативного сохранения: `qwerty`.
Генератор не читает и не перезаписывает сохранение игрока.
Начальное состояние: 151 запись каталога (включая группы), все 44 стадии правил цивилизаций, все шесть этик на каждой стадии, 1000 когорт (по десять на сущность с временными партиями). У большинства обычных объектов количество равно 6e60, у стадий цивилизаций — 6e20. Пространство и водород имеют количество 1e90, гелий и металлы — 1e80, энергия — 1e100. Возраст — 1e15 лет. Запасов достаточно для требований продвинутых стадий звезд и структур. Оставшиеся сроки жизни когорт покрывают весь срок жизни сущностей, поэтому переходы происходят во время замера.
Это искусственный экстремальный сценарий, а не прогноз для обычного сохранения.
Машина: Apple M4 Pro, Godot 4.7.2, рендерер Metal Mobile.
| Замер | Результат |
|---|---:|
| Headless, скорость 6, шесть шагов по 0,5 секунды | 943,936–1221,992 мс на шаг |
| Среднее время headless-шага | 1122,287 мс |
| Пропускная способность headless | 0,446 секунды симуляции на секунду CPU |
| Настоящий UI, страница цивилизаций, 600 кадров | 17,38 FPS |
| Средний / p95 / максимальный кадр UI | 57,55 / 99,78 / 116,94 мс |
| Завершенные транзакции | 23 |
| Запрошенный прирост игрового времени | 3464662,267 лет |
| Опубликованный прирост игрового времени | 1080000 лет |
| Пропускная способность с UI | 0,3117 |
| Накопленный долг за замер | 2384662,267 игровых лет (23,85 реальных секунд на скорости 6) |
| Записей каталога осталось в конце | 151 |
Динамический шаг достигает предела в 0,5 секунды. Рендеринг идет быстрее 5 FPS, но симуляция не успевает за заданным темпом в этом сценарии. На обработку поколений приходится примерно 94% времени CPU. Подготовка цивилизаций занимает в среднем 634 мс на шаг, в том числе дрифт этик — 218 мс, войны — 124 мс; колонизация — 121 мс на шаг. Интервалы профилировщика вложенные и частично перекрываются.
## Сравнение оптимизации дрифта (2026-10-05)
Замеры сделаны на одном сгенерированном сохранении и одной машине до и после прямого распределения потоков для обычного и колониального дрифта, а также кеширования ставок дипломатии в фиксированной точке. Каждый headless-запуск выполняет шесть последовательных шагов по 0,5 секунды на каждой скорости.
| Замер | До | После |
|---|---:|---:|
| Средний headless-шаг на скорости 6 | 1122,287 мс | 1018,559 мс |
| Пропускная способность headless на скорости 6 | 0,446 | 0,491 |
| Дрифт этик, сумма интервалов за шесть шагов | 1,338 с | 0,643 с |
| UI, FPS за 600 кадров | 17,38 | 17,04 |
| Средний / p95 / максимальный кадр UI | 57,55 / 99,78 / 116,94 мс | 58,70 / 102,67 / 114,30 мс |
| Завершенные UI-транзакции | 23 | 25 |
| Запрошено / опубликовано игровых лет в UI | 3464662 / 1080000 | 3533627 / 1180000 |
| Пропускная способность симуляции с UI | 0,3117 | 0,3339 |
Средний headless-шаг ускорился примерно на 9,2%, а интервал профиля дрифта этик сократился примерно на 52%. Частота кадров UI практически не изменилась (в этом запуске снизилась примерно на 2%), при этом завершилось больше транзакций и выросла доля опубликованного игрового времени. На скорости 6 стресс-сценарий все еще отстает от реального времени: пропускная способность — около 0,49 секунды симуляции на секунду CPU в headless и 0,33 с UI. Самыми затратными остаются планирование поколений и войны.
Прямые пути сохраняют целое население, но разносят малые целочисленные потоки по нескольким последовательным переходам с помощью остатков для каждого источника. Поэтому распределение в отдельном переходе отличается от независимого округленного распределения по матрице 6×6. Ставки дипломатии округляются до сетки фиксированной точки с шагом 1e-9. Целевая регрессия: 769 проверок эволюции цивилизаций, оптимизаций симуляции, границ партий, укрупненных поколений и эволюции кадров; все пройдены.
## Последующая оптимизация подготовки поколений и кешей (2026-10-05)
На той же нагрузке среднее время headless-шага на скорости 6 снизилось с 1018,559 до 1005,138 мс (примерно на 1,3%). Пропускная способность headless изменилась с 0,491 до 0,497. Суммарные интервалы `generations` близки: 5,703 с и 5,629 с за шесть шагов. Подготовка цивилизаций остается самой затратной измеренной подфазой — 3,130 с. UI также почти не изменился: 17,04 → 17,09 FPS, пропускная способность симуляции — 0,3339 → 0,3351. Улучшение небольшое: арифметика населения в поколениях по-прежнему дорога при сотнях активных когорт и множестве правил цивилизаций.
Профиль теперь отдельно показывает `generation_withdrawal` и `generation_products`. Первый интервал занимает 55,5 мс, второй — 120,2 мс за шесть headless-шагов на скорости 6. Эти значения нельзя складывать с общим временем поколений, поскольку интервалы профилировщика вложенные.
## Инкрементальная обработка партий новорожденных (2026-10-05)
Удалены снимки когорт до и после рождения и последующий полный обход когорт. `append_batch` теперь сразу накапливает поправку на возраст новорожденных при добавлении частей когорт. Финальный замер после повторного использования сумм завершившихся партий в пределах поколения дал 1028,991 мс на headless-шаг скорости 6 и пропускную способность 0,486. В повторных прогонах этой же версии получилось 1005–1011 мс, поэтому при выборке всего в шесть шагов разброс велик, и устойчивое ускорение утверждать нельзя. В UI получилось 17,05 FPS, среднее время кадра 58,66 мс и пропускная способность 0,3342. Новый профиль показывает 319 мс на обработку партий новорожденных за шесть шагов. Это изменение пока не демонстрирует снижения общего времени на этом сохранении; его потенциальная польза относится прежде всего к сценариям с гораздо большим числом когорт на сущность, где прежние обходы росли пропорционально числу когорт.
Повторить замеры из родительской папки проекта:
```sh
godot --headless --path Owniverse.GI --script res://tests/create_full_benchmark_save.gd
godot --headless --path Owniverse.GI --script res://tests/benchmark_saved_state.gd -- Owniverse.GI/tests/artifacts/all_objects_speed6.adventure.json 0.5 profile
godot --path Owniverse.GI --script res://tests/benchmark_full_ui.gd
```
+48
View File
@@ -0,0 +1,48 @@
extends SceneTree
const E = preload("res://world/owniverse/math/exact.gd")
func _initialize(): call_deferred("run")
func restore(value):
if value is float and value == floorf(value) and absf(value) <= 9007199254740991: return int(value)
if value is Dictionary:
for k in value: value[k] = restore(value[k])
elif value is Array:
for i in value.size(): value[i] = restore(value[i])
return value
func run():
var payload = E.decode(restore(JSON.parse_string(FileAccess.get_file_as_string("res://tests/artifacts/all_objects_speed6.adventure.json"))))
var scene = load("res://world/world.tscn").instantiate()
var stage = scene.get_node("Stage")
stage.owniverse.free()
stage.set_script(load("res://tests/fixtures/benchmark_ui_stage.gd"))
root.add_child(scene)
await process_frame
stage.owniverse.state = payload.state.duplicate(true)
stage.owniverse.restore_frame_checkpoint(payload.get("simulation", {}))
stage.owniverse.presentation.refresh(stage.owniverse.state, stage.owniverse.catalog)
stage.set_owniverse_item_value()
stage.stage_page_scroller.scroll_horizontal = 4 * stage.PAGE_WIDTH
var initial_requested: Variant = stage.owniverse.frame_clock.get("datetime", stage.owniverse.state.time.datetime)
var initial_published: Variant = stage.owniverse.state.time.datetime
stage.owniverse.profile_enabled = true
stage.measuring = true
for i in 600: await process_frame
stage.measuring = false
var samples = stage.frame_samples
var total: float = 0
for sample in samples: total += sample
samples.sort()
print("Saved UI: FPS=%.2f mean=%.2fms p95=%.2fms max=%.2fms commits=%d" % [1000.0/(total/samples.size()),total/samples.size(),samples[int(ceil(samples.size()*0.95))-1],samples.back(),stage.owniverse.frame_commits])
var requested_advance: Variant = E.subtract(stage.owniverse.frame_clock.datetime, initial_requested)
var published_advance: Variant = E.subtract(stage.owniverse.state.time.datetime, initial_published)
print("Requested years advanced=", requested_advance, " published=", published_advance, " throughput=", E.divide(published_advance, requested_advance))
print("UI CPU profile: ", stage.owniverse.profile)
var remaining_objects: int = 0
for id in stage.owniverse.catalog.entities:
if E.gt(stage.owniverse.ledger.physical_amount(stage.owniverse.state, id), 0): remaining_objects += 1
print("Remaining objects: ", remaining_objects)
print("Final adaptive step: ", stage.owniverse.frame_step_seconds)
for entity in stage.owniverse.catalog.entities.values(): entity.free()
stage.owniverse.free()
scene.free()
for i in 3: await process_frame
quit()
+1
View File
@@ -0,0 +1 @@
uid://3xjh23kg5vrn
+8
View File
@@ -27,6 +27,8 @@ func run():
quit(1)
return
var initial: Dictionary = E.decode(restore_json_integers(data)).state
var validation: String = root.get_node("SaveManager").validate_data(E.decode(restore_json_integers(data)))
print("Save validation: ", "OK" if validation.is_empty() else validation)
var delta: float = args[1].to_float() if args.size() > 1 else 1.0 / 60.0
if not is_finite(delta) or delta <= 0:
quit(1)
@@ -36,12 +38,18 @@ func run():
world.catalog.load_definitions(root.get_node("Global").OwniverseEntities)
world.state = initial.duplicate(true)
world.speed = speed
world.profile_enabled = args.has("profile")
var elapsed: Array = []
for cycle in 6:
var start: int = Time.get_ticks_usec()
world.evolute(delta)
elapsed.append((Time.get_ticks_usec() - start) / 1000.0)
print("Speed %d, six consecutive %s-second steps, ms: %s" % [speed, delta, elapsed])
var total_ms: float = 0.0
for sample in elapsed: total_ms += sample
var throughput: float = 6.0 * delta / (total_ms / 1000.0)
print("Simulation throughput: %.3f real-time seconds processed per CPU second; needs >= 1.0 to keep up" % throughput)
if world.profile_enabled: print("CPU profile (usec, calls): ", world.profile)
for entity in world.catalog.entities.values(): entity.free()
world.free()
quit()
+51
View File
@@ -0,0 +1,51 @@
extends SceneTree
## Reproducible stress save; never writes to the player's user:// directory.
const E = preload("res://world/owniverse/math/exact.gd")
const State = preload("res://world/owniverse/civilization_state.gd")
func _initialize(): call_deferred("run")
func run():
var global: Node = root.get_node("Global")
var world = load("res://world/owniverse/owniverse.gd").new()
world.catalog.load_definitions(global.OwniverseEntities)
world.speed = 6
world.state.time = {"datetime": 1000000000000000, "year": 1000000000000000, "tick_remainder": 0}
world.state.energy = E.of("1e100")
for id in world.catalog.entities:
world.state.amount[id] = E.of("6e60")
world.state.stats.total_amount[id] = world.state.amount[id]
if global.CivilizationRules.has(id): world.state.amount[id] = E.of("6e20")
world.state.amount.S = E.of("1e90")
world.state.amount.H = E.of("1e90")
world.state.amount.He = E.of("1e80")
world.state.amount.Met = E.of("1e80")
world.ledger.refresh_groups(world.state)
State.enforce_capacity(world, world.state, global.CivilizationRules, world.state.time.year)
State.reconcile(world, world.state, global.CivilizationRules)
var cohorts: int = 0
for id in world.catalog.entities:
if world.catalog.is_group(id): continue
var lifespan: Variant = State.effective_span(world, world.state, id, global.CivilizationRules)
if E.le(lifespan, 0): continue
world.state.batches[id] = []
var width: Variant = E.divide(lifespan, 10)
for i in 10:
var start: Variant = E.add(world.state.time.year, E.multiply(width, i))
var end: Variant = E.add(start, width)
var birth: Variant = E.subtract(start, lifespan)
world.state.batches[id].append({"amount": E.divide(world.state.amount[id], 10), "created_from": birth, "created_to": E.add(birth, width), "start_year": start, "end_year": end})
cohorts += 1
world.state.batch_origins[id] = world.state.batches[id][0].created_from
world.state.stats.total_amount = world.state.amount.duplicate(true)
var manager: Node = root.get_node("SaveManager")
var folder: String = ProjectSettings.globalize_path("res://tests/artifacts")
DirAccess.make_dir_recursive_absolute(folder)
manager.save_directory = folder
global.save_plaintext_copy = true
var success: bool = manager.save_data("all_objects_speed6", "qwerty", {"state": world.state, "simulation": world.frame_checkpoint(), "ui": {"current_page": 4}})
var empty: Array = []
for id in world.catalog.entities:
if E.le(world.state.amount.get(id, 0), 0): empty.append(id)
print("Full save: objects=%d civilization stages=%d cohorts=%d empty=%s success=%s" % [world.catalog.entities.size(), global.CivilizationRules.size(), cohorts, empty, success])
for entity in world.catalog.entities.values(): entity.free()
world.free()
quit(0 if success and empty.is_empty() else 1)
+1
View File
@@ -0,0 +1 @@
uid://1icskkk5nld8
+12
View File
@@ -0,0 +1,12 @@
extends "res://world/owniverse/object_ledger.gd"
var checks: int = 0
var failures: int = 0
func round_object_allocations(target: Dictionary, affected: Variant = null) -> void:
var reference: Dictionary = target.duplicate(true)
super.round_object_allocations(reference)
super.round_object_allocations(target, affected)
checks += 1
if not E.eq(target, reference):
failures += 1
push_error("Selective rounding differs from full rounding")
+1
View File
@@ -0,0 +1 @@
uid://csew6jyuiwxh0
+8
View File
@@ -1,4 +1,12 @@
extends "res://stage/stage.gd"
var actions_refreshes: int = 0
func tick_ui(delta: float) -> void:
super._process(delta)
func _set_active_page_actions() -> void:
actions_refreshes += 1
super._set_active_page_actions()
# Keep scene wiring and display logic, without accessing the player's save.
func load_data() -> bool:
+55
View File
@@ -38,6 +38,43 @@ func dispose(world) -> void:
func run() -> void:
var world = fixture()
world.catalog.entities.N.lifespan = 100
world.batches.append_batch(world.state, "N", 2, 10, 10)
world.batches.append_batch(world.state, "N", 3, 10, 10)
check(world.state.batches.N.size() == 1 and E.eq(world.state.batches.N[0].amount, 5), "Repeated insertion merges using the cohort index")
world.batches.append_batch(world.state, "N", 1, 0, 0)
check(E.eq(world.state.batches.N[0].created_from, 0), "Earlier insertion preserves chronological order")
var replaced: Array = world.state.batches.N.duplicate(true)
world.state.batches.N = replaced
world.batches.append_batch(world.state, "N", 7, 10, 10)
check(E.eq(replaced[1].amount, 12), "Replacing cohort array invalidates cached references")
var separate: Dictionary = world.state.duplicate(true)
world.batches.append_batch(separate, "N", 9, 10, 10)
check(E.eq(separate.batches.N[1].amount, 21) and E.eq(world.state.batches.N[1].amount, 12), "Index is isolated between transaction states")
dispose(world)
world = fixture()
for speed in range(1, 7):
world.state.speed = speed
check(E.eq(world.batches.window_duration(world.state, 100), 2.5 if speed < 4 else pow(10, speed - 2)), "Windows follow selected speed")
check(E.eq(world.batches.window_duration(world.state, 5), 5), "Short explosions retain their timing")
var huge: Variant = E.of("10000000000000000000000000000000000000000")
world.catalog.entities.N.lifespan = 100
world.state.batches.N = [
{"amount": huge, "start_year": 100, "end_year": 110, "created_from": 0, "created_to": 10, "withdraw_remainder": 0.25},
{"amount": 7, "start_year": 120, "end_year": 130, "created_from": 20, "created_to": 30, "withdraw_remainder": 0.5}
]
world.batches.coarsen(world.state)
check(world.state.batches.N.size() == 1, "High speed combines nearby cohorts")
check(E.eq(world.state.batches.N[0].amount, E.add(huge, 7)), "Coarsening preserves exact large whole counts")
check(E.eq(world.state.batches.N[0].withdraw_remainder, 0.75), "Coarsening preserves withdrawal carry")
var combined: Dictionary = world.state.batches.N[0].duplicate(true)
world.batches.coarsen(world.state)
check(world.state.batches.N[0] == combined, "Coarsening is idempotent")
world.state.speed = 1
world.batches.coarsen(world.state)
check(world.state.batches.N[0] == combined, "Slowing down does not invent finer history")
dispose(world)
world = fixture()
world.state.batch_origins.LGRB = E.of("10357034.80000000074505806")
var boundary: Variant = E.of("41215289.79999999701976776")
for interval in [[E.subtract(boundary, E.of("2.5")), E.add(boundary, E.of("2.25"))], [boundary, E.add(boundary, 2)]]:
@@ -54,5 +91,23 @@ func run() -> void:
check(E.eq(total, 100), "Boundary correction preserves all objects")
check(E.le(world.state.batches.LGRB.size(), 7), "Finite number of windows")
dispose(world)
world = fixture()
world.batches.append_batch(world.state, "N", 100, 100, 100)
var first: Dictionary = world.state.batches.N[0].duplicate(true)
world.batches.append_batch(world.state, "N", 7, 100, 100)
check(world.state.batches.N.size() == 1 and E.eq(world.state.batches.N[0].amount, 107), "Repeated births merge directly into one window")
check(E.eq(world.state.batches.N[0].start_year, first.start_year), "Direct merge preserves transition time")
check(world.batches.withdraw_batches(world.state, "N", 0).is_empty(), "Future cohorts are not withdrawn")
var untouched: Array = world.state.batches.N
check(world.batches.withdraw_batches(world.state, "N", 1).is_empty() and is_same(untouched, world.state.batches.N), "Readiness index skips future cohorts")
world.state.batches.N = [{"amount": 7, "start_year": 0, "end_year": 0, "created_from": 0, "created_to": 0}]
check(world.batches.withdraw_batches(world.state, "N", 1).size() == 1, "Replacing cohorts invalidates readiness index")
world.batches.append_batch(world.state, "N", 3, 100, 100)
check(E.eq(world.state.batches.N[0].amount, 3), "Replacing cohorts invalidates instant merge cache")
world.batches.withdraw_batches(world.state, "N", 0)
world.batches.scale_batches(world.state, "N", 0)
world.batches.withdraw_batches(world.state, "N", 1)
check(world.state.batches.N.is_empty(), "Scaling invalidates readiness and removes zero cohorts")
dispose(world)
print(("Batch boundaries: %d checks, %d failures" % [checks, failures]))
quit((0 if E.eq(failures, 0) else 1))
+83
View File
@@ -0,0 +1,83 @@
extends SceneTree
const E = preload("res://world/owniverse/math/exact.gd")
var checks: int = 0
var failures: int = 0
func _initialize(): call_deferred("run")
func check(condition: bool, message: String):
checks += 1
if not condition:
failures += 1
push_error(message)
func fixture(id: String, speed: int):
var world = load("res://world/owniverse/owniverse.gd").new()
world.catalog.load_definitions(root.get_node("Global").OwniverseEntities)
for entity in world.catalog.entities.values():
world.state.amount[entity.id] = 0
world.state.stats.total_amount[entity.id] = 0
if entity.group_as != "":
world.state.amount[entity.group_as] = 0
world.state.stats.total_amount[entity.group_as] = 0
world.state.amount.RD = 1
world.state.binds.RD = {id: 40000}
world.state.batches[id] = [{"amount": 40000, "start_year": 1, "end_year": 1}]
# A saved origin off the new grid must not backdate rounded successors.
world.state.batch_origins[id] = 500
world.speed = speed
world.profile_enabled = true
return world
func dispose(world):
for entity in world.catalog.entities.values(): entity.free()
world.free()
func run():
for id in ["C0.0", "C0.1", "C0.2"]:
var world = fixture(id, 6)
world.evolution.evolute_to_datetime(10000)
var physical: Dictionary = world.ledger.physical_amounts(world.state)
var population: Variant = 0
for stage in physical:
if world.catalog.entities[stage].group_as == "Planet":
population = E.add(population, physical[stage])
check(E.eq(population, 40000), "Coarse transitions preserve all whole populations: " + id)
for batches: Array in world.state.batches.values():
for batch: Dictionary in batches:
check(E.gt(batch.start_year, 10000), "Successors cannot expire inside their birth bucket: " + id)
if id == "C0.0":
check(E.eq(physical.get("C0.0", 0), 38300), "C0.0 attempts evolution once")
check(E.eq(physical.get("C0.1", 0), 700), "C0.0 progress rate is applied once")
check(E.eq(physical.get("EON5", 0), 1000), "C0.0 degradation rate is applied once")
elif id == "C0.1":
check(E.eq(physical.get("C0.1", 0), 38300), "C0.1 attempts evolution once")
check(E.eq(physical.get("C0.2", 0), 700), "C0.1 successor does not immediately attempt again")
else:
check(world.profile.civilization_transitions[1] == 1, "Ethical civilization is processed only once per birth bucket")
var before: Dictionary = world.state.duplicate(true)
world.evolution.evolute_to_datetime(10000)
check(E.eq(world.state, before), "Repeating completed clock does not repeat transitions")
var validation: String = root.get_node("SaveManager").validate_data({"format_version": 5, "app_version": "", "ui": {"current_page": 0}, "state": world.state})
check(validation.is_empty(), "Coarse state validates: " + validation)
world.evolution.evolute_to_datetime(20000)
if id in ["C0.0", "C0.1"]:
check(E.lt(world.ledger.physical_amounts(world.state)[id], 38300), "The next bucket still processes legitimate evolution: " + id)
dispose(world)
var fine = fixture("C0.0", 1)
fine.evolution.evolute_to_datetime(10000)
check(E.lt(fine.ledger.physical_amounts(fine.state)["C0.0"], 38300), "Low speeds retain multiple chronological generations")
dispose(fine)
var large = fixture("C0.0", 6)
var count: Variant = E.of("10000000000000000000000000000000000000001")
large.state.binds.RD["C0.0"] = count
large.state.batches["C0.0"][0].amount = count
var reference: Dictionary = large.state.duplicate(true)
var products: Dictionary = large.life.life_products(reference, large.catalog.entities["C0.0"], count)
large.evolution.evolute_to_datetime(10000)
var physical: Dictionary = large.ledger.physical_amounts(large.state)
for id in products:
check(E.eq(physical.get(id, 0), products[id]), "Large whole population undergoes one transition: " + id)
check(E.eq(large.state.life_remainders, reference.life_remainders), "Coarse timing preserves the single attempt's fractional carry")
dispose(large)
print("Coarse generations: %d checks, %d failures" % [checks, failures])
quit(1 if failures else 0)
+1
View File
@@ -0,0 +1 @@
uid://ggml5q061lwh
+4
View File
@@ -31,6 +31,10 @@ func run():
verify(not E.eq(E.of("1e1000"), INF), "huge number is not infinity")
verify(E.eq(E.floor_sum(huge, 2, 1, 2), E.divide(E.multiply(huge, E.subtract(huge, 1)), 2)), "floor sum supports huge window counts")
var rows = JSON.parse_string(FileAccess.get_file_as_string("res://tests/fixtures/big_integer_oracle.json"))
for row in rows.slice(0, 20):
var scaled = B.divmod(B.parse(row[0] + "000000000000000000"), B.parse(row[1] + "000000000000000000"))
verify(B.decimal(scaled[0]) == row[4], "cancel shared blocks preserves quotient")
verify(B.compare(scaled[1], B.multiply(B.parse(row[5]), B.parse("1000000000000000000"))) == 0, "cancel shared blocks restores original remainder")
for row in rows:
var a: Array = B.parse(row[0])
var b: Array = B.parse(row[1])
+54
View File
@@ -0,0 +1,54 @@
extends SceneTree
const E = preload("res://world/owniverse/math/exact.gd")
const Extra = preload("res://data/owniverse_extra_param_loader.gd")
const Parameters = preload("res://world/owniverse/world_parameters.gd")
var checks: int = 0
var failures: int = 0
func _initialize(): call_deferred("run")
func check(ok: bool, label: String):
checks += 1
if not ok:
failures += 1
push_error(label)
func run():
var global = root.get_node("Global")
check(E.eq(global.ExtraParams, Extra.get_data()), "Global table equals loader data")
check(E.eq(global.ExtraParams.E, E.of("1e27")), "Energy parsed as exact integer")
check(E.eq(global.ExtraParams.DA, 65536), "Export column is used, not formatted display column")
var saved: Dictionary = global.ExtraParams.duplicate()
global.ExtraParams.E = E.of("1e40")
var world = load("res://world/owniverse/owniverse.gd").new()
world.catalog.load_definitions(global.OwniverseEntities)
check(E.eq(world.state.energy, E.of("1e40")), "New world uses configured energy")
var initial: Dictionary = world.environment.stellar_environment(world.state)
global.ExtraParams.DA = E.multiply(saved.DA, 4)
check(E.near(world.environment.stellar_environment(world.state).density, E.multiply(initial.density, 2)), "Base mass changes density")
global.ExtraParams.DA = saved.DA
global.ExtraParams.NPC = E.multiply(saved.NPC, 2)
check(E.near(world.environment.stellar_environment(world.state).density, E.multiply(initial.density, 2)), "NPC changes density")
global.ExtraParams.NPC = saved.NPC
world.state.amount.S = E.of("1e24")
world.state.amount.LGF = 1
var old_density = world.environment.stellar_environment(world.state).density
global.ExtraParams.VoidSize = E.multiply(saved.VoidSize, 100)
check(E.lt(world.environment.stellar_environment(world.state).density, old_density), "Void volume uses configured size")
global.ExtraParams.bigcrunch1 = E.of("0.5")
global.ExtraParams.bigcrunch2 = E.of("0.6")
global.ExtraParams.bigcrunch3 = E.of("0.7")
check(Parameters.density_display(E.of("0.6")).mode == "DensityCrunch", "Configured crunch start")
check(E.near(Parameters.density_display(E.of("0.6")).position, E.of("0.5")), "Crunch indicator uses configured interval")
check(Parameters.density_warning_color(E.of("0.6")) == Color.html("20b0dfbf"), "Configured middle crunch warning")
global.ExtraParams.bigrip1 = E.of("0.01")
global.ExtraParams.bigrip2 = E.of("0.001")
global.ExtraParams.bigrip3 = E.of("0.0001")
check(Parameters.density_display(E.of("0.001")).mode == "DensityRip", "Configured rip start")
check(E.near(Parameters.density_display(E.of("0.001")).position, E.of("0.5")), "Rip indicator uses configured interval")
check(Parameters.density_warning_color(E.of("0.001")) == Color.html("df2020bf"), "Configured middle rip warning")
world.state.world_parameters.Bur = 19
global.ExtraParams.combustibility_bonus = 1
check(E.eq(Parameters.production(world.state, world.catalog.entities.RD), Parameters.effective(world.state, "Bur")), "Configured combustion exponent")
global.ExtraParams.merge(saved, true)
for entity in world.catalog.entities.values(): entity.free()
world.free()
print("Extra params: %d checks, %d failures" % [checks, failures])
quit(1 if failures else 0)
+1
View File
@@ -0,0 +1 @@
uid://doertyqlkrm26
+20
View File
@@ -96,5 +96,25 @@ func run():
invalid.evolute(1e308)
check(not invalid.frame_busy and invalid.frame_clock.is_empty() and E.eq(before, invalid.state), "Overflowing elapsed float cannot enter either clock API")
dispose(invalid)
var adaptive = fixture()
adaptive.frame_clock = Clock.advance(adaptive.state.time, 10.0, 6)
var debt_clock: Dictionary = adaptive.frame_clock.duplicate(true)
check(adaptive.update_frame_step() == 0.2, "Growing debt increases step to 0.2 seconds")
check(adaptive.update_frame_step() == 0.5, "Large debt increases step to bounded 0.5 seconds")
check(adaptive.update_frame_step() == 0.5 and E.eq(adaptive.frame_clock, debt_clock), "Maximum step preserves requested time")
adaptive.frame_clock = Clock.advance(adaptive.state.time, 0.3, 6)
check(adaptive.update_frame_step() == 0.5, "Hysteresis keeps step between thresholds")
adaptive.frame_clock = Clock.advance(adaptive.state.time, 0.05, 6)
check(adaptive.update_frame_step() == 0.2, "Small debt reduces step")
check(adaptive.update_frame_step() == 0.1, "Caught-up simulation returns to base step")
adaptive.frame_clock = Clock.advance(adaptive.state.time, 0.15, 6)
adaptive._frame_cost_ratio = 1.1
check(adaptive.update_frame_step() == 0.2, "Measured slow transactions increase step before two-step debt")
adaptive.frame_clock = Clock.advance(adaptive.state.time, 0.05, 6)
adaptive.speed = 3
check(adaptive.update_frame_step() == 1.0 / 60.0, "Low speeds retain 60 Hz scheduling")
adaptive.speed = 6
check(adaptive.update_frame_step() == 0.1, "Speed switch resets adaptive step")
dispose(adaptive)
print("Frame evolution: %d checks, %d failures" % [checks, failures])
quit(1 if failures else 0)
+2
View File
@@ -66,6 +66,8 @@ func run() -> void:
world = fixture()
world.state.amount.RD = 1
world.state.binds.RD = {"EON5": 40000}
# Test host preservation with a fixed rate, independent of game balance.
world.catalog.entities.EON5.life_rule.progress = "0.00025"
world.evolution.initialize_life_batches()
world.evolution.evolve_batches(world.state, E.add(500000, E.divide(500000, 40)))
check(E.eq(world.state.binds.RD["C0.0"], 10), "Intelligence emerges at the same host star")
+3
View File
@@ -30,6 +30,9 @@ func run() -> void:
for id in requests: requests[id] = E.multiply(requests[id], E.of("1e40"))
var limit: Variant = E.multiply(rng.randi_range(0, 600), E.of("1e40")) if sample % 3 == 0 else rng.randi_range(0, 600)
check(E.eq(Math.allocate_whole(requests, limit), Legacy.allocate_whole(requests, limit)), "Allocation matches legacy with limits, ties and big integers")
var whole_requests: Dictionary = {}
for id in requests: whole_requests[id] = E.floor_value(E.maximum(0, requests[id]))
check(E.eq(Math.allocate_whole(whole_requests, limit), Math.allocate_whole_with_total(whole_requests, limit, Math.sum(whole_requests))), "Known-total allocation matches ordinary allocation")
var count: Variant = limit
check(E.eq(Math.split(new_remainders, "population", count, weights), Legacy.split(old_remainders, "population", count, weights)), "Split matches legacy rounding")
check(E.eq(new_remainders, old_remainders), "Signed remainder debt matches legacy")
+112
View File
@@ -0,0 +1,112 @@
extends SceneTree
const E = preload("res://world/owniverse/math/exact.gd")
const Civ = preload("res://world/owniverse/civilization_evolution.gd")
const Fixture = preload("res://tests/fixtures/civilization_benchmark.gd")
var checks: int = 0
var failures: int = 0
func _initialize(): call_deferred("run")
func check(value: bool, message: String):
checks += 1
if not value:
failures += 1
push_error(message)
func reference_drift(target: Dictionary, pop: Dictionary, rows: Dictionary, diplomacy: bool, colony: bool) -> Dictionary:
var weights: Dictionary = {}
for other in Civ.ETHICS: weights[other] = 0
for ethic in pop:
var contribution: Variant = E.multiply(pop[ethic], E.of(rows[ethic].diplomacy_rate) if diplomacy else 1)
if E.eq(contribution, 0): continue
for other in Civ.ETHICS:
var weight: int = 9 if colony else 1
if other == ethic: weight = 960 if colony else 196
elif other == Civ.OPPOSITE[ethic]: weight = 4 if colony else 0
weights[other] = E.add(weights[other], E.multiply(contribution, weight))
if E.le(Civ.total(weights), 0): return pop.duplicate()
return Civ.split(target, "test", Civ.total(pop), weights)
func run():
var rows: Dictionary = {}
for ethic in Civ.ETHICS: rows[ethic] = {"diplomacy_rate": "0.125" if ethic == "m" else "1.75"}
for count in [0, 1, 7, 999999999, E.of("1e40")]:
for diplomacy in [false, true]:
for colony in [false, true]:
var actual: Dictionary = {}
var reference: Dictionary = {}
for round_index in 5:
var pop: Dictionary = {"m": count, "l": round_index, "w": 9, "d": 0, "c": 137, "b": 2}
var result: Dictionary = Civ.drift(actual, "test", pop, rows, diplomacy, colony)
if diplomacy:
check(E.eq(result, reference_drift(reference, pop, rows, diplomacy, colony)), "Diplomatic drift preserves allocation")
var carries_valid: bool = true
for value in actual.get("civilization_remainders", {}).values():
carries_valid = carries_valid and E.ge(value, -1) and E.le(value, 1)
check(carries_valid, "Diplomatic drift carries stay bounded")
else:
check(E.eq(Civ.total(result), Civ.total(pop)), "Integer flow drift conserves population")
var valid_whole: bool = true
for ethic in Civ.ETHICS:
valid_whole = valid_whole and E.ge(result[ethic], 0) and E.eq(result[ethic], E.floor_value(result[ethic]))
check(valid_whole, "Integer flow drift has nonnegative whole counts")
var decimal_rows: Dictionary = {}
for ethic in Civ.ETHICS: decimal_rows[ethic] = {"diplomacy_rate": "0.333333333333" if ethic == "m" else "0.017"}
var decimal_target: Dictionary = {}
for round_index in 20:
var pop: Dictionary = {"m": E.of("1e40"), "l": round_index, "w": 17, "d": 4, "c": 91, "b": 2}
var result: Dictionary = Civ.drift(decimal_target, "decimal", pop, decimal_rows, true)
check(E.eq(Civ.total(result), Civ.total(pop)), "Decimal diplomatic drift preserves whole population")
for ethic in result:
check(E.ge(result[ethic], 0) and E.eq(result[ethic], E.floor_value(result[ethic])), "Decimal drift returns nonnegative whole counts")
for speed in [1, 4, 6]:
var world = load("res://world/owniverse/owniverse.gd").new()
world.catalog.load_definitions(root.get_node("Global").OwniverseEntities)
Fixture.seed(world, root.get_node("Global"), true, true)
var rules: Dictionary = root.get_node("Global").CivilizationRules
var id: String = rules.keys()[0]
var modifiers: Dictionary = {"progress": 1, "degradation": 1, "war": 1, "colonization": 1}
var original: Dictionary = Civ.coefficients(world, rules, id, modifiers).duplicate(true)
modifiers.progress = 2
var changed: Dictionary = Civ.coefficients(world, rules, id, modifiers)
var row: Dictionary = rules[id].ethics.m
var p: Variant = E.maximum(0, E.multiply(E.of(row.progress), 2))
var d: Variant = E.maximum(0, E.of(row.degradation))
check(E.eq(changed.m.pro, E.divide(p, E.maximum(1, E.add(p, d)))), "Coefficient cache follows modifiers")
modifiers.progress = 1
check(E.eq(Civ.coefficients(world, rules, id, modifiers), original), "Coefficient cache restores original rates")
var local_rules: Dictionary = rules.duplicate(true)
local_rules[id].ethics.m.progress = "0.375"
changed = Civ.coefficients(world, local_rules, id, modifiers)
check(E.eq(changed.m.pro, E.divide(E.of("0.375"), E.maximum(1, E.add(E.of("0.375"), d)))), "Coefficient cache follows rule edits")
var target: Dictionary = {"ethics": {}}
Civ.State.reconcile(world, target, rules, {id: 60})
target.ethics[id].m = 100
Civ.State.reconcile(world, target, rules, {id: 60})
check(E.eq(Civ.total(target.ethics[id]), 60), "Reconcile cache detects changed ethics")
Civ.State.reconcile(world, target, rules, {id: 120})
check(E.eq(Civ.total(target.ethics[id]), 120), "Reconcile cache detects changed population")
Civ.worship(world, target, rules)
target.ethics[id].m = E.add(target.ethics[id].m, 5)
var expected: Variant = 0
for stage in rules:
if rules[stage].worships:
for ethic in target.ethics[stage]:
expected = E.add(expected, E.multiply(target.ethics[stage][ethic], E.of(rules[stage].ethics[ethic].worship)))
check(E.eq(Civ.worship(world, target, rules), expected), "Worship cache detects changed ethics")
var worship_rules: Dictionary = rules.duplicate(true)
for stage in worship_rules:
if worship_rules[stage].worships:
worship_rules[stage].ethics.m.worship = "0.375"
expected = 0
for stage in worship_rules:
if worship_rules[stage].worships:
for ethic in target.ethics[stage]:
expected = E.add(expected, E.multiply(target.ethics[stage][ethic], E.of(worship_rules[stage].ethics[ethic].worship)))
check(E.eq(Civ.worship(world, target, worship_rules), expected), "Worship cache detects changed rules")
world.ledger = load("res://tests/fixtures/audit_rounding_ledger.gd").new(world)
world.speed = speed
for i in 3: world.evolute(1.0 if speed == 1 else 0.1)
check(world.ledger.checks > 0 and world.ledger.failures == 0, "Selective and full rounding agree at speed %d" % speed)
for entity in world.catalog.entities.values(): entity.free()
world.free()
print("Simulation optimizations: %d checks, %d failures" % [checks, failures])
quit(1 if failures else 0)
@@ -0,0 +1 @@
uid://bcvertbh5uxys
+66
View File
@@ -0,0 +1,66 @@
extends SceneTree
const E = preload("res://world/owniverse/math/exact.gd")
const Q = preload("res://world/owniverse/quantity_math.gd")
var checks: int = 0
var failures: int = 0
func _initialize(): call_deferred("run")
func check(value: bool, message: String):
checks += 1
if not value:
failures += 1
push_error(message)
static func reference_split(remainders: Dictionary, key: String, count: Variant, weights: Dictionary) -> Dictionary:
var result: Dictionary = {}
var sum_weights: Variant = Q.sum(weights)
if (E.le(count, 0) or E.le(sum_weights, 0)): return result
var ids: Array = weights.keys()
var expected: Array = []
var remainder_keys: Array = []
var positive_sum: Variant = 0
for id in ids:
var remainder_key: String = key + ":" + str(id)
remainder_keys.append(remainder_key)
var value: Variant = E.add(E.mul_div(count, weights[id], sum_weights), remainders.get(remainder_key, 0))
expected.append(value)
positive_sum = E.add(positive_sum, E.maximum(0, value))
var order: Array = []
var rests: Array = []
var assigned: Variant = 0
for i in ids.size():
var normalized: Variant = E.mul_div(E.maximum(0, expected[i]), count, positive_sum) if E.gt(positive_sum, 0) else 0
result[ids[i]] = E.floor_value(normalized)
assigned = E.add(assigned, result[ids[i]])
rests.append(E.subtract(normalized, result[ids[i]]))
order.append(i)
order.sort_custom(func(a: int, b: int) -> bool: return E.gt(rests[a], rests[b]) if E.ne(rests[a], rests[b]) else str(ids[a]) < str(ids[b]))
for i in order:
if E.ge(assigned, count): break
result[ids[i]] = E.add(result[ids[i]], 1)
assigned = E.add(assigned, 1)
for i in ids.size():
remainders[remainder_keys[i]] = E.clamp_value(E.subtract(expected[i], result[ids[i]]), E.neg(1), 1)
return result
func run():
for count in [0, 1, 7, E.of("1.375"), 1000000, E.of("1e40"), E.of("1e80")]:
for weights in [{}, {"a": 0, "b": 0}, {"a": 0, "b": 7}, {"b": 0, "a": 7}, {"a": 1, "b": 1, "c": 1}, {"a": E.of("0.017"), "b": E.of("0.333333333333"), "c": 0}, {"a": E.of("1e40"), "b": 17, "c": 1}]:
for carry in [0, E.of("0.25"), E.of("-0.75")]:
var actual: Dictionary = {"case:a": carry}
var expected: Dictionary = actual.duplicate(true)
for iteration in 5:
var reference: Dictionary = reference_split(expected, "case", count, weights)
var result: Dictionary = Q.split(actual, "case", count, weights)
check(E.eq(result, reference), "Split preserves allocation")
check(E.eq(actual, expected), "Split preserves rounding carries")
for a in [0, 7, E.of("1e40"), E.of("-1e40"), E.of("1.375")]:
var values: Array = [0, 1, -7, E.of("0.017"), E.of("1e30")]
for divisor in [1, 3, E.of("0.017"), E.of("1e40")]:
var results: Array = E.mul_div_many(a, values, divisor)
for i in values.size(): check(E.eq(results[i], E.mul_div(a, values[i], divisor)), "Grouped ratios preserve scalar results")
for count in [1, 7, 1000000000, E.of("1e40"), E.of("1e80")]:
for factor in [200, 1000]:
var weights: Array = [0, 17, E.of("1e40"), E.multiply(count, factor)]
var results: Array = E.population_quotas(count, weights, factor)
for i in weights.size(): check(E.eq(results[i], E.mul_div(count, weights[i], E.multiply(count, factor))), "Cancelled population preserves exact scalar quotas")
print("Split optimizations: %d checks, %d failures" % [checks, failures])
quit(1 if failures else 0)
+1
View File
@@ -0,0 +1 @@
uid://b4e1nd22q1705
+14
View File
@@ -0,0 +1,14 @@
extends SceneTree
const E = preload("res://world/owniverse/math/exact.gd")
func _initialize():
# SceneTree initialization runs before Global._ready, like main scene construction.
var global = root.get_node("Global")
assert(not global.is_node_ready(), "Test must cover pre-ready initialization")
assert(global.ExtraParams.has("E"), "Energy table exists before Global._ready")
var scene = load("res://world/world.tscn").instantiate()
var stage = scene.get_node("Stage")
assert(E.eq(stage.owniverse.state.energy, global.ExtraParams.E), "Stage starts with configured energy")
stage.owniverse.free()
scene.free()
print("Startup params: 3 checks, 0 failures")
quit()
+1
View File
@@ -0,0 +1 @@
uid://5cbgaqn5s1yw
+22
View File
@@ -65,6 +65,28 @@ func run() -> void:
check(stage.effects_player.stream == stage.effects_player._effects.window_open, "Opening a window plays its effect")
stage._on_topmenu_button_pressed("World")
check(stage.effects_player.stream == stage.effects_player._effects.window_close, "Closing a window plays its effect")
stage.indicator_elapsed = 1.0
stage.active_actions_elapsed = 1.0
stage.tick_ui(0.0)
var refreshes: int = stage.actions_refreshes
stage.date_time.text = "unchanged"
stage.active_actions_elapsed = 1.0
stage.tick_ui(0.0)
check(stage.actions_refreshes == refreshes, "Idle UI does not recalculate production limits")
check(stage.date_time.text == "unchanged", "Idle UI does not reformat the clock")
stage.owniverse.state.amount.H = 3456
stage.owniverse.presentation.refresh(stage.owniverse.state, stage.owniverse.catalog)
stage.tick_ui(0.0)
check(hydrogen.description.text == "3 456", "A manual publication updates idle UI")
check(stage.actions_refreshes == refreshes + 1, "A publication invalidates production limits")
stage.active_actions_dirty = true
stage.tick_ui(0.0)
check(stage.actions_refreshes == refreshes + 2, "Selection invalidation refreshes limits immediately")
var old_pointer: float = stage.world_indicators.pointers.Agg.position.x
stage.owniverse.environment.modify_world_parameter("Agg", 1)
stage.indicator_elapsed = 1.0
stage.tick_ui(0.0)
check(stage.world_indicators.pointers.Agg.position.x != old_pointer, "World parameter actions invalidate indicators")
for entity in stage.owniverse.catalog.entities.values(): entity.free()
stage.owniverse.free()
scene.free()
+14
View File
@@ -7,6 +7,8 @@ const SILENT_VOLUME_DB := -80.0
@onready var music_button: TextureButton = $Media/Music
@onready var sound_volume: HSlider = $Volume/SoundVolume
@onready var music_volume: HSlider = $Volume/MusicVolume
@onready var english_button: TextureButton = $Language/English
@onready var russian_button: TextureButton = $Language/Russian
@onready var effects_player: OwniverseEffectsPlayer = $"../../FXPlayer"
@onready var music_player: OwniverseMusicPlayer = $"../../MusicPlayer"
@@ -17,6 +19,7 @@ func _ready() -> void:
music_button.set_pressed_no_signal(bool(Global.Settings.music_enabled))
sound_volume.set_value_no_signal(float(Global.Settings.sound_volume) * sound_volume.max_value)
music_volume.set_value_no_signal(float(Global.Settings.music_volume) * music_volume.max_value)
_update_locale_buttons()
_apply_sound_settings()
_apply_music_settings()
@@ -65,3 +68,14 @@ func _apply_bus_volume(bus_name: String, value: float) -> void:
var normalized: float = clampf(value, 0.0, 1.0)
var volume_db: float = SILENT_VOLUME_DB if is_zero_approx(normalized) else lerpf(MIN_VOLUME_DB, 0.0, normalized)
AudioServer.set_bus_volume_db(bus_index, volume_db)
func _on_change_locale_pressed(locale: String) -> void:
Global.set_locale(locale)
_update_locale_buttons()
SaveManager.save_settings()
func _update_locale_buttons() -> void:
english_button.set_pressed_no_signal(Global.Locale == "en")
russian_button.set_pressed_no_signal(Global.Locale == "ru")
+2 -10
View File
@@ -203,20 +203,12 @@ func auto_capacity(source: Dictionary, entity: OwniverseEntity, budget: Dictiona
return (E.multiply(E.floor_value(E.divide(capacity, step)), step) if (E.finite(capacity) and E.finite(step)) else 0)
func produce_newborn_lifetime(target: Dictionary, id: String, count: Variant, born_from: Variant, born_to: Variant, to_year: Variant, before_batches: Array, remaining_object_years: Variant = NAN) -> void:
func produce_newborn_lifetime(target: Dictionary, id: String, count: Variant, born_from: Variant, born_to: Variant, to_year: Variant, newborn_past_years: Variant = 0, remaining_object_years: Variant = NAN) -> void:
var products: Dictionary = yearly_products(world.catalog.entities[id])
if (products.is_empty() or E.le(count, 0)):
return
var object_years: Variant = (remaining_object_years if E.finite(remaining_object_years) else E.multiply(count, E.maximum(0, E.subtract(to_year, E.multiply((E.add(born_from, born_to)), E.of("0.5"))))))
var previous_amounts: Dictionary = {}
for old : Dictionary in before_batches:
var start: Variant = old.get("created_from", E.neg(INF))
if (not previous_amounts.has(str(start))):
previous_amounts[str(start)] = old.amount
for batch : Dictionary in target.batches.get(id, []):
var added: Variant = E.subtract(batch.amount, previous_amounts.get(str(batch.get("created_from", INF)), 0))
object_years = E.subtract(object_years, E.multiply(E.maximum(0, added), world.batches.expired_years(to_year, batch.start_year, batch.end_year)))
object_years = E.maximum(0, object_years)
object_years = E.maximum(0, E.subtract(object_years, newborn_past_years))
for resource in products:
var coefficient: Variant = E.multiply(products[resource], WorldParameters.production(target, world.catalog.entities[id]))
var output: Variant = E.multiply(object_years, coefficient)
+234 -60
View File
@@ -7,6 +7,8 @@ const State = preload("res://world/owniverse/civilization_state.gd")
const WorldParameters = preload("res://world/owniverse/world_parameters.gd")
const ETHICS = State.ETHICS
const OPPOSITE = {"m": "l", "l": "m", "w": "d", "d": "w", "c": "b", "b": "c"}
const DIPLOMACY_SCALE: int = 1000000000
static var _diplomacy_rates: Dictionary = {}
static func total(pop: Dictionary) -> Variant:
return QuantityMath.sum(pop)
@@ -14,8 +16,8 @@ static func total(pop: Dictionary) -> Variant:
static func add(to: Dictionary, from: Dictionary) -> void:
for key in from: to[key] = E.add(to.get(key, 0), from[key])
static func take(world, pop: Dictionary, count: Variant) -> Dictionary:
var taken: Dictionary = QuantityMath.allocate_whole(pop, count)
static func take(world, pop: Dictionary, count: Variant, population_total: Variant = null) -> Dictionary:
var taken: Dictionary = QuantityMath.allocate_whole_with_total(pop, count, population_total) if population_total != null else QuantityMath.allocate_whole(pop, count)
for key in taken: pop[key] = E.subtract(pop[key], taken[key])
return taken
@@ -30,18 +32,124 @@ static func split(target: Dictionary, key: String, count: Variant, weights: Dict
if (not target.has("civilization_remainders")): target.civilization_remainders = {}
return QuantityMath.split(target.civilization_remainders, key, count, weights)
static func drift(target: Dictionary, key: String, pop: Dictionary, rows: Dictionary, diplomacy: bool = false, colony: bool = false) -> Dictionary:
static func drift(target: Dictionary, key: String, pop: Dictionary, rows: Dictionary, diplomacy: bool = false, colony: bool = false, population: Variant = null) -> Dictionary:
if population == null: population = total(pop)
if E.le(population, 0): return pop.duplicate()
if not diplomacy and E.eq(population, E.floor_value(population)):
return direct_drift(target, key, pop, colony, population)
var weights: Array = []
if not diplomacy:
# Integer populations: exact algebraic reduction of the 6 x 6 matrix.
var common: Variant = E.multiply(population, 9) if colony else population
for ethic in ETHICS:
weights.append(E.subtract(E.add(common, E.multiply(pop.get(ethic, 0), 951 if colony else 195)), E.multiply(pop.get(OPPOSITE[ethic], 0), 5 if colony else 1)))
else:
# Algebraic reduction of the diplomatic 6 x 6 matrix.
var rates: Array = diplomacy_rates(rows)
var contributions: Array = [0, 0, 0, 0, 0, 0]
var combined: Variant = 0
for ethic in pop:
var index: int = ETHICS.find(ethic)
var contribution: Variant = E.multiply(pop[ethic], rates[index])
contributions[index] = contribution
combined = E.add(combined, contribution)
var common: Variant = E.multiply(combined, 9) if colony else combined
for ethic in ETHICS:
weights.append(E.maximum(0, E.subtract(E.add(common, E.multiply(contributions[ETHICS.find(ethic)], 951 if colony else 195)), E.multiply(contributions[ETHICS.find(OPPOSITE[ethic])], 5 if colony else 1))))
if E.le(QuantityMath.sum_array(weights), 0): return pop.duplicate()
if not target.has("civilization_remainders"): target.civilization_remainders = {}
return QuantityMath.split_arrays(target.civilization_remainders, key, population, ETHICS, weights, 0)
static func diplomacy_rates(rows: Dictionary) -> Array:
var signature: String = ""
for ethic in ETHICS: signature += str(rows[ethic].diplomacy_rate) + ";"
if _diplomacy_rates.has(signature): return _diplomacy_rates[signature]
var rates: Array = []
for ethic in ETHICS:
var exact_rate: Variant = E.of(rows[ethic].diplomacy_rate)
rates.append(E.integer(E.round_value(E.multiply(exact_rate, DIPLOMACY_SCALE))))
if _diplomacy_rates.size() >= 256: _diplomacy_rates.clear()
rates.make_read_only()
_diplomacy_rates[signature] = rates
return rates
static func direct_drift(target: Dictionary, key: String, pop: Dictionary, colony: bool, population: Variant) -> Dictionary:
if not target.has("civilization_remainders"): target.civilization_remainders = {}
var carries: Dictionary = target.civilization_remainders
var result: Dictionary = {}
for ethic in ETHICS: result[ethic] = 0
for ethic in ETHICS:
if E.ne(pop.get(ethic, 0), E.floor_value(pop.get(ethic, 0))): return fractional_direct_fallback(target, key, pop, colony, population)
var divisor: int = 25 if colony else 50
for source in ETHICS:
var count: Variant = pop.get(source, 0)
if E.le(count, 0): continue
var whole: Variant = E.floor_value(E.divide(count, divisor))
var count_remainder: int = E.integer(E.subtract(count, E.multiply(whole, divisor)))
var remainder_key: String = key + ":flow:" + source
var pending: int = count_remainder + int(carries.get(remainder_key, 0))
var outgoing: Variant = E.add(whole, pending / divisor)
carries[remainder_key] = pending % divisor
result[source] = E.add(result[source], E.subtract(count, outgoing))
if E.le(outgoing, 0): continue
if not colony:
var neighbor_base: Variant = E.floor_value(E.divide(outgoing, 4))
var extras: int = E.integer(E.subtract(outgoing, E.multiply(neighbor_base, 4)))
var neighbors: Array = []
for destination in ETHICS:
if destination != source and destination != OPPOSITE[source]: neighbors.append(destination)
var cursor_key: String = key + ":flow_cursor:" + source
var cursor: int = int(carries.get(cursor_key, 0))
for neighbor_index in 4:
var destination: String = neighbors[neighbor_index]
var add: Variant = E.add(neighbor_base, 1 if ((neighbor_index - cursor + 4) % 4) < extras else 0)
result[destination] = E.add(result[destination], add)
carries[cursor_key] = (cursor + extras) % 4
else:
distribute_colonial_flow(result, carries, key, source, outgoing)
assert(E.eq(total(result), population), "Direct ethic drift must conserve population")
return result
static func distribute_colonial_flow(result: Dictionary, carries: Dictionary, key: String, source: String, outgoing: Variant) -> void:
# Colonial flow is 9:9:9:9:4 among the other ethics (total weight 40).
var base: Variant = E.floor_value(E.divide(outgoing, 40))
var tail: int = E.integer(E.subtract(outgoing, E.multiply(base, 40)))
var destinations: Array = []
var weights: Array = []
for destination in ETHICS:
if destination == source: continue
destinations.append(destination)
weights.append(4 if destination == OPPOSITE[source] else 9)
var assigned: Variant = 0
var rests: Array = []
var quotas: Array = []
for i in destinations.size():
var carry_key: String = key + ":col_flow:" + source + ":" + destinations[i]
var numerator: int = tail * weights[i] + int(carries.get(carry_key, 0))
var extra: int = floori(float(numerator) / 40.0)
var rest: int = numerator - extra * 40
quotas.append(E.add(E.multiply(base, weights[i]), extra))
rests.append(rest)
assigned = E.add(assigned, quotas[i])
carries[carry_key] = rest
var missing: int = E.integer(E.subtract(outgoing, assigned))
var order: Array = [0, 1, 2, 3, 4]
order.sort_custom(func(a: int, b: int) -> bool: return rests[a] > rests[b] if rests[a] != rests[b] else destinations[a] < destinations[b])
for i in order:
if missing <= 0: break
quotas[i] = E.add(quotas[i], 1)
var carry_key: String = key + ":col_flow:" + source + ":" + destinations[i]
carries[carry_key] = int(carries[carry_key]) - 40
missing -= 1
for i in destinations.size(): result[destinations[i]] = E.add(result[destinations[i]], quotas[i])
static func fractional_direct_fallback(target: Dictionary, key: String, pop: Dictionary, colony: bool, population: Variant) -> Dictionary:
var weights: Dictionary = {}
for ethic in pop:
var influence: Variant = (E.of(rows[ethic].diplomacy_rate) if diplomacy else 1)
var contribution: Variant = E.multiply(pop[ethic], influence)
for other in ETHICS:
var weight: Variant = (9 if colony else 1)
if E.eq(other, ethic): weight = (960 if colony else 196)
elif E.eq(other, OPPOSITE[ethic]): weight = (4 if colony else 0)
weights[other] = E.add(weights.get(other, 0), E.multiply(contribution, weight))
if E.le(total(weights), 0): return pop.duplicate()
return split(target, key, total(pop), weights)
for ethic in ETHICS:
var common: Variant = E.multiply(population, 9) if colony else population
weights[ethic] = E.subtract(E.add(common, E.multiply(pop.get(ethic, 0), 951 if colony else 195)), E.multiply(pop.get(OPPOSITE[ethic], 0), 5 if colony else 1))
if not target.has("civilization_remainders"): target.civilization_remainders = {}
return QuantityMath.split(target.civilization_remainders, key, population, weights)
static func emit(plan: Dictionary, destination: String, pop: Dictionary) -> void:
if (not plan.outputs.has(destination)): plan.outputs[destination] = {}
@@ -50,37 +158,85 @@ static func emit(plan: Dictionary, destination: String, pop: Dictionary) -> void
static func fall(target: Dictionary, plan: Dictionary, rules: Dictionary, pop: Dictionary) -> void:
for ethic in pop:
if E.le(pop[ethic], 0): continue
var weights: Dictionary = {}
for term in str(rules[plan.id].ethics[ethic].fall).split("^", false):
var pair: PackedStringArray = term.split(":")
weights[pair[0]] = E.of(pair[1])
if weights.is_empty(): weights[rules[plan.id].previous] = 1
var weights: Dictionary = QuantityMath.rule_weights(str(rules[plan.id].ethics[ethic].fall))
if weights.is_empty(): weights = {rules[plan.id].previous: 1}
var shares: Dictionary = split(target, E.add(E.add(E.add("fall:", plan.id), ":"), ethic), pop[ethic], weights)
for stage in shares: emit(plan, stage, {ethic: shares[stage]})
static func progress(world, target: Dictionary, rules: Dictionary, budget: Dictionary, plan: Dictionary, pop: Dictionary) -> Dictionary:
static func progress(world, target: Dictionary, rules: Dictionary, budget: Dictionary, plan: Dictionary, pop: Dictionary, population_total: Variant = null) -> Dictionary:
var successor: String = rules[plan.id].next
var admitted: Variant = State.admit_transition(budget, rules, plan.id, successor, total(pop))
var accepted: Dictionary = take(world, pop, admitted)
if population_total == null: population_total = total(pop)
var admitted: Variant = State.admit_transition(budget, rules, plan.id, successor, population_total)
var accepted: Dictionary = take(world, pop, admitted, population_total)
emit(plan, successor, accepted)
return pop
static func new_plan(id: String, year: Variant) -> Dictionary:
return {"id": id, "from": year, "to": E.neg(INF), "amount": 0, "outputs": {}}
static func consume_untriggered(world, target: Dictionary, plan: Dictionary, pop: Dictionary, count: Variant, year: Variant) -> Dictionary:
var old_total: Variant = total(pop)
var removed: Dictionary = take(world, pop, count)
var actual: Variant = total(removed)
static func consume_untriggered(world, target: Dictionary, plan: Dictionary, pop: Dictionary, count: Variant, year: Variant, population_total: Variant = null) -> Dictionary:
var old_total: Variant = total(pop) if population_total == null else population_total
var actual: Variant = E.floor_value(E.minimum(E.maximum(0, count), old_total))
var removed: Dictionary = take(world, pop, actual, old_total)
if E.gt(actual, 0):
world.batches.scale_batches(target, plan.id, E.divide((E.subtract(old_total, actual)), old_total))
plan.amount = E.add(plan.amount, actual)
plan.to = E.maximum(plan.to, year)
return removed
static func prepare(world, target: Dictionary, expired: Dictionary, year: Variant, budget: Dictionary, rules: Dictionary, physical: Dictionary = {}, budget_timer: RefCounted = null) -> Dictionary:
# Cache products per ethic, then sum them in the original stage/ethic order.
# Keeping the summation order preserves float fractional rounding exactly.
static func worship(world, target: Dictionary, rules: Dictionary) -> Variant:
var result: Variant = 0
for id in rules:
if not rules[id].worships: continue
var pop: Dictionary = target.ethics[id]
var coefficients: Dictionary = {}
for ethic in pop: coefficients[ethic] = rules[id].ethics[ethic].worship
var cached: Dictionary = world.ledger.worship_products.get(id, {})
if cached.is_empty() or not E.eq(cached.population, pop) or not E.eq(cached.coefficients, coefficients):
var products: Dictionary = {}
for ethic in pop: products[ethic] = E.multiply(pop[ethic], E.of(coefficients[ethic]))
cached = {"population": pop.duplicate(), "coefficients": coefficients, "products": products}
world.ledger.worship_products[id] = cached
for ethic in pop: result = E.add(result, cached.products[ethic])
return result
static func coefficients(world, rules: Dictionary, id: String, modifiers: Dictionary) -> Dictionary:
if not E.eq(world.ledger.civilization_modifiers, modifiers):
world.ledger.civilization_modifiers = modifiers.duplicate()
world.ledger.civilization_coefficients.clear()
var cached: Dictionary = world.ledger.civilization_coefficients.get(id, {})
var signature: String = ""
for ethic in ETHICS:
var row: Dictionary = rules[id].ethics[ethic]
signature += ethic + ":" + str(row.progress) + "," + str(row.degradation) + "," + str(row.war) + "," + str(row.colonization) + ";"
if not cached.is_empty() and cached.signature == signature: return cached.rates
var rates: Dictionary = {}
for ethic in rules[id].ethics:
var row: Dictionary = rules[id].ethics[ethic]
var p: Variant = E.maximum(0, E.multiply(E.of(row.progress), modifiers.progress))
var d: Variant = E.maximum(0, E.multiply(E.of(row.degradation), modifiers.degradation))
var scale: Variant = E.maximum(1, E.add(p, d))
rates[ethic] = {"pro": E.divide(p, scale), "deg": E.divide(d, scale),
"war": E.minimum(1, E.multiply(E.of(row.war), modifiers.war)),
"col": E.minimum(1, E.multiply(E.of(row.colonization), modifiers.colonization))}
world.ledger.civilization_coefficients[id] = {"signature": signature, "rates": rates}
return rates
static func prepare(world, target: Dictionary, expired: Dictionary, year: Variant, budget: Dictionary, rules: Dictionary, physical: Dictionary = {}, budget_timer: RefCounted = null, expired_totals: Dictionary = {}) -> Dictionary:
var profile_started: int = world.profile_start()
State.reconcile(world, target, rules, physical)
var ids: Array = []
for id in expired:
if rules.has(id) and not expired[id].is_empty(): ids.append(id)
if ids.is_empty():
world.profile_end("civilization_prepare", profile_started)
return {"active": false}
var reconcile_ids: Array = []
for id in ids:
reconcile_ids.append(id)
if rules[id].fights and not reconcile_ids.has(rules[id].previous): reconcile_ids.append(rules[id].previous)
State.reconcile(world, target, rules, physical, reconcile_ids)
var remaining: Dictionary = target.ethics.duplicate()
var copied: Dictionary = {}
var plans: Dictionary = {}
@@ -89,15 +245,15 @@ static func prepare(world, target: Dictionary, expired: Dictionary, year: Varian
var modifiers: Dictionary = WorldParameters.life_modifiers(target)
var order: Variant = WorldParameters.value(target, "Order")
if (not target.has("civilization_stats")): target.civilization_stats = {}
var ids: Array = expired.keys()
ids.sort()
for id in ids:
if budget_timer != null and not await budget_timer.pause(): return {}
if ((not rules.has(id)) or expired[id].is_empty()): continue
var plan: Dictionary = new_plan(id, year)
plans[id] = plan
plan.amount = expired_totals.get(id, 0)
for part : Dictionary in expired[id]:
plan.amount = E.add(plan.amount, part.amount)
if not expired_totals.has(id): plan.amount = E.add(plan.amount, part.amount)
plan.from = E.minimum(plan.from, part.from)
plan.to = E.maximum(plan.to, part.to)
remaining[id] = remaining[id].duplicate()
@@ -107,16 +263,15 @@ static func prepare(world, target: Dictionary, expired: Dictionary, year: Varian
var failures: Dictionary = {}
var warriors: Dictionary = {}
var settlers: Dictionary = {}
var stage_rates: Dictionary = coefficients(world, rules, id, modifiers)
for ethic in triggered:
var row: Dictionary = rules[id].ethics[ethic]
var p: Variant = E.maximum(0, E.multiply(E.of(row.progress), modifiers.progress))
var d: Variant = E.maximum(0, E.multiply(E.of(row.degradation), modifiers.degradation))
var scale: Variant = E.maximum(1, E.add(p, d))
var pro: Variant = rate(target, E.add(E.add(E.add(id, ":"), ethic), ":pro"), triggered[ethic], E.divide(p, scale))
var deg: Variant = rate(target, E.add(E.add(E.add(id, ":"), ethic), ":deg"), triggered[ethic], E.divide(d, scale))
var probability: Dictionary = stage_rates[ethic]
var prefix: String = id + ":" + ethic
var pro: Variant = rate(target, prefix + ":pro", triggered[ethic], probability.pro)
var deg: Variant = rate(target, prefix + ":deg", triggered[ethic], probability.deg)
var bounded: Dictionary = QuantityMath.allocate_whole({"pro": pro, "deg": deg}, triggered[ethic])
if rules[id].fights: warriors[ethic] = rate(target, E.add(E.add(E.add(id, ":"), ethic), ":war"), triggered[ethic], E.minimum(1, E.multiply(E.of(row.war), modifiers.war)))
if rules[id].colonizes: settlers[ethic] = rate(target, E.add(E.add(E.add(id, ":"), ethic), ":col"), triggered[ethic], E.minimum(1, E.multiply(E.of(row.colonization), modifiers.colonization)))
if rules[id].fights: warriors[ethic] = rate(target, prefix + ":war", triggered[ethic], probability.war)
if rules[id].colonizes: settlers[ethic] = rate(target, prefix + ":col", triggered[ethic], probability.col)
successes[ethic] = bounded.pro
failures[ethic] = bounded.deg
triggered[ethic] = E.subtract(triggered[ethic], E.add(bounded.pro, bounded.deg))
@@ -127,22 +282,36 @@ static func prepare(world, target: Dictionary, expired: Dictionary, year: Varian
if rules[id].fights:
var profile_wars: int = world.profile_start()
for ethic in warriors: warriors[ethic] = E.minimum(warriors[ethic], triggered[ethic])
var wars: Variant = E.minimum(total(warriors), E.floor_value(E.divide((E.add(total(triggered), total(remaining[id]))), 2)))
warriors = QuantityMath.allocate_whole(warriors, wars)
var warriors_total: Variant = total(warriors)
var triggered_total: Variant = total(triggered)
var remaining_total: Variant = total(remaining[id])
var wars: Variant = E.minimum(warriors_total, E.floor_value(E.divide(E.add(triggered_total, remaining_total), 2)))
warriors = QuantityMath.allocate_whole_with_total(warriors, wars, warriors_total)
for ethic in warriors: triggered[ethic] = E.subtract(triggered[ethic], warriors[ethic])
triggered_total = E.subtract(triggered_total, wars)
var outcomes: Dictionary = split(target, E.add(id, ":wars"), wars, {"deg": 1, "pro25": 2, "pro50": 3, "pro75": 3})
var win_expected: Variant = E.add(E.add(E.multiply(outcomes.get("pro25", 0), E.of("0.25")), E.multiply(outcomes.get("pro50", 0), E.of("0.5"))), E.multiply(outcomes.get("pro75", 0), E.of("0.75")))
var loss_expected: Variant = E.add(E.add(E.add(E.multiply(outcomes.get("deg", 0), 2), outcomes.get("pro25", 0)), E.multiply(outcomes.get("pro50", 0), E.of("1.5"))), E.multiply(outcomes.get("pro75", 0), 2))
var winners: Dictionary = take(world, warriors, rate(target, E.add(id, ":wins"), win_expected, 1))
var attackers_lost: Dictionary = take(world, warriors, rate(target, E.add(id, ":attackers_lost"), E.divide(outcomes.get("deg", 0), order), 1))
add(triggered, progress(world, target, rules, budget, plan, winners))
var wins_requested: Variant = rate(target, E.add(id, ":wins"), win_expected, 1)
var winners: Dictionary = take(world, warriors, wins_requested, wars)
var winner_total: Variant = E.floor_value(E.minimum(E.maximum(0, wins_requested), wars))
warriors_total = E.subtract(wars, winner_total)
var losses_requested: Variant = rate(target, E.add(id, ":attackers_lost"), E.divide(outcomes.get("deg", 0), order), 1)
var attackers_lost: Dictionary = take(world, warriors, losses_requested, warriors_total)
var attackers_lost_total: Variant = E.floor_value(E.minimum(E.maximum(0, losses_requested), warriors_total))
warriors_total = E.subtract(warriors_total, attackers_lost_total)
add(triggered, progress(world, target, rules, budget, plan, winners, winner_total))
triggered_total = total(triggered)
fall(target, plan, rules, attackers_lost)
var losses: Variant = E.minimum(rate(target, E.add(id, ":loss"), E.divide(loss_expected, order), 1), E.add(total(triggered), total(remaining[id])))
var sides: Dictionary = QuantityMath.allocate_whole({"due": total(triggered), "later": total(remaining[id])}, losses)
var victims: Dictionary = take(world, triggered, sides.due)
add(victims, consume_untriggered(world, target, plan, remaining[id], sides.later, year))
remaining_total = total(remaining[id])
var losses: Variant = E.minimum(rate(target, E.add(id, ":loss"), E.divide(loss_expected, order), 1), E.add(triggered_total, remaining_total))
var sides: Dictionary = QuantityMath.allocate_whole_with_total({"due": triggered_total, "later": remaining_total}, losses, E.add(triggered_total, remaining_total))
var victims: Dictionary = take(world, triggered, sides.due, triggered_total)
triggered_total = E.subtract(triggered_total, sides.due)
add(victims, consume_untriggered(world, target, plan, remaining[id], sides.later, year, remaining_total))
fall(target, plan, rules, victims)
add(triggered, warriors)
triggered_total = E.add(triggered_total, warriors_total)
var damage: Variant = rate(target, E.add(id, ":collateral"), E.divide((E.add(E.multiply(outcomes.get("pro50", 0), 10), E.multiply(outcomes.get("pro75", 0), 30))), order), 1)
collateral[rules[id].previous] = E.add(collateral.get(rules[id].previous, 0), damage)
target.civilization_stats.wars = E.add(target.civilization_stats.get("wars", 0), wars)
@@ -158,10 +327,12 @@ static func prepare(world, target: Dictionary, expired: Dictionary, year: Varian
if (not plans.has(id)): plans[id] = new_plan(id, year)
var plan: Dictionary = plans[id]
var retry: Dictionary = plan.outputs.get(id, {})
var amount: Variant = E.minimum(collateral[id], E.add(total(retry), total(remaining[id])))
var sides: Dictionary = QuantityMath.allocate_whole({"due": total(retry), "later": total(remaining[id])}, amount)
var victims: Dictionary = take(world, retry, sides.due)
add(victims, consume_untriggered(world, target, plan, remaining[id], sides.later, year))
var retry_total: Variant = total(retry)
var remaining_total: Variant = total(remaining[id])
var amount: Variant = E.minimum(collateral[id], E.add(retry_total, remaining_total))
var sides: Dictionary = QuantityMath.allocate_whole_with_total({"due": retry_total, "later": remaining_total}, amount, E.add(retry_total, remaining_total))
var victims: Dictionary = take(world, retry, sides.due, retry_total)
add(victims, consume_untriggered(world, target, plan, remaining[id], sides.later, year, remaining_total))
fall(target, plan, rules, victims)
target.civilization_stats.collateral = E.add(target.civilization_stats.get("collateral", 0), total(victims))
var incoming: Dictionary = {}
@@ -172,22 +343,29 @@ static func prepare(world, target: Dictionary, expired: Dictionary, year: Varian
var products: Dictionary = {}
for destination in plan.outputs:
var pop: Dictionary = plan.outputs[destination]
var count: Variant = total(pop)
if rules.has(destination):
if E.ne(destination, "Ct"):
if E.ne(destination, "Ct") and E.gt(count, 0):
var profile_drift: int = world.profile_start()
pop = drift(target, E.add(E.add(E.add(id, ":"), destination), ":drift"), pop, rules[id].ethics, (E.eq(destination, id) and rules[id].diplomacy))
pop = drift(target, E.add(E.add(E.add(id, ":"), destination), ":drift"), pop, rules[id].ethics, (E.eq(destination, id) and rules[id].diplomacy), false, count)
world.profile_end("ethics_drift", profile_drift)
if (not incoming.has(destination)): incoming[destination] = {}
add(incoming[destination], pop)
products[destination] = total(pop)
products[destination] = count
if (State.is_space_civilization(id, rules) and E.eq(world.catalog.entities[destination].group_as, "Planet")):
planetary[destination] = E.add(planetary.get(destination, 0), total(pop))
planetary[destination] = E.add(planetary.get(destination, 0), count)
expired[id] = [{"amount": plan.amount, "from": plan.from, "to": E.maximum(plan.from, plan.to), "products": products}]
world.profile_end("civilization_prepare", profile_started)
return {"remaining": remaining, "incoming": incoming, "planetary": planetary, "colonies": colonies}
return {"active": true, "remaining": remaining, "incoming": incoming, "planetary": planetary, "colonies": colonies}
static func finish(world, target: Dictionary, transaction: Dictionary, year: Variant, rules: Dictionary, budget_timer: RefCounted = null) -> void:
var profile_started: int = world.profile_start()
if not transaction.get("active", true):
State.reconcile(world, target, rules)
if not target.has("civilization_stats"): target.civilization_stats = {}
target.civilization_stats.worship = worship(world, target, rules)
world.profile_end("civilization_finish", profile_started)
return
target.ethics = transaction.remaining
for id in transaction.incoming:
if (not target.ethics.has(id)): target.ethics[id] = {}
@@ -209,11 +387,7 @@ static func finish(world, target: Dictionary, transaction: Dictionary, year: Var
else:
colonize(world, target, transaction.colonies, year, rules, physical)
State.reconcile(world, target, rules, physical if transaction.colonies.is_empty() else {})
var worship: Variant = 0
for id in rules:
if (not rules[id].worships): continue
for ethic in target.ethics[id]: worship = E.add(worship, E.multiply(target.ethics[id][ethic], E.of(rules[id].ethics[ethic].worship)))
target.civilization_stats.worship = worship
target.civilization_stats.worship = worship(world, target, rules)
world.profile_end("civilization_finish", profile_started)
static func colonize(world, target: Dictionary, colonies: Array, year: Variant, rules: Dictionary, physical: Dictionary = {}, budget_timer: RefCounted = null) -> void:
+8 -2
View File
@@ -10,14 +10,19 @@ static func is_space_civilization(id: String, rules: Dictionary) -> bool:
# Preserve any existing ethics. New populations start equally distributed;
# reductions (including blasts) are proportional and never leave negative counts.
static func reconcile(world, target: Dictionary, rules: Dictionary, physical: Dictionary = {}) -> void:
static func reconcile(world, target: Dictionary, rules: Dictionary, physical: Dictionary = {}, only_ids: Array = []) -> void:
if (not target.has("ethics")):
target.ethics = {}
if physical.is_empty():
physical = world.ledger.physical_amounts(target)
for id in rules:
var ids: Variant = rules if only_ids.is_empty() else only_ids
for id in ids:
if not rules.has(id): continue
var count: Variant = physical.get(id, 0)
var current: Dictionary = target.ethics.get(id, {})
var cached: Dictionary = world.ledger.reconciled_ethics.get(id, {})
if not cached.is_empty() and E.eq(cached.count, count) and E.eq(cached.population, current):
continue
var total: Variant = 0
for ethic in ETHICS:
current[ethic] = E.maximum(0, current.get(ethic, 0))
@@ -31,6 +36,7 @@ static func reconcile(world, target: Dictionary, rules: Dictionary, physical: Di
for i in ETHICS.size():
current[ETHICS[i]] = E.add(current[ETHICS[i]], E.add(base, ((1 if E.lt(i, rest) else 0))))
target.ethics[id] = current
world.ledger.reconciled_ethics[id] = {"count": count, "population": current.duplicate()}
static func detach_space_civilizations(target: Dictionary, rules: Dictionary) -> void:
for held : Dictionary in target.binds.values():
+67 -26
View File
@@ -38,6 +38,7 @@ func evolute_to_datetime(datetime: Variant, clock: Dictionary = {}, budget: RefC
next.version = SimulationTime.STATE_VERSION
next.speed = clampi(E.integer(previous.speed), 1, Global.SPEED_LIMIT)
next.speed_in_year = E.power(10, E.subtract(next.speed, 1))
world.batches.coarsen(next)
var from_year: Variant = previous.time.year
var to_year: Variant = processed_year
if E.gt(to_year, from_year):
@@ -72,38 +73,48 @@ func evolve_batches(target: Dictionary, to_year: Variant, budget: RefCounted = n
var _keep_alive: RefCounted = self
# A long cycle may contain several generations; preserve actual birth intervals.
var completed: Dictionary = {}
while await evolve_batch_generation(target, to_year, completed, budget):
var context: Dictionary = {
"life_modifiers": WorldParameters.life_modifiers(target),
"enlightenment": WorldParameters.value(target, "Enlightenment"),
"explosiveness": WorldParameters.effective(target, "Exp")
}
while await evolve_batch_generation(target, to_year, completed, budget, context):
if budget != null and not await budget.pause(): return
func evolve_batch_generation(target: Dictionary, to_year: Variant, completed: Dictionary = { }, budget: RefCounted = null) -> bool:
func evolve_batch_generation(target: Dictionary, to_year: Variant, completed: Dictionary = { }, budget: RefCounted = null, context: Dictionary = {}) -> bool:
var _keep_alive: RefCounted = self
# Apply direct completions at the original next-generation boundary, so
# binding transfers, the blast environment and capacity checks keep order.
if budget != null and not await budget.pause(): return false
var completed_now: Dictionary = completed.duplicate(true)
var completed_now: Dictionary = completed.duplicate()
completed.clear()
if context.is_empty():
context = {"life_modifiers": WorldParameters.life_modifiers(target), "enlightenment": WorldParameters.value(target, "Enlightenment"), "explosiveness": WorldParameters.effective(target, "Exp")}
var quantities: Dictionary = world.ledger.physical_amounts(target)
var expired: Dictionary = {}
var preview: Dictionary = {"batches": {}}
for id in target.batches:
if (world.catalog.entities.has(id) and E.gt(world.catalog.entities[id].destroy_level, 0)):
preview.batches[id] = target.batches[id].duplicate(true)
for id in target.batches.keys():
var withdrawn: Dictionary = {}
var batch_ids: Array = target.batches.keys()
var planets_changed: bool = false
var profile_withdraw: int = world.profile_start()
for id in batch_ids:
if ((not world.catalog.entities.has(id)) or E.le(world.catalog.entities[id].destroy_level, 0)):
continue
var dying: Variant = 0
for part : Dictionary in completed_now.get(id, []):
dying = E.add(dying, part.amount)
for part : Dictionary in world.batches.withdraw_batches(preview, id, to_year):
withdrawn[id] = world.batches.withdraw_batches(target, id, to_year)
for part : Dictionary in withdrawn[id]:
dying = E.add(dying, part.amount)
if E.gt(quantities.get(id, 0), 0):
world.stellar.destroy_planets(target, id, E.divide(dying, quantities[id]), world.catalog.entities[id].destroy_level)
quantities = world.ledger.physical_amounts(target)
planets_changed = world.stellar.destroy_planets(target, id, E.divide(dying, quantities[id]), world.catalog.entities[id].destroy_level) or planets_changed
world.profile_end("generation_withdrawal", profile_withdraw)
if planets_changed: quantities = world.ledger.physical_amounts(target)
# Withdraw all types before creating successors: iteration order cannot affect them.
for id in target.batches.keys():
for id in batch_ids:
if world.catalog.entities.has(id):
expired[id] = E.add(completed_now.get(id, []), world.batches.withdraw_batches(target, id, to_year))
var parts: Array = withdrawn[id] if withdrawn.has(id) else world.batches.withdraw_batches(target, id, to_year)
expired[id] = E.add(completed_now.get(id, []), parts)
var has_expired: bool = false
for parts : Array in expired.values():
if (not parts.is_empty()):
@@ -111,22 +122,28 @@ func evolve_batch_generation(target: Dictionary, to_year: Variant, completed: Di
break
if (not has_expired):
return false
# This per-generation summary is valid until the next transition mutates
# the cohort set. Reuse it for civilization planning and transfer ratios.
var expired_totals: Dictionary = {}
for id in expired:
var total: Variant = 0
for part: Dictionary in expired[id]: total = E.add(total, part.amount)
expired_totals[id] = total
var fractions: Dictionary = {}
var outputs: Dictionary = {}
var current_quantities: Dictionary = quantities
var star_budget: Dictionary = CivilizationState.stellar_budget(world, target, Global.CivilizationRules, current_quantities)
var civilization_transaction: Dictionary = await CivilizationEvolution.prepare(world, target, expired, to_year, star_budget, Global.CivilizationRules, current_quantities, budget)
var civilization_transaction: Dictionary = await CivilizationEvolution.prepare(world, target, expired, to_year, star_budget, Global.CivilizationRules, current_quantities, budget, expired_totals)
if budget != null and budget.cancelled: return false
var profile_products: int = world.profile_start()
for id in expired:
if budget != null and not await budget.pause(): return false
var total: Variant = 0
for part : Dictionary in expired[id]:
total = E.add(total, part.amount)
var total: Variant = expired_totals[id]
fractions[id] = (E.clamp_value(E.divide(total, quantities[id]), 0, 1) if E.gt(quantities.get(id, 0), 0) else 0)
var combined: Dictionary = {}
for part : Dictionary in expired[id]:
if (not part.has("products")):
part.products = world.stellar.evolution_products(target, world.catalog.entities[id], part.amount)
part.products = world.stellar.evolution_products(target, world.catalog.entities[id], part.amount, context)
for successor in part.products.keys():
if Global.CivilizationRules.has(id):
continue
@@ -141,19 +158,32 @@ func evolve_batch_generation(target: Dictionary, to_year: Variant, completed: Di
if E.gt(total, 0):
for successor in combined:
outputs[id][successor] = E.divide(combined[successor], total)
world.profile_end("generation_products", profile_products)
var affected: Dictionary = {}
for id in fractions:
if E.le(fractions[id], 0): continue
affected[id] = true
for held in target.binds.get(id, {}): affected[held] = true
for successor in outputs[id]: affected[successor] = true
var incoming: Dictionary = world.ledger.transfer_evolution(target, fractions, outputs)
var new_owners: Dictionary = {}
var blast_power: Variant = 0
var environment: Dictionary = world.environment.stellar_environment(target)
for parts: Array in expired.values():
for part: Dictionary in parts:
blast_power = E.add(blast_power, part.products.get("blast", 0))
# A zero blast does not need density/mass/volume recalculated. For an actual
# blast retain the original snapshot before crediting newborn populations.
var environment: Dictionary = world.environment.stellar_environment(target) if E.gt(blast_power, 0) else {}
var resolution: Variant = world.batches.temporal_resolution(target)
for id in expired:
for part : Dictionary in expired[id]:
for successor in part.products:
if budget != null and not await budget.pause(): return false
var amount: Variant = part.products[successor]
if E.le(amount, 0): continue
if E.eq(successor, "blast"):
blast_power = E.add(blast_power, amount)
continue
if (not world.catalog.entities.has(successor)):
continue
@@ -162,27 +192,38 @@ func evolve_batch_generation(target: Dictionary, to_year: Variant, completed: Di
else:
amount = world.ledger.credit(target, successor, amount)
var produces: bool = not world.automatic.yearly_products(world.catalog.entities[successor]).is_empty()
var before_batches: Array = target.batches.get(successor, []).duplicate(true) if produces else []
var newborn_adjustment: Dictionary = {}
var cutoff: Variant = (to_year if world.stellar.uses_short_lived_fast_path(successor) else E.neg(INF))
var born_from: Variant = part.from
var born_to: Variant = part.to
if E.gt(resolution, 0) and (Global.CivilizationRules.has(successor) or not world.catalog.entities[successor].life_rule.is_empty()):
# Biological stages (including C0.0/C0.1) and civilizations
# share the coarse clock. Historical retry intervals must
# not retrigger their early population within the same bucket.
born_to = E.multiply(E.ceil_value(E.divide(born_to, resolution)), resolution)
born_from = born_to
var profile_newborn: int = world.profile_start()
var integral: Variant
if budget != null:
integral = await world.batches.append_batch(target, successor, amount, part.from, part.to, completed, cutoff, budget)
integral = await world.batches.append_batch(target, successor, amount, born_from, born_to, completed, cutoff, budget, newborn_adjustment if produces else null, to_year)
if budget.cancelled: return false
else:
integral = world.batches.append_batch(target, successor, amount, part.from, part.to, completed, cutoff)
integral = world.batches.append_batch(target, successor, amount, born_from, born_to, completed, cutoff, null, newborn_adjustment if produces else null, to_year)
if produces:
world.automatic.produce_newborn_lifetime(target, successor, amount, part.from, part.to, to_year, before_batches, integral)
world.automatic.produce_newborn_lifetime(target, successor, amount, born_from, born_to, to_year, newborn_adjustment.get("past_years", 0), integral)
world.profile_end("newborn_batches", profile_newborn)
new_owners[successor] = E.add(new_owners.get(successor, 0), amount)
world.ledger.accept_transfers(target, incoming)
world.ledger.bind_new_owners(target, new_owners)
world.ledger.round_object_allocations(target)
for owner in new_owners:
for resource in world.catalog.entities[owner].bind:
for member in world.catalog.members(resource): affected[member] = true
world.ledger.round_object_allocations(target, affected)
if budget != null:
await CivilizationEvolution.finish(world, target, civilization_transaction, to_year, Global.CivilizationRules, budget)
if budget.cancelled: return false
else:
CivilizationEvolution.finish(world, target, civilization_transaction, to_year, Global.CivilizationRules)
world.stellar.apply_blast(target, blast_power, environment)
if E.gt(blast_power, 0): world.stellar.apply_blast(target, blast_power, environment)
CivilizationState.enforce_capacity(world, target, Global.CivilizationRules, to_year)
return true
+2
View File
@@ -5,11 +5,13 @@ const E = preload("res://world/owniverse/math/exact.gd")
var pending_amounts: Dictionary [ String , Variant ] = {}
var deferred_updates: bool = false
var dirty: bool = true
var revision: int = 0
func refresh(state: Dictionary, catalog, force: bool = false) -> void:
dirty = true
if (deferred_updates and (not force)):
return
revision += 1
pending_amounts = amounts(state, catalog)
dirty = false
+8 -10
View File
@@ -3,11 +3,12 @@ const E = preload("res://world/owniverse/math/exact.gd")
const WorldParameters = preload("res://world/owniverse/world_parameters.gd")
const QuantityMath = preload("res://world/owniverse/quantity_math.gd")
func life_products(target: Dictionary, entity: OwniverseEntity, count: Variant) -> Dictionary:
var rule: Dictionary = entity.life_rule
func life_products(target: Dictionary, entity: OwniverseEntity, count: Variant, context: Dictionary = {}) -> Dictionary:
var plan: Dictionary = entity.generation_plan
var pending: Dictionary = {}
var modifiers: Dictionary = WorldParameters.life_modifiers(target)
var probabilities: Dictionary = {"progress": E.multiply(E.multiply(E.of(rule.progress), modifiers.progress), WorldParameters.value(target, "Enlightenment")), "degradation": E.multiply(E.of(rule.degradation), modifiers.degradation)}
var modifiers: Dictionary = context.life_modifiers if context.has("life_modifiers") else WorldParameters.life_modifiers(target)
var enlightenment: Variant = context.enlightenment if context.has("enlightenment") else WorldParameters.value(target, "Enlightenment")
var probabilities: Dictionary = {"progress": E.multiply(E.multiply(plan.life_progress, modifiers.progress), enlightenment), "degradation": E.multiply(plan.life_degradation, modifiers.degradation)}
var probability_sum: Variant = E.maximum(1, E.add(probabilities.progress, probabilities.degradation))
if (not target.has("life_remainders")):
target.life_remainders = {}
@@ -21,13 +22,10 @@ func life_products(target: Dictionary, entity: OwniverseEntity, count: Variant)
var key: String = E.add(E.add(entity.id, ":"), channel)
target.life_remainders[key] = E.maximum(0, E.subtract(target.life_remainders[key], assigned[channel]))
var result: Dictionary = {entity.id: E.subtract(E.subtract(count, assigned.progress), assigned.degradation)}
result[rule.next] = assigned.progress
var weights: Dictionary = {}
result[plan.life_next] = assigned.progress
var weights: Dictionary = plan.life_fall
var weight_sum: Variant = 0
for term in str(rule.fall).split("^"):
var pair: PackedStringArray = term.split(":")
weights[pair[0]] = E.of(pair[1])
weight_sum = E.add(weight_sum, E.of(pair[1]))
for weight in weights.values(): weight_sum = E.add(weight_sum, weight)
var requests: Dictionary = {}
for id in weights:
var key: String = E.add(E.add(entity.id, ":fall:"), id)
+17
View File
@@ -47,6 +47,9 @@ static func subtract(a: Array, b: Array) -> Array:
return trim(result)
static func multiply(a: Array, b: Array) -> Array:
if a == [0] or b == [0]: return [0]
if a == [1]: return b.duplicate()
if b == [1]: return a.duplicate()
var result: Array = []
result.resize(a.size() + b.size())
result.fill(0)
@@ -64,6 +67,20 @@ static func divmod(a: Array, b: Array) -> Array:
assert(b != [0], "Division by zero")
if b == [1]: return [a.duplicate(), [0]]
if compare(a, b) < 0: return [[0], a.duplicate()]
# Decimal ratios often share entire base-1e9 factors. Cancel them before
# long division; restore the remainder's original scale afterwards.
var shared: int = 0
while shared < mini(a.size(), b.size()) - 1 and a[shared] == 0 and b[shared] == 0:
shared += 1
if shared:
var reduced: Array = divmod(a.slice(shared), b.slice(shared))
if reduced[1] != [0]:
var restored: Array = []
restored.resize(shared)
restored.fill(0)
restored.append_array(reduced[1])
reduced[1] = restored
return reduced
if b.size() == 1:
var quotient: Array = []
quotient.resize(a.size())
+39
View File
@@ -170,6 +170,8 @@ static func absolute(a): return neg(a) if lt(a, 0) else a
static func add(a, b):
if not numeric(a) or not numeric(b): return a + b
if b is int and b == 0: return of(a)
if a is int and a == 0: return of(b)
if a is int and b is int:
if (b >= 0 and a <= MAX_INT - b) or (b < 0 and a >= MIN_INT - b): return a + b
if not finite(a) or not finite(b): return approx(a) + approx(b)
@@ -190,6 +192,7 @@ static func add(a, b):
static func subtract(a, b):
if not numeric(a) or not numeric(b): return a - b
if b is int and b == 0: return of(a)
if a is int and b is int:
if (b >= 0 and a >= MIN_INT + b) or (b < 0 and a <= MAX_INT + b): return a - b
return add(a, neg(b))
@@ -202,6 +205,10 @@ static func multiply(a, b):
if eq(b, 1): return of(a)
if a is int and b is int and a != MIN_INT and b != MIN_INT:
if absi(a) <= MAX_INT / absi(b): return a * b
if (a is int or (a is Value and a.fraction == 0.0)) and (b is int or (b is Value and b.fraction == 0.0)):
var whole_a: Array = _blocks(a)
var whole_b: Array = _blocks(b)
return _compose(Big.multiply(whole_a[0], whole_b[0]), 0.0, whole_a[2] * whole_b[2])
var x: Array = parts(a)
var y: Array = parts(b)
return make(Big.multiply(x[0], y[0]), Big.multiply(x[1], y[1]), x[2] * y[2])
@@ -217,6 +224,38 @@ static func mul_div(a, b, divisor):
assert(z[0] != [0], "Division by zero")
return make(Big.multiply(Big.multiply(x[0], y[0]), z[1]), Big.multiply(Big.multiply(x[1], y[1]), z[0]), x[2] * y[2] * z[2])
## Reuse the count and divisor decomposition across all quotas.
static func mul_div_many(a, values: Array, divisor) -> Array:
var result: Array = []
if not finite(a) or not finite(divisor):
for value in values: result.append(mul_div(a, value, divisor))
return result
var x: Array = parts(a)
var z: Array = parts(divisor)
assert(z[0] != [0], "Division by zero")
for value in values:
if not finite(value) or (a is int and value is int and a != MIN_INT and value != MIN_INT and (value == 0 or absi(a) <= MAX_INT / absi(value))):
result.append(mul_div(a, value, divisor))
continue
var y: Array = parts(value)
result.append(make(Big.multiply(Big.multiply(x[0], y[0]), z[1]), Big.multiply(Big.multiply(x[1], y[1]), z[0]), x[2] * y[2] * z[2]))
return result
## Cancel an integer population from quotas, retaining the original float ratio.
static func population_quotas(count, weights: Array, factor: int) -> Array:
var denominator = multiply(count, factor)
if ne(count, floor_value(count)) or le(count, 0): return mul_div_many(count, weights, denominator)
var population: Array = _blocks(count)[0]
var denominator_blocks: Array = Big.multiply(population, [factor])
var result: Array = []
for weight in weights:
if ne(weight, floor_value(weight)) or lt(weight, 0) or (count is int and weight is int and count != MIN_INT and weight != MIN_INT and (weight == 0 or absi(count) <= MAX_INT / absi(weight))):
result.append(mul_div(count, weight, denominator))
else:
var qr: Array = Big.divmod(_blocks(weight)[0], [factor])
result.append(_compose(qr[0], _fraction_ratio(Big.multiply(qr[1], population), denominator_blocks)))
return result
## Sum of nonnegative linear quotas rounded down separately at each boundary.
static func floor_sum(count, step, offset, divisor):
var n: Array = parts(count)
+130 -13
View File
@@ -4,7 +4,99 @@ const CivilizationState = preload("res://world/owniverse/civilization_state.gd")
const SimulationTime = preload("res://world/owniverse/simulation_time.gd")
const WorldParameters = preload("res://world/owniverse/world_parameters.gd")
func temporal_resolution(target: Dictionary) -> Variant:
var speed: int = int(target.get("speed", 1))
return E.divide(E.power(10, speed - 1), 10) if speed >= 4 else 0
func window_duration(target: Dictionary, lifespan: Variant) -> Variant:
if E.le(lifespan, 10): return lifespan
var base: Variant = E.divide(lifespan, Global.batch_count)
# At high speed one tenth of a real second is the temporal resolution.
# Short stellar explosions retain their original event windows.
return E.maximum(base, temporal_resolution(target))
func coarsen(target: Dictionary) -> void:
if int(target.get("speed", 1)) < 4: return
for id in target.batches:
if target.batches[id].size() <= 1: continue
if not world.catalog.entities.has(id): continue
var lifespan: Variant = effective_lifespan(target, id)
if E.le(lifespan, 10): continue
var width: Variant = window_duration(target, lifespan)
if E.le(width, E.divide(lifespan, Global.batch_count)): continue
var groups: Dictionary = {}
var result: Array = []
for batch: Dictionary in target.batches[id]:
# Never move an already processed boundary backwards.
var start: Variant = E.maximum(batch.start_year, batch.get("processed_until", batch.start_year))
var key: String = str(E.floor_value(E.divide(start, width)))
if not groups.has(key):
var combined: Dictionary = batch.duplicate()
groups[key] = combined
result.append(combined)
else:
var combined: Dictionary = groups[key]
combined.amount = E.add(combined.amount, batch.amount)
combined.start_year = E.minimum(combined.start_year, batch.start_year)
combined.end_year = E.maximum(combined.end_year, batch.end_year)
combined.created_from = E.minimum(combined.get("created_from", start), batch.get("created_from", start))
combined.created_to = E.maximum(combined.get("created_to", batch.end_year), batch.get("created_to", batch.end_year))
combined.withdraw_remainder = E.add(combined.get("withdraw_remainder", 0), batch.get("withdraw_remainder", 0))
if combined.has("processed_until") or batch.has("processed_until"):
combined.processed_until = E.maximum(combined.get("processed_until", combined.start_year), batch.get("processed_until", batch.start_year))
if result.size() < target.batches[id].size():
result.sort_custom(func(a: Dictionary, b: Dictionary) -> bool: return E.lt(a.get("created_from", a.start_year), b.get("created_from", b.start_year)))
target.batches[id] = result
# Indices belong to one transaction. Withdrawal replaces the cohort array,
# invalidating that entity's index; amount changes leave its keys intact.
var _indexed_target: Dictionary = {}
var _batch_indices: Dictionary = {}
var _ready_target: Dictionary = {}
var _ready_indices: Dictionary = {}
var _instant_target: Dictionary = {}
var _instant_appends: Dictionary = {}
var _static_spans: Dictionary = {}
var _star_spans: Dictionary = {}
func effective_lifespan(target: Dictionary, id: String) -> Variant:
var entity: OwniverseEntity = world.catalog.entities[id]
if Global.CivilizationRules.has(id):
if CivilizationState.is_space_civilization(id, Global.CivilizationRules):
return CivilizationState.effective_span(world, target, id, Global.CivilizationRules)
return Global.CivilizationRules[id].span
var lifespan: Variant = _static_spans.get(id, entity.lifespan)
if not _static_spans.has(id): _static_spans[id] = lifespan
if entity.group_as != "Star": return lifespan
var burnability: Variant = WorldParameters.effective(target, "Bur")
var signature: String = id + ":" + str(burnability)
if _star_spans.has(signature): return _star_spans[signature]
var result: Variant = E.divide(lifespan, burnability)
if _star_spans.size() >= 256: _star_spans.clear()
_star_spans[signature] = result
return result
func batch_index(target: Dictionary, id: String, batches: Array) -> Dictionary:
if not is_same(_indexed_target, target):
_indexed_target = target
_batch_indices.clear()
var cached: Dictionary = _batch_indices.get(id, {})
if not cached.is_empty() and is_same(cached.batches, batches) and cached.count == batches.size():
return cached.starts
for i in range(1, batches.size()):
if E.lt(batches[i].get("created_from", -INF), batches[i - 1].get("created_from", -INF)):
batches.sort_custom(func(a: Dictionary, b: Dictionary) -> bool: return E.lt(a.get("created_from", -INF), b.get("created_from", -INF)))
break
var starts: Dictionary = {}
for existing: Dictionary in batches:
var key: String = str(existing.get("created_from", -INF))
if not starts.has(key): starts[key] = []
starts[key].append(existing)
_batch_indices[id] = {"batches": batches, "count": batches.size(), "starts": starts}
return starts
func scale_batches(target: Dictionary, id: String, factor: Variant) -> void:
_ready_indices.erase(id)
var batches: Array = target.batches.get(id, [])
if batches.is_empty():
return
@@ -34,26 +126,29 @@ func scale_batches(target: Dictionary, id: String, factor: Variant) -> void:
share.batch.withdraw_remainder = E.minimum(share.batch.get("withdraw_remainder", 0), share.batch.amount)
func append_batch(target: Dictionary, id: String, amount: Variant, created_from: Variant, created_to: Variant, completed: Dictionary = { }, completed_before: Variant = - INF, budget: RefCounted = null) -> Variant:
func append_batch(target: Dictionary, id: String, amount: Variant, created_from: Variant, created_to: Variant, completed: Dictionary = { }, completed_before: Variant = - INF, budget: RefCounted = null, newborn_adjustment: Variant = null, newborn_until: Variant = NAN) -> Variant:
var _keep_alive: RefCounted = self
if ((E.le(amount, 0) or (not world.catalog.entities.has(id))) or E.le(world.catalog.entities[id].lifespan, 0)):
return NAN
if E.lt(created_to, created_from):
return NAN
_ready_indices.erase(id)
if (not target.batches.has(id)):
target.batches[id] = []
if (not target.has("batch_origins")):
target.batch_origins = {}
var batches: Array = target.batches[id]
var lifespan: Variant = CivilizationState.effective_span(world, target, id, Global.CivilizationRules)
if E.eq(world.catalog.entities[id].group_as, "Star"):
lifespan = E.divide(lifespan, WorldParameters.effective(target, "Bur"))
var batch_duration: Variant = (E.divide(lifespan, Global.batch_count) if E.gt(lifespan, 10) else lifespan)
var lifespan: Variant = effective_lifespan(target, id)
var batch_duration: Variant = window_duration(target, lifespan)
if E.le(batch_duration, 0):
return NAN
if (not target.batch_origins.has(id)):
target.batch_origins[id] = (batches[0].get("created_from", created_from) if (not batches.is_empty()) else created_from)
var origin: Variant = target.batch_origins[id]
if E.gt(temporal_resolution(target), 0) and (Global.CivilizationRules.has(id) or not world.catalog.entities[id].life_rule.is_empty()):
# Match successor birth buckets, regardless of the old saved origin.
# Otherwise a rounded birth can be placed back into an earlier window.
origin = 0
var cursor: Variant = created_from
var duration: Variant = E.subtract(created_to, created_from)
var remaining_amount: Variant = amount
@@ -62,18 +157,23 @@ func append_batch(target: Dictionary, id: String, amount: Variant, created_from:
var completed_to: Variant = E.neg(INF)
# Subtract each completed window's lifetime production exactly.
var remaining_object_years: Variant = (E.multiply(amount, E.maximum(0, E.subtract(completed_before, E.multiply((E.add(created_from, created_to)), E.of("0.5"))))) if E.finite(completed_before) else NAN)
if not is_same(_instant_target, target):
_instant_target = target
_instant_appends.clear()
var instant: Dictionary = _instant_appends.get(id, {})
if E.eq(duration, 0) and not instant.is_empty() and is_same(instant.batches, batches) and instant.count == batches.size() and E.eq(instant.birth, created_from) and E.eq(instant.lifespan, lifespan) and E.eq(instant.width, batch_duration) and E.eq(instant.origin, origin) and E.gt(instant.batch.end_year, completed_before):
instant.batch.amount = E.add(instant.batch.amount, amount)
if newborn_adjustment != null and E.finite(newborn_until):
newborn_adjustment.past_years = E.add(newborn_adjustment.get("past_years", 0), E.multiply(amount, expired_years(newborn_until, instant.batch.start_year, instant.batch.end_year)))
return remaining_object_years
# Advance an exact window index rather than repeatedly finding a boundary.
var window_index: Variant = E.floor_value(E.divide((E.subtract(cursor, origin)), batch_duration))
if E.le(E.add(origin, E.multiply((E.add(window_index, 1)), batch_duration)), cursor):
window_index = E.add(window_index, 1)
var batches_by_start: Dictionary = {}
var batches_by_start: Dictionary = batch_index(target, id, batches)
var order_changed: bool = false
var skip_empty_expired: bool = E.gt(duration, 0) and E.finite(completed_before) and E.eq(amount, E.floor_value(amount))
var sparse_windows: bool = E.gt(duration, 0) and E.gt(amount, 0) and E.gt(duration, E.multiply(batch_duration, amount)) and not skip_empty_expired
for existing : Dictionary in batches:
var start: Variant = existing.get("created_from", E.neg(INF))
if (not batches_by_start.has(str(start))):
batches_by_start[str(start)] = []
batches_by_start[str(start)].append(existing)
while true:
if budget != null and not await budget.pause(): return NAN
# A zero cohort is discarded by withdraw_batches. Jump straight to the
@@ -145,17 +245,24 @@ func append_batch(target: Dictionary, id: String, amount: Variant, created_from:
break
if batch.is_empty():
batch = {"created_from": window_start, "created_to": window_end, "start_year": E.add(window_start, lifespan), "end_year": E.add(window_end, lifespan), "amount": 0}
order_changed = order_changed or (not batches.is_empty() and E.lt(window_start, batches.back().created_from))
batches.append(batch)
if (not batches_by_start.has(str(window_start))):
batches_by_start[str(window_start)] = []
batches_by_start[str(window_start)].append(batch)
batch.amount = E.add(batch.amount, part_amount)
if newborn_adjustment != null and E.finite(newborn_until):
newborn_adjustment.past_years = E.add(newborn_adjustment.get("past_years", 0), E.multiply(part_amount, expired_years(newborn_until, batch.start_year, batch.end_year)))
if E.eq(duration, 0):
_instant_appends[id] = {"batches": batches, "count": batches.size(), "birth": created_from, "lifespan": lifespan, "width": batch_duration, "origin": origin, "batch": batch}
remaining_amount = E.subtract(remaining_amount, part_amount)
if (E.eq(duration, 0) or E.ge(part_end, created_to)):
break
cursor = window_end
window_index = E.add(window_index, 1)
batches.sort_custom(func ( a : Dictionary , b : Dictionary ) -> bool : return E.lt(a.created_from, b.created_from))
if order_changed:
batches.sort_custom(func ( a : Dictionary , b : Dictionary ) -> bool : return E.lt(a.created_from, b.created_from))
_batch_indices[id].count = batches.size()
if E.gt(completed_amount, 0):
if (not completed.has(id)): completed[id] = []
completed[id].append({"amount": completed_amount, "from": completed_from, "to": completed_to})
@@ -163,9 +270,16 @@ func append_batch(target: Dictionary, id: String, amount: Variant, created_from:
func withdraw_batches(target: Dictionary, id: String, to_year: Variant) -> Array:
if not is_same(_ready_target, target):
_ready_target = target
_ready_indices.clear()
var batches: Array = target.batches.get(id, [])
var ready: Dictionary = _ready_indices.get(id, {})
if not ready.is_empty() and is_same(ready.batches, batches) and ready.count == batches.size() and E.lt(to_year, ready.year): return []
var expired: Array = []
var remaining: Array = []
for batch : Dictionary in target.batches.get(id, []):
var next_year: Variant = INF
for batch : Dictionary in batches:
var start: Variant = E.maximum(batch.start_year, batch.get("processed_until", batch.start_year))
var end: Variant = batch.end_year
var amount: Variant = batch.amount
@@ -173,6 +287,7 @@ func withdraw_batches(target: Dictionary, id: String, to_year: Variant) -> Array
continue
if (E.lt(to_year, start) or ((E.eq(to_year, start) and E.gt(end, start)))):
remaining.append(batch)
next_year = E.minimum(next_year, start)
continue
var consumed: Variant = amount
var until: Variant = E.minimum(to_year, end)
@@ -184,9 +299,11 @@ func withdraw_batches(target: Dictionary, id: String, to_year: Variant) -> Array
batch.amount = E.maximum(0, E.subtract(amount, consumed))
batch.processed_until = to_year
remaining.append(batch)
next_year = E.minimum(next_year, to_year)
if E.gt(consumed, 0):
expired.append({"amount": consumed, "from": start, "to": until})
target.batches[id] = remaining
_ready_indices[id] = {"batches": remaining, "count": remaining.size(), "year": next_year}
return expired
+34 -11
View File
@@ -7,6 +7,11 @@ var _amount_snapshot: Dictionary = {}
var _binds_snapshot: Dictionary = {}
var _physical_cache: Dictionary = {}
var _physical_revision: int = -1
# Per-world derived caches: never serialized and never shared between worlds.
var reconciled_ethics: Dictionary = {}
var worship_products: Dictionary = {}
var civilization_modifiers: Dictionary = {}
var civilization_coefficients: Dictionary = {}
func physical_amounts(source: Dictionary) -> Dictionary:
world.catalog._ensure_group_index()
@@ -107,9 +112,10 @@ func credit(target: Dictionary, id: String, amount: Variant) -> Variant:
return amount
func round_object_allocations(target: Dictionary) -> void:
var physical: Dictionary = physical_amounts(target)
for id in physical:
func round_object_allocations(target: Dictionary, affected: Variant = null) -> void:
var ids: Variant = world.catalog.entities if affected == null else affected
for id in ids:
if not world.catalog.entities.has(id) or world.catalog.is_group(id): continue
if (not is_discrete(id)):
continue
var slots: Array = [{"owner": "", "value": target.amount.get(id, 0)}]
@@ -117,12 +123,17 @@ func round_object_allocations(target: Dictionary) -> void:
if target.binds[owner_id].has(id):
slots.append({"owner": owner_id, "value": target.binds[owner_id][id]})
var assigned: Variant = 0
var physical: Variant = 0
var fractional: bool = false
for slot : Dictionary in slots:
slot.whole = E.floor_value(slot.value)
slot.rest = E.subtract(slot.value, slot.whole)
assigned = E.add(assigned, slot.whole)
physical = E.add(physical, E.maximum(0, slot.value))
fractional = fractional or E.ne(slot.rest, 0)
if not fractional: continue
slots.sort_custom(func ( a : Dictionary , b : Dictionary ) -> bool : return (E.gt(a.rest, b.rest) if E.ne(a.rest, b.rest) else E.lt(str(a.owner), str(b.owner))))
var left: Variant = E.subtract(E.round_value(physical[id]), assigned)
var left: Variant = E.subtract(E.round_value(physical), assigned)
for slot : Dictionary in slots:
if E.gt(left, 0):
slot.whole = E.add(slot.whole, 1)
@@ -182,15 +193,21 @@ func bind_new_owners(target: Dictionary, amounts: Dictionary, require_full: bool
if require_full:
return bind_full(target, amounts)
var requests: Dictionary = {}
var distributions: Dictionary = {}
for owner_id in amounts:
if (not world.catalog.entities.has(owner_id)):
continue
if E.le(amounts[owner_id], 0): continue
for id in world.catalog.entities[owner_id].bind:
var quantity: Variant = E.multiply(amounts[owner_id], E.maximum(0, world.catalog.entities[owner_id].bind[id]))
var weights: Dictionary = {}
for member in world.catalog.members(id):
weights[member] = target.amount.get(member, 0)
weights = QuantityMath.normalize_distribution(weights)
# Requests are collected before any stock is changed. Every owner
# asking for this resource therefore uses the same distribution.
if not distributions.has(id):
var members: Dictionary = {}
for member in world.catalog.members(id):
members[member] = target.amount.get(member, 0)
distributions[id] = QuantityMath.normalize_distribution(members)
var weights: Dictionary = distributions[id]
for member in weights:
if (not requests.has(member)):
requests[member] = {}
@@ -256,17 +273,23 @@ func process_entity(entity_id: String, amount: Variant) -> void:
## Freeze holdings before simultaneous transitions and reserve successors.
func transfer_evolution(target: Dictionary, fractions: Dictionary, outputs: Dictionary) -> Dictionary:
# Use a frozen binding table so simultaneous transitions cannot cascade by type order.
var bindings: Dictionary = target.binds.duplicate(true)
var bindings: Dictionary = target.binds.duplicate()
var incoming: Dictionary = {}
for owner_id in bindings:
var owner_survival: Variant = E.subtract(1, fractions.get(owner_id, 0))
var stellar_heirs: Dictionary = world.stellar.stellar_successors(outputs.get(owner_id, {}))
target.binds[owner_id] = {}
for id in bindings[owner_id]:
var held: Variant = bindings[owner_id][id]
var fraction: Variant = fractions.get(id, 0)
if E.eq(held, 0) or (E.eq(owner_survival, 1) and E.eq(fraction, 0)):
# Preserve the holding without running release/inheritance math
# for populations that did not participate in this generation.
target.binds[owner_id][id] = held
continue
var released: Variant = E.multiply(held, (E.subtract(1, owner_survival)))
target.amount[id] = E.add(target.amount.get(id, 0), released)
var heirs: Dictionary = (world.stellar.stellar_successors(outputs.get(owner_id, {})) if (world.catalog.entities.has(id) and E.eq(world.catalog.entities[id].group_as, "Planet")) else {})
var fraction: Variant = fractions.get(id, 0)
var heirs: Dictionary = (stellar_heirs if (world.catalog.entities.has(id) and E.eq(world.catalog.entities[id].group_as, "Planet")) else {})
for heir in heirs:
if (not incoming.has(heir)):
incoming[heir] = {}
+28 -4
View File
@@ -65,6 +65,27 @@ var _requested_speed: int = 0
var _queued_productions: Array = []
var frame_active_clock: Dictionary = {}
var _resume_clock: Dictionary = {}
var frame_step_seconds: float = 0.1
var _frame_step_speed: int = 0
var _frame_started_usec: int = 0
var _frame_duration_seconds: float = 0.0
var _frame_cost_ratio: float = 0.0
## Hysteresis prevents alternating step sizes around one queue threshold.
## Only scheduling uses float; both clocks and the accumulated debt stay exact.
func update_frame_step() -> float:
if _frame_step_speed != speed:
_frame_step_speed = speed
frame_step_seconds = 0.1
_frame_cost_ratio = 0.0
if speed < 4: return 1.0 / 60.0
var debt: Variant = E.maximum(0, E.subtract(frame_clock.get("datetime", state.time.datetime), state.time.datetime))
var seconds: float = E.approx(E.divide(debt, state.speed_in_year))
if seconds > frame_step_seconds * 2.0 or (_frame_cost_ratio > 0.85 and seconds > frame_step_seconds):
frame_step_seconds = 0.2 if frame_step_seconds < 0.2 else 0.5
elif seconds < frame_step_seconds * 0.5:
frame_step_seconds = 0.2 if frame_step_seconds > 0.2 else 0.1
return frame_step_seconds
## Keep the requested clock advancing while a transaction spans render frames.
func evolute_frame(delta: float, tree: SceneTree) -> void:
@@ -76,14 +97,14 @@ func evolute_frame(delta: float, tree: SceneTree) -> void:
frame_busy = true
frame_budget = preload("res://world/owniverse/frame_budget.gd").new(tree)
frame_active_clock = _resume_clock if not _resume_clock.is_empty() else frame_clock.duplicate()
# Keep each transaction at the normal 60 Hz simulation interval. The
# requested clock holds the backlog, rather than feeding an ever-growing
# multi-generation interval into one transaction and freezing publication.
# Bound catch-up work; never turn the entire accumulated debt into one step.
if _resume_clock.is_empty():
var normal_clock: Dictionary = SimulationTime.advance(state.time, 1.0 / 60.0, speed)
var normal_clock: Dictionary = SimulationTime.advance(state.time, update_frame_step(), speed)
if E.lt(normal_clock.datetime, frame_clock.datetime):
frame_active_clock = normal_clock
_resume_clock = {}
_frame_duration_seconds = E.approx(E.divide(E.subtract(frame_active_clock.datetime, state.time.datetime), state.speed_in_year))
_frame_started_usec = Time.get_ticks_usec()
evolution.run_frame(frame_active_clock, frame_budget)
func request_production(id: String, amount: Variant, resource: bool = false) -> void:
@@ -108,6 +129,9 @@ func restore_frame_checkpoint(checkpoint: Dictionary) -> void:
_requested_speed = checkpoint.get("speed", state.speed)
func finish_frame() -> void:
if _frame_started_usec > 0 and _frame_duration_seconds > 0:
var ratio: float = (Time.get_ticks_usec() - _frame_started_usec) / 1000000.0 / _frame_duration_seconds
_frame_cost_ratio = ratio if _frame_cost_ratio == 0.0 else lerpf(_frame_cost_ratio, ratio, 0.25)
frame_busy = false
frame_commits += 1
if _requested_speed != 0:
+39
View File
@@ -1,6 +1,7 @@
extends Node
class_name OwniverseEntity
const E = preload("res://world/owniverse/math/exact.gd")
const QuantityMath = preload("res://world/owniverse/quantity_math.gd")
var id: String
var is_visible: bool = false
@@ -10,6 +11,8 @@ var bind: Dictionary = {}
var mass: Variant
var space: int
var life_rule: Dictionary = {}
var life_fall_weights: Dictionary = {}
var generation_plan: Dictionary = {}
var lifespan: Variant
var lifespan_delta: Variant
var auto: Variant
@@ -47,6 +50,8 @@ func _init(values: Dictionary) -> void:
life_rule = Global.LifeRules.get(id, {}).duplicate(true)
if Global.CivilizationRules.has(id):
life_rule = {"ethical": true, "span": Global.CivilizationRules[id].span}
elif not life_rule.is_empty():
life_fall_weights = QuantityMath.rule_weights(str(life_rule.get("fall", "")))
lifespan = (E.of(life_rule.span) if (not life_rule.is_empty()) else E.of(values.lifespan))
lifespan_delta = (E.divide(lifespan, Global.batch_count) if E.gt(lifespan, 10) else lifespan)
auto = E.of(values.auto)
@@ -72,6 +77,40 @@ func _init(values: Dictionary) -> void:
space_bonus = E.of(values.space_bonus)
civ_bonus = E.of(values.civ_bonus)
claim = values.claim
refresh_generation_plan()
func refresh_generation_plan() -> void:
var fall_text: String = str(life_rule.get("fall", ""))
if not generation_plan.is_empty() \
and E.eq(generation_plan.outputs, output_and) \
and E.eq(generation_plan.chance, output_or.get("chance", 0)) \
and E.eq(generation_plan.positive, output_or.get("positive", "")) \
and E.eq(generation_plan.negative, output_or.get("negative", "")) \
and E.eq(generation_plan.blast, blast) \
and E.eq(generation_plan.life_progress, life_rule.get("progress", 0)) \
and E.eq(generation_plan.life_degradation, life_rule.get("degradation", 0)) \
and E.eq(generation_plan.life_next, str(life_rule.get("next", id))) \
and E.eq(generation_plan.life_fall_text, fall_text):
return
life_fall_weights = QuantityMath.rule_weights(fall_text) if not fall_text.is_empty() else {}
generation_plan = {
"life": not life_rule.is_empty(),
"life_progress": E.of(life_rule.get("progress", 0)),
"life_degradation": E.of(life_rule.get("degradation", 0)),
"life_next": str(life_rule.get("next", id)),
"life_fall": life_fall_weights,
"outputs": output_and,
"chance": output_or.get("chance", 0),
"positive": output_or.get("positive", ""),
"negative": output_or.get("negative", ""),
"life_fall_text": fall_text,
"positive_terms": QuantityMath.output_terms(str(output_or.get("positive", ""))),
"negative_terms": QuantityMath.output_terms(str(output_or.get("negative", ""))),
"blast": blast,
"destroy_level": destroy_level
}
generation_plan.make_read_only()
func _parse_or_string(source_line: String) -> Dictionary:
+99 -13
View File
@@ -1,6 +1,32 @@
extends RefCounted
const E = preload("res://world/owniverse/math/exact.gd")
## Quantity arithmetic without scene tree or global settings.
static var _weight_rules: Dictionary = {}
static var _output_rules: Dictionary = {}
## Parsed rules are shared read-only; the string itself is the cache key.
static func rule_weights(text: String) -> Dictionary:
if _weight_rules.has(text): return _weight_rules[text]
var result: Dictionary = {}
for term in text.split("^", false):
var pair: PackedStringArray = term.split(":")
result[pair[0]] = E.of(pair[1])
if _weight_rules.size() >= 128: _weight_rules.clear()
result.make_read_only()
_weight_rules[text] = result
return result
static func output_terms(text: String) -> Array:
if _output_rules.has(text): return _output_rules[text]
var result: Array = []
for term in text.split("&"):
var pair: PackedStringArray = term.strip_edges().split(":")
if pair[0].strip_edges().is_empty(): continue
result.append({"id": pair[0].strip_edges(), "amount": E.of(pair[1]) if E.eq(pair.size(), 2) else 1})
if _output_rules.size() >= 128: _output_rules.clear()
result.make_read_only()
_output_rules[text] = result
return result
static func accumulate_whole(target: Dictionary, field: String, key: String, value: Variant) -> Variant:
if (not target.has(field)):
@@ -17,6 +43,18 @@ static func allocate_whole(requests: Dictionary, limit: Variant) -> Dictionary:
for id in requests:
result[id] = E.floor_value(E.maximum(0, requests[id]))
total = E.add(total, result[id])
return _allocate_whole_with_total(requests, limit, result, total)
## Variant for callers that already maintain the sum of floored request values.
## The supplied total must equal sum(floor(max(0, requests[id]))).
static func allocate_whole_with_total(requests: Dictionary, limit: Variant, request_total: Variant) -> Dictionary:
var result: Dictionary = {}
for id in requests: result[id] = E.floor_value(E.maximum(0, requests[id]))
return _allocate_whole_with_total(requests, limit, result, request_total)
static func _allocate_whole_with_total(requests: Dictionary, limit: Variant, result: Dictionary, total: Variant) -> Dictionary:
var available: Variant = E.floor_value(E.minimum(E.maximum(0, limit), total))
# No apportionment or rounding is necessary when every request fits.
if E.eq(available, total): return result
@@ -72,34 +110,82 @@ static func normalize_distribution(values: Dictionary) -> Dictionary:
return normalized_distribution
static func sum_array(values: Array) -> Variant:
var result: Variant = 0
for value in values: result = E.add(result, value)
return result
static func sum(pop: Dictionary) -> Variant:
var result: Variant = 0
for n in pop.values(): result = E.add(result, n)
return result
static var _split_keys: Dictionary = {}
static func split(remainders: Dictionary, key: String, count: Variant, weights: Dictionary) -> Dictionary:
if E.le(count, 0): return {}
return split_arrays(remainders, key, count, weights.keys(), weights.values())
static func split_arrays(remainders: Dictionary, key: String, count: Variant, ids: Array, weights: Array, population_factor: int = 0) -> Dictionary:
var result: Dictionary = {}
var sum_weights: Variant = sum(weights)
if (E.le(count, 0) or E.le(sum_weights, 0)): return result
var ids: Array = weights.keys()
if E.le(count, 0): return result
var sum_weights: Variant = 0
var positive_index: int = -1
var positive_count: int = 0
for i in weights.size():
sum_weights = E.add(sum_weights, weights[i])
if E.gt(weights[i], 0):
positive_index = i
positive_count += 1
if E.le(sum_weights, 0): return result
var cached: Dictionary = _split_keys.get(key, {})
if cached.is_empty() or cached.ids != ids:
var keys: Array = []
for id in ids: keys.append(key + ":" + str(id))
if _split_keys.size() >= 512: _split_keys.clear()
cached = {"ids": ids.duplicate(), "keys": keys}
_split_keys[key] = cached
var remainder_keys: Array = cached.keys
# A single branch is exact only when no saved rounding error redistributes it.
var single: bool = positive_count == 1 and E.eq(count, E.floor_value(count))
if single:
for i in ids.size():
if E.lt(weights[i], 0) or E.ne(remainders.get(remainder_keys[i], 0), 0):
single = false
break
if single:
for i in ids.size():
result[ids[i]] = count if i == positive_index else 0
remainders[remainder_keys[i]] = 0
return result
var expected: Array = []
var remainder_keys: Array = []
if population_factor > 0 and E.eq(sum_weights, E.multiply(count, population_factor)):
# Ordinary drift: count cancels exactly from count*weight/(factor*count).
expected = E.population_quotas(count, weights, population_factor)
else:
expected = E.mul_div_many(count, weights, sum_weights)
var positives: Array = []
var positive_sum: Variant = 0
for id in ids:
var remainder_key: String = key + ":" + str(id)
remainder_keys.append(remainder_key)
var value: Variant = E.add(E.mul_div(count, weights[id], sum_weights), remainders.get(remainder_key, 0))
expected.append(value)
positive_sum = E.add(positive_sum, E.maximum(0, value))
var whole_quotas: bool = true
for i in ids.size():
expected[i] = E.add(expected[i], remainders.get(remainder_keys[i], 0))
var positive: Variant = E.maximum(0, expected[i])
whole_quotas = whole_quotas and E.eq(positive, E.floor_value(positive))
positives.append(positive)
positive_sum = E.add(positive_sum, positive)
# Fractional identity ratios still round-trip through parts/make in the
# original algorithm. Retain them to preserve ties and saved errors exactly.
var normalized: Array = positives
if E.gt(positive_sum, 0) and (E.ne(positive_sum, count) or not whole_quotas):
normalized = E.mul_div_many(count, positives, positive_sum)
var order: Array = []
var rests: Array = []
var assigned: Variant = 0
for i in ids.size():
var normalized: Variant = E.mul_div(E.maximum(0, expected[i]), count, positive_sum) if E.gt(positive_sum, 0) else 0
result[ids[i]] = E.floor_value(normalized)
result[ids[i]] = E.floor_value(normalized[i])
assigned = E.add(assigned, result[ids[i]])
rests.append(E.subtract(normalized, result[ids[i]]))
rests.append(E.subtract(normalized[i], result[ids[i]]))
order.append(i)
order.sort_custom(func(a: int, b: int) -> bool: return E.gt(rests[a], rests[b]) if E.ne(rests[a], rests[b]) else str(ids[a]) < str(ids[b]))
for i in order:
+24 -18
View File
@@ -9,35 +9,38 @@ var direct_completions: bool = true
func add_output_terms(outputs: Dictionary, terms: String, count: Variant) -> void:
if E.le(count, 0):
return
for term in terms.split("&"):
var parts: PackedStringArray = term.strip_edges().split(":")
var id: String = parts[0].strip_edges()
var amount: Variant = (E.of(parts[1]) if E.eq(parts.size(), 2) else 1)
if (E.ne(id, "") and E.gt(amount, 0)):
outputs[id] = E.add(outputs.get(id, 0), E.multiply(count, amount))
for term: Dictionary in QuantityMath.output_terms(terms):
if E.gt(term.amount, 0):
outputs[term.id] = E.add(outputs.get(term.id, 0), E.multiply(count, term.amount))
func evolution_products(target: Dictionary, entity: OwniverseEntity, count: Variant) -> Dictionary:
if (not entity.life_rule.is_empty()):
return world.life.life_products(target, entity, count)
func evolution_products(target: Dictionary, entity: OwniverseEntity, count: Variant, context: Dictionary = {}) -> Dictionary:
entity.refresh_generation_plan()
var plan: Dictionary = entity.generation_plan
if plan.life:
return world.life.life_products(target, entity, count, context)
var outputs: Dictionary = {}
for id in entity.output_and:
outputs[id] = E.multiply(count, E.maximum(0, entity.output_and[id]))
for id in plan.outputs:
outputs[id] = E.multiply(count, E.maximum(0, plan.outputs[id]))
if (not entity.output_or.is_empty()):
# The parser stores the percentage after '%', e.g. 0.1 means 0.1 percent.
var chance: Variant = E.clamp_value(E.multiply(E.divide(entity.output_or.get("chance", 0), 100), WorldParameters.effective(target, "Exp")), 0, 1)
var explosiveness: Variant = context.explosiveness if context.has("explosiveness") else WorldParameters.effective(target, "Exp")
var chance: Variant = E.clamp_value(E.multiply(E.divide(plan.chance, 100), explosiveness), 0, 1)
if (not target.has("evolution_remainders")):
target.evolution_remainders = {}
var expected: Variant = E.add(E.multiply(count, chance), target.evolution_remainders.get(entity.id, 0))
var positive: Variant = E.minimum(count, E.floor_value(expected))
target.evolution_remainders[entity.id] = E.maximum(0, E.subtract(expected, positive))
add_output_terms(outputs, str(entity.output_or.get("positive", "")), positive)
add_output_terms(outputs, str(entity.output_or.get("negative", "")), E.subtract(count, positive))
for term: Dictionary in plan.positive_terms:
if E.gt(term.amount, 0): outputs[term.id] = E.add(outputs.get(term.id, 0), E.multiply(positive, term.amount))
for term: Dictionary in plan.negative_terms:
if E.gt(term.amount, 0): outputs[term.id] = E.add(outputs.get(term.id, 0), E.multiply(E.subtract(count, positive), term.amount))
# Entity.blast is authoritative even if imported output still contains
# blast:N. Zero disables the event; never add both representations.
outputs.erase("blast")
if E.gt(entity.blast, 0):
outputs["blast"] = E.multiply(E.multiply(count, entity.blast), WorldParameters.effective(target, "Exp"))
if E.gt(plan.blast, 0):
var explosiveness: Variant = context.explosiveness if context.has("explosiveness") else WorldParameters.effective(target, "Exp")
outputs["blast"] = E.multiply(E.multiply(count, plan.blast), explosiveness)
return outputs
@@ -65,11 +68,12 @@ func stellar_successors(products: Dictionary) -> Dictionary:
return QuantityMath.normalize_distribution(weights)
func destroy_planets(target: Dictionary, owner_id: String, ratio: Variant, level: int, cause: String = "local") -> void:
func destroy_planets(target: Dictionary, owner_id: String, ratio: Variant, level: int, cause: String = "local") -> bool:
if (E.le(ratio, 0) or not E.contains([1, 2], level)):
return
return false
var held: Dictionary = target.binds.get(owner_id, {})
var rocky: Variant = 0
var changed: bool = false
for id in held.keys():
if ((not world.catalog.entities.has(id)) or E.ne(world.catalog.entities[id].group_as, "Planet")):
continue
@@ -81,6 +85,7 @@ func destroy_planets(target: Dictionary, owner_id: String, ratio: Variant, level
target.destruction_remainders[key] = 0
if E.le(destroyed, 0):
continue
changed = true
var physical: Variant = world.ledger.physical_amount(target, id)
held[id] = E.subtract(held[id], destroyed)
if E.gt(physical, 0):
@@ -91,6 +96,7 @@ func destroy_planets(target: Dictionary, owner_id: String, ratio: Variant, level
rocky = world.ledger.credit(target, "RP", rocky)
target.amount.RP = E.subtract(target.amount.RP, rocky)
held.RP = E.add(held.get("RP", 0), rocky)
return changed
func apply_blast(target: Dictionary, power: Variant, environment: Dictionary) -> void:
+6 -5
View File
@@ -16,24 +16,24 @@ func stellar_environment(source: Dictionary) -> Dictionary:
else:
mass = E.add(mass, E.multiply(quantities[id], E.maximum(0, entity.mass)))
volume += E.approx(quantities[id]) * maxf(0.0, E.approx(entity.space))
volume += E.approx(quantities[id]) * maxf(0.0, E.approx(entity.voids)) * 1e22
volume += E.approx(quantities[id]) * maxf(0.0, E.approx(entity.voids)) * E.approx(Global.ExtraParams.VoidSize)
var metallicity: Variant = 0
if E.gt(mass, 0):
metallicity = E.maximum(0, E.add(E.multiply(E.of("0.4"), E.logarithm(E.add(E.mul_div(100, source.amount.get("Met", 0), mass), E.of("0.11")))), E.of("0.88")))
var base_mass: Variant = E.multiply(65536, ((E.power(mass, E.of("0.1")) if (E.gt(mass, 0) and E.lt(mass, E.of("1.0e10"))) else ((10 if E.ge(mass, E.of("1.0e10")) else 1)))))
var base_mass: Variant = E.multiply(Global.ExtraParams.DA, ((E.power(mass, E.of("0.1")) if (E.gt(mass, 0) and E.lt(mass, E.of("1.0e10"))) else ((10 if E.ge(mass, E.of("1.0e10")) else 1)))))
if not is_finite(volume) or not is_finite(E.approx(E.add(base_mass, mass))):
# Dynamic counts may exceed the float exponent range. Evaluate the
# same geometry using logarithms, avoiding infinity / infinity.
var exact_volume: Variant = quantities.get("S", 0)
for id in quantities:
var entity: OwniverseEntity = world.catalog.entities[id]
var size: Variant = E.add(E.maximum(0, entity.space), E.multiply(E.maximum(0, entity.voids), E.of("1e22")))
var size: Variant = E.add(E.maximum(0, entity.space), E.multiply(E.maximum(0, entity.voids), Global.ExtraParams.VoidSize))
exact_volume = E.add(exact_volume, E.multiply(quantities[id], size))
var density_log: float = log(1.23456e-7) + E.approx(E.logarithm(E.add(base_mass, mass))) / 2.0 - E.approx(E.logarithm(E.maximum(1, exact_volume))) / 6.0
var density_log: float = log(E.approx(Global.ExtraParams.NPC)) + E.approx(E.logarithm(E.add(base_mass, mass))) / 2.0 - E.approx(E.logarithm(E.maximum(1, exact_volume))) / 6.0
var density: Variant = E.of("1e%d" % int(floor(density_log / log(10.0))))
density = E.multiply(density, E.coefficient(exp(density_log - floor(density_log / log(10.0)) * log(10.0))))
return {"metallicity": metallicity, "density": density, "blast": E.clamp_value(E.divide(source.amount.get("S", 0), exact_volume), 0, 1) if E.gt(exact_volume, 0) else 1}
return {"metallicity": metallicity, "density": E.coefficient(1.23456e-7 * sqrt(E.approx(E.add(base_mass, mass))) / pow(maxf(1.0, volume), 1.0 / 6.0)), "blast": E.coefficient(clampf(E.approx(source.amount.get("S", 0)) / volume, 0.0, 1.0)) if volume > 0.0 else 1}
return {"metallicity": metallicity, "density": E.coefficient(E.approx(Global.ExtraParams.NPC) * sqrt(E.approx(E.add(base_mass, mass))) / pow(maxf(1.0, volume), 1.0 / 6.0)), "blast": E.coefficient(clampf(E.approx(source.amount.get("S", 0)) / volume, 0.0, 1.0)) if volume > 0.0 else 1}
func modify_world_parameter(key: String, change: Variant) -> void:
@@ -51,3 +51,4 @@ func modify_world_parameter(key: String, change: Variant) -> void:
# withdrawal carry remain intact; already elapsed time is not replayed.
for field in ["start_year", "end_year", "processed_until"]:
if batch.has(field): batch[field] = E.add(now, E.multiply(E.maximum(0, E.subtract(batch[field], now)), ratio))
world.presentation.refresh(world.state, world.catalog)
+17 -13
View File
@@ -1,7 +1,11 @@
extends RefCounted
const E = preload("res://world/owniverse/math/exact.gd")
static var INITIAL_ENERGY = E.of("1.0e27")
static func extra_params() -> Dictionary:
return Engine.get_main_loop().root.get_node("Global").ExtraParams
static var INITIAL_ENERGY: Variant:
get: return extra_params().E
const TRENDS = ["Antitheism", "Integration", "Xenocide", "Reconstruction", "Spirituality"]
const WEIGHTS = {"m": [0, 2, 2, 0, 6], "l": [6, 1, 1, 2, 0], "w": [2, 0, 6, 0, 2], "d": [0, 6, 0, 1, 3], "c": [1, 3, 3, 3, 0], "b": [3, 0, 0, 6, 1]}
@@ -26,25 +30,25 @@ static func production(source: Dictionary, entity) -> Variant:
return effective(source, "Exp")
if E.eq(entity.group_as, "Star"):
var burn: Variant = effective(source, "Bur")
return (E.square_root(burn) if E.gt(burn, 1) else burn)
return (E.power(burn, extra_params().combustibility_bonus) if E.gt(burn, 1) else burn)
return 1
static func density_display(density: Variant) -> Dictionary:
if E.le(density, E.of("1.0e-5")):
if E.le(density, extra_params().bigrip1):
# Unity had log10(density) - 7 here; +7 maps 1e-7..1e-5 to 0..1.
return {"mode": "DensityRip", "position": E.clamp_value(E.divide((E.add(E.divide(E.logarithm(E.maximum(density, E.of("1e-7"))), E.logarithm(10)), 7)), 2), 0, 1)}
if E.ge(density, E.of("0.9")):
return {"mode": "DensityCrunch", "position": E.clamp_value(E.multiply((E.subtract(density, E.of("0.9"))), 10), 0, 1)}
return {"mode": "Density", "position": E.clamp_value(E.divide(E.logarithm(E.multiply(density, 100000)), E.logarithm(90000)), 0, 1)}
return {"mode": "DensityRip", "position": E.clamp_value(E.divide(E.logarithm(E.divide(E.maximum(density, extra_params().bigrip3), extra_params().bigrip3)), E.logarithm(E.divide(extra_params().bigrip1, extra_params().bigrip3))), 0, 1)}
if E.ge(density, extra_params().bigcrunch1):
return {"mode": "DensityCrunch", "position": E.clamp_value(E.divide(E.subtract(density, extra_params().bigcrunch1), E.subtract(extra_params().bigcrunch3, extra_params().bigcrunch1)), 0, 1)}
return {"mode": "Density", "position": E.clamp_value(E.divide(E.logarithm(E.divide(density, extra_params().bigrip1)), E.logarithm(E.divide(extra_params().bigcrunch1, extra_params().bigrip1))), 0, 1)}
## Unity ApocalypseCheck thresholds and WarningUI colors; visual warning only.
static func density_warning_color(density: Variant) -> Color:
if E.ge(density, 1): return Color.html("00c0ffff")
if E.ge(density, E.of("0.97")): return Color.html("20b0dfbf")
if E.ge(density, E.of("0.9")): return Color.html("40a0c07f")
if E.le(density, E.of("1.0e-7")): return Color.html("ff0000ff")
if E.le(density, E.of("1.0e-6")): return Color.html("df2020bf")
if E.le(density, E.of("1.0e-5")): return Color.html("c040407f")
if E.ge(density, extra_params().bigcrunch3): return Color.html("00c0ffff")
if E.ge(density, extra_params().bigcrunch2): return Color.html("20b0dfbf")
if E.ge(density, extra_params().bigcrunch1): return Color.html("40a0c07f")
if E.le(density, extra_params().bigrip3): return Color.html("ff0000ff")
if E.le(density, extra_params().bigrip2): return Color.html("df2020bf")
if E.le(density, extra_params().bigrip1): return Color.html("c040407f")
return Color(0, 0, 0, 0)
## Integrate the population present at the start of the simulation interval.