Скорость рабочих Atlants: подтверждённая арифметика
В выпуске 0.13.0 общая функция вклада рабочего заменяет прежний дробный расчёт. Она используется приказами, выполнением работ, автоматической прокладкой дороги, оценкой ИИ и подсказками. Модель native-terrain-work-v7, собственные сохранения схемы31.
Источник и способ проверки
Предоставленный Conquests/Civ3Conquests.exe, SHA256 c40583d707af7abd9b8568e2ed5a4f117f27a775dca617c8d7b873d76772dd6d. Вызов из функции оставшихся ходов 0x5c63e0 ведёт в функцию вклада 0x5b30d0. Названия структур и точка входа оставшихся ходов сопоставлены с исходником C3X и описанием структур C3CPatchFramework; решение определяется инструкциями предоставленного EXE.
verify-worker-rate.py исполняет неизменённые241 байт арифметики и исходные константы x86/x87 в Unicorn2.1.4. В памяти подготовлены поля юнита, правительства и типа; запросы промышленной черты и известной технологии возвращают управляемые входные значения. Проверены576 сочетаний, включая реальные дробные силы и пограничные float32. Хеш функции и константы независимо сверяет Python-тест с файлом EXE. Полные входы и результаты.
Это изолированная эмуляция математической функции, а не запуск Windows-партии. Она не доказывает совпадение всех фаз первого/последнего хода работы, перебора рабочих, многопользовательской игры или исходного PRNG.
Формула и округление
- Взять
GOVT.worker_rate, представленный как float32. - Для промышленной цивилизации владельца (
RACE.traits_mask & 0x20) умножить на1,5 и сохранить промежуточный float32. - Если есть хотя бы одна известная технология с
TECH.flags & 0x40000, умножить на2. Несколько технологий не складываются. - Если цивилизация происхождения юнита отличается от цивилизации владельца, умножить на0,5. Название типа и отдельный булевый признак пленного не заменяют проверку происхождения.
- Умножить на
PRTO.worker_strengthкак float32. - Усечь итог к целому и ограничить минимумом1. Округление выполняется после всех множителей.
Пример: правительство3 × промышленная черта1,5 × обычный рабочий1 =4,5 → вклад4. С технологией ×2 получается9, а не8. Иностранный при тех же условиях без технологии даёт2,25 →2. На Общине1 вклад иностранного рабочего0,5 ограничивается минимумом1. Собственный тип «Раб» не становится иностранным из-за имени.
В исходном профиле нет технологий с флагом0x40000; эффект поддержан по флагу и проверен отдельным изменённым профилем, но ни одной технологии Atlants он не приписывается по названию. Промышленные цивилизации берутся из фактического RACE.
Каждый рабочий округляется отдельно, затем вклады участников одного задания на клетке складываются. Объём задания сохраняется: TFRM.work_required_raw × max(1, TERR.movement). Срок группы — округлённое вверх оставшееся количество работы, делённое на сумму вкладов. Утратившие условия задания участники не включаются в прогноз, выбранное недоступное задание показывается приостановленным. Отдельная подсказка показывает множители каждого участника; краткая сводка сохраняет число рабочих, общую скорость и оставшиеся ходы. При изменении правительства/технологий/происхождения следующий вклад рассчитывается заново.
Сохранения и проверки
Миграция30→31 меняет только номер схемы и имя модели работы. Дробный накопленный прогресс, задания, маршруты, RNG и прочие поля не пересчитываются. Подготовлен файл действовавшей0.12.0 с двумя рабочими и прогрессом1,5; после загрузки новые вклады применяются к этому остатку. Неизвестная модель в старом или текущем файле отклоняется.
Проверки: сравнение всех576 результатов EXE с ядром, порядок округления, минимум каждого рабочего, технологический флаг и его несложение, собственное/иностранное происхождение, миграция и дальнейшая работа после загрузки. Браузер проходит старое сохранение, смешанную группу с промышленной чертой, частичную работу, перезагрузку и завершение теми же командами ядра. Итоговые отчёты: data/browser-worker-rate-verification.json, data/release-0130-validation.json.