FOnline Engine
Current 2026.1.118-dev GitHub
Документация Docs/ru/reference/changelog.md

История изменений движка

Здесь ведутся значимые для разработчиков изменения FOnline и заметки о миграции на русском и английском. Текущую версию разработки задаёт VERSION. Правила версий и выпусков определяют CalVer, даты выпусков, неизменяемые теги и границы совместимости.

Unreleased

Current - 2026-11-08

Исправлено

  • Пиксель карты, лежащий ровно на границе гекса вдали от начала координат, теперь разрешается так же, как тот же пиксель вблизи. GetHexPosCoord() округлял решёточные координаты через double, поэтому граничный пиксель в миллионах пикселей от начала мог выбрать другого соседа, чем его сдвинутая копия; это выявили карты с широкими координатами и тест GetHexPosCoord far out on a large map. Решёточные координаты, кубическое округление и проверка попадания теперь считаются точно в целых числах.

Миграция

  • Базовая версия 2026.1.117-dev → 2026.1.118-dev. Миграция проекта не требуется: контракты API, свойств, сериализации, сети и ресурсов не затрагиваются. Пиксель ровно на границе гекса может разрешиться в другую соседнюю клетку, чем раньше при округлении с плавающей точкой; теперь результат одинаков на любом расстоянии по карте. Пересоберите клиентскую и серверную роли, чтобы получить исправление.

2026.1.117-dev - 2026-11-08

Исправлено

  • Документационный тест безопасности выпуска приведён в соответствие с инициализацией настроек из нулевого профиля. ResolveSettingValue() получает режим выпечки параметром, поэтому его проверка target-директив читает !baking_mode; тест всё ещё ожидал прежнее выражение через поле и ронял задание документации на каждом коммите после 8b1a9d5547. Поведение движка не меняется.

Миграция

  • Базовая версия 2026.1.116-dev → 2026.1.117-dev. Миграция проекта не требуется: меняется только ожидание документационного теста; контракты API, свойств, сериализации, сети и ресурсов не затрагиваются.

2026.1.116-dev - 2026-11-08

Исправлено

  • Восстановлена сборка Linux-сервера. EntityManager::ReserveRegistrationId() объявлял атрибут FO_TSA_EXCLUDES(_registryLock) после завершающего возвращаемого типа, который clang не разбирает отложенно, поэтому объявленная ниже по классу блокировка считалась неизвестным идентификатором. MSVC атрибут игнорирует, из-за чего на Windows ошибка не проявлялась. Теперь у метода обычный возвращаемый тип, и атрибут разбирается после завершения класса.
  • Комментарий класса StaticMap и комментарий теста PathFindingCost сокращены до двух строк по лимиту аудита стандарта комментариев.

Миграция

  • Базовая версия 2026.1.115-dev → 2026.1.116-dev. Миграция проекта не требуется: контракты API, свойств, сериализации, сети и ресурсов не меняются; изменены форма объявления и два комментария. Проектный baseline классификации безопасности исключений по телам функций не затронут, потому что тела функций не менялись.

2026.1.115-dev - 2026-11-08

Исправлено

  • Устранено зависание всего сервера между регистрацией сущности и singleton-блокировкой Game. Раз в Server.EntityIdReserveBatch id регистрация сохраняла следующую границу LastEntityId, удерживая реестр сущностей и ожидая блокировку Game, а владелец Game.Lock(), искавший сущность, ждал реестр. Оба потока останавливались, за ними вставали все последующие обращения к свойствам Game, поиски и регистрации сущностей, и пул воркеров вместе с обработкой соединений переставал работать. Теперь новый id резервируется до захвата реестра, граница сохраняется под блокировкой Game без реестра, а FlushExactEntityId() сначала захватывает блокировку Game. Порядок покрывает ServerEntityIdReserveWaitsForGameLockOutsideRegistry.
  • Устранено зависание того же рода между соединением игрока и singleton-блокировкой Game. Player::Send_LoginSuccess() и Player::Send_InitData() удерживали соединение, пока ждали блокировку Game для кодирования глобальных значений, а поток внутри scope GameLock, записывавший публичное свойство Game или вызывавший клиента, ждал это соединение. Теперь глобальные значения кодируются до захвата соединения. Порядок покрывает PlayerGlobalVarsAreCapturedBeforeTheConnectionIsTaken.

Миграция

  • База 0d1a56de63 (2026.1.114-dev) → 2026.1.115-dev. Миграция проекта не требуется: id сущностей остаются уникальными и монотонными, граница LastEntityId по-прежнему сохраняется раньше выдачи любого id её диапазона, а сохранённые документы, ID свойств, сетевые сообщения, Managed ABI, схемы ресурсов и маркер MigrationRule Version не меняются. Server.EntityIdReserveBatch должен быть положительным: нулевое или отрицательное значение раньше сохраняло границу ниже выданного id, а теперь отклоняет первую регистрацию с новым id. Пересоберите серверную роль, чтобы получить исправление.

2026.1.114-dev - 2026-11-06

Исправлено

  • Общее core-свойство ExplicitlyPersistent теперь регистрируется и для custom-типов сущностей. Custom-типы регистрировали только CustomHolderId и CustomHolderEntry, поэтому MakePersistent() с явным запросом, включая скриптовый Entity.MakePersistent(bool), записывал флаг в следующее свойство custom-типа и падал или портил его.
  • Перегенерированы справочники API, image-format, map-format и prototype-format, чьи ссылки на исходники устарели после замены лицензионных заголовков на SPDX.

Миграция

  • База 320c982767 (2026.1.113-dev) → 2026.1.114-dev; центральный MigrationRule Version 0.0.87 → 0.0.88. Каждый custom-тип получает persistent core-свойство bool ExplicitlyPersistent сразу после CustomHolderEntry, поэтому индекс регистрации каждого следующего свойства custom-типа сдвигается на единицу. Переконфигурируйте, пересоберите все native-роли и перезапеките метаданные и скрипты вместе; смешанные сборки и наборы ресурсов отклоняются проверкой совместимости. Сохранённые документы хранят поля по именам и конвертации не требуют: отсутствующее ExplicitlyPersistent читается как false. Скрипты, вызывающие Entity.MakePersistent(bool) для custom entities, теперь работают вместо отказа. Откатывайте бинарники и ресурсы вместе.

2026.1.113-dev - 2026-11-06

Исправлено

  • Список восстановления каждого владельца равен сущностям во владении, у которых есть собственная запись: списки карты, инвентаря криттера и вложенного контейнера для предметов, Map.CritterIds для криттеров не под управлением игрока, Location.MapIds для карт и постоянные записи владельца для пользовательских сущностей. Присоединение и отсоединение постоянной сущности, включение и отключение постоянства меняют список строго; временная сущность его не затрагивает. Включение постоянства создаёт записи потомков раньше записи владельца, а отключение удаляет запись владельца раньше записей потомков, поэтому прерванное изменение оставляет записи без ссылок, а не ссылки на отсутствующие записи.
  • Доступ к владельцу списка восстановления сущности проверяется до изменения флагов, хранилища и списка восстановления. Отказ обоих направлений проверен с двумя рабочими потоками; предметы, криттеры, карты и пользовательские сущности проходят настоящие удаление, уничтожение и выгрузку/загрузку.

Миграция

  • База 8b32281d50 (2026.1.112-dev) → 2026.1.113-dev. Аргумент и смысл MakePersistent(bool) сохранены. Перед вызовом покройте сущность и владельца её списка восстановления по полному native-графу: непосредственного владельца предмета, карту криттера не под управлением игрока, локацию карты и владельца пользовательской сущности. Проверьте вызовы, меняющие постоянство сущностей во владении, до внедрения. Без покрытия владельца Entity access without sync возникает до мутации. Native-вызывающим нужно то же покрытие.
  • Пересоберите согласованные server/baker и native-потребителей, обновите справочник API и перезапеките скрипты проекта. ID свойств, объявленные документы, сетевые сообщения, маркер MigrationRule Version, Managed ABI и схемы ресурсов прежние. Свойства только для чтения Map.ItemIds, Critter.ItemIds, Item.InnerItemIds, Map.CritterIds, Location.MapIds и <Entry>Ids постоянных записей владельца больше не перечисляют временные сущности, в том числе у временных владельцев; читайте сущности во владении через runtime-методы вроде Map.GetItems(), Critter.GetItems() или Location.GetMaps(). Поиск: rg -n 'ItemIds|CritterIds|MapIds|InnerItemIds' <project-source-dirs>. Прежние отсутствующие записи остаются ошибками загрузки; автоматической очистки и починки нет. Сохраните согласованные бинарники/хранилище и проверяйте прежние несогласованные данные изолированным восстановлением. Откат использует предыдущие согласованные бинарники/данные без новой конвертации.

2026.1.112-dev - 2026-11-06

Исправлено

  • Плоские спрайты карты упорядочиваются по sub-layer раньше ряда. У плоского спрайта нет ground depth, поэтому ниже DrawOrderType::NormalBegin ключ порядка рисования теперь [group 6][sub-layer 8][gap 4][hex Y 24][hex X 22]: Item.DrawOrderSubLayer — слой рисования, который старше ряда гексов, а ряд и X упорядочивают только спрайты одного sub-layer. Раньше плоская декаль на более позднем ряду перекрывала плоскую метку с большим sub-layer на более раннем ряду, и декали земли проступали сквозь полосу метки везде, где их гекс шёл в порядке после клетки полосы. Ключ стоящих спрайтов не изменился. Test_MapSprite.cpp закрепляет оба порядка.

Миграция

  • Базовая ревизия 6ea95ac28d (2026.1.111-dev) → 2026.1.112-dev. Миграция исходников проекта, генерируемых моделей и сохранённых данных не требуется; хранимые свойства, сетевой протокол, MigrationRule Version, Managed ABI и схемы ресурсов не меняются. Нужна пересборка клиента и Mapper; выпечка требуется только чтобы применить контент проекта, который теперь опирается на этот порядок. Плоские спрайты с разными sub-layer могут рисоваться в ином порядке, чем раньше: плоский спрайт с большим DrawOrderSubLayer теперь перекрывает меньший на любом ряду, а прежде — только на том же ряду. Спрайты с равным sub-layer сохраняют порядок «ряд, затем X». Проверьте плоские декали с ненулевым sub-layer (например плоский переносимый предмет с +1).

2026.1.111-dev - 2026-11-06

Исправлено

  • Depth сцены карты отсчитывается от верхней строки пикселей вида, а не от абсолютной глубины карты. GeometryHelper::GetHexMapDepth(rawHex, hexOffset, elevation, originY) даёт depth спрайта относительно этой строки с разностью строк в целых числах, SpriteManager::DrawSprites принимает строку начала отсчёта, а MapView::DrawMap задаёт ortho depth range каждый кадр по виду, а не по углам карты. Вдали от начала карты размером с континент depth в миллионы округляли смещение слоёв и наклон depth стоящих спрайтов, и direct-draw модели и частицы мерцали на стенах; теперь depth сохраняют точность маленькой карты.
  • GeometryHelper::GetHexPosCoord переводит пиксели экрана и карты в клетки точно: квадратная геометрия решает свою ромбическую решётку в целых числах, поэтому пиксель на краю клетки округляется одинаково в любом месте карты, а гексагональная геометрия находит координаты решётки во float64_t. Пиксели в миллионах от начала большой карты больше не попадают у краёв в соседнюю клетку.
  • GeometryHelper::GetLineDirAngle берёт разность векторов в целых числах до масштабирования, поэтому короткий вектор между далёкими позициями карты сохраняет свой угол.
  • Смещение сегмента MovingContext возводится в квадрат во float64_t; сегмент длиннее примерно 46 000 пикселей раньше переполнял int32.
  • MapView::TraceLightLine трассирует лучи света по номеру шага относительно гекса источника, поэтому лучи заканчиваются на тех же клетках, где бы ни стоял свет; накопитель float раньше уходил далеко на большой карте на величину до пятой части гекса.
  • Прокрутка клиента ограничивается областью прокрутки по целочисленным краям относительно вида, поэтому камера далеко на большой карте больше не дрожит у границы области на величину до половины пикселя.
  • Поворот тела ModelInstance остаётся в пределах одного оборота: завершённый поворот попадает точно в цель, а не добавляет 360 градусов за каждый круг.
  • Полёт предмета заканчивается в начальном смещении плюс пройденное направление (ItemHexView); раньше конечная точка умножала начальное смещение на расстояние.
  • Map.GetHexScreenPosF для гексов далеко от вида считается во float64_t до сужения экранного результата, а последний шаг симуляции границ SPARK определяется по номеру шага, а не по накопителю float.

Миграция

  • Базовая ревизия b055b5da22 (2026.1.110-dev) → 2026.1.111-dev. API, настройки, сетевой протокол, MigrationRule Version, Managed ABI, сохранённые данные и схемы ресурсов не меняются. Пересоберите все нативные роли. Нативный код, вызывающий SpriteManager::DrawSprites, передаёт строку начала отсчёта depth после области отрисовки (MapView::GetMapDepthOriginY() для вида карты). Пиксель точно на краю клетки, луч света около ничьей в полгекса и эффект SPARK, чья длительность симуляции попадает на границу шага, могут разрешиться иначе, чем раньше; перепеките ресурсы, чтобы обновить границы частиц.

2026.1.110-dev - 2026-11-06

Изменено

  • Тесты больших карт собираются с 16-битными координатами карты: TraceIsTheSameAnywhereOnTheMap, VeryLongTracesReachTheirTargetAndStayInvariant, VeryLongSquareTracesFollowTheExactLine и PathFinding::RoutesMatchOnContinentSizedMaps больше не подставляют в размер карты литерал за пределами диапазона mcoord_t в пропускаемой ветке широких координат, поэтому LF_UnitTests компилируется без FO_MAP_WIDE_COORDS.
  • Ожидающее чтение запечённой карты в серверном кэше статических карт определяется по общему обещанию, а не по целому значению его адреса. Поведение не меняется.

Миграция

  • Базовая ревизия 9e096e8f6f (2026.1.109-dev) → 2026.1.110-dev. Меняются только тесты и внутренний токен кэша: настройки, API скриптов, сетевой протокол, маркер MigrationRule Version, Managed ABI, сохранённые данные и схемы ресурсов не затронуты, поэтому миграция проекта не требуется. Проекты с 16-битными координатами карты (FO_MAP_WIDE_COORDS выключен) собирают тесты 2026.1.109-dev только с этим шагом; пересоберите все native-роли и тесты.

2026.1.109-dev - 2026-11-05

Изменено

  • Блоки ChunkedTwoDimensionalGrid индексируются двухуровневой таблицей: верхний уровень хранит по одному владельцу на 32x32 слота блоков, а таблица слотов выделяется при первой записи внутри неё. Сетка максимального размера карты больше не выделяет индекс блоков размером с карту (512 МБ для 128 000 ячеек по стороне при блоках по 16 ячеек). Адреса полей, чтение пустых ячеек и семантика изменения размера не меняются.
  • Применённый свет каждого поля клиентской карты хранится в MapView::Field::Light вместо плотного буфера цветов на всю карту. MapView::SetupSpriteLight(mspr, corner) находит гекс спрайта и соседей по углу и записывает эти поля; MapSprite::SetLight теперь принимает три готовых указателя на свет. Resize в Mapper не требует прохода по свету каждой ячейки.
  • Группы крыш на клиенте нумеруются по отслеживаемому множеству полей с крышами в прежнем порядке (сначала x, затем y); у карты без осевой области прокрутки очищаются только ранее заблокированные поля; представления за пределами нового размера карты удаляются по спискам представлений. Номера групп и заблокированные ячейки не меняются.
  • Индекс блоков поиска пути занимает окно вокруг старта, которое допускает ограничение длины (MaxLength плюс контур мультигекса и кольцо цели, с обрезкой по карте), а не всю карту, поэтому поиск на карте размером с континент стоит столько же, сколько на маленькой; пробник замкнутости отдельно учитывает гексы, которые он заливает за пределами окна. Маршруты не меняются.
  • Запечённое серверное содержимое proto-карты читается при первой надобности, а не при старте сервера. MapManager::LoadFromResources() только проверяет, что у каждого .fomap-bin-server есть proto-карта; MapManager::GetStaticMap() читает содержимое при первом использовании (экземпляр карты, Map.LoadRuntimeStaticItems, Map.GenerateContent или Game.GetStaticItemsForProtoMap) и кэширует его; одновременные первые запросы одной карты используют одно чтение. Повреждённый или отсутствующий файл карты сообщается в этот момент как MapManagerException, а не срывает старт.
  • LineTracer трассирует линию во float64_t относительно её стартового гекса, в квадратной геометрии берёт каждую позицию из номера шага, а не из суммы шагов, а форма с углом и расстоянием пускает луч из гекса в начале карты с той же чётностью столбца, что у старта. Округление больше не зависит ни от того, где на карте лежит линия, ни от её длины: линия далеко на карте размером с континент проходит те же шаги, что и та же линия у начала координат, а квадратная линия длиной в десятки тысяч клеток остаётся на клетках, ближайших к её точному ходу. Раньше маршрут FreeMovement, выпрямляемый около координаты 120 000, мог уходить на долю гекса. В любом месте карты выпрямленный маршрут теперь может выбрать другой из двух почти равных гексов; результаты, достижимость и длины маршрутов поиска пути в остальном не меняются.

Добавлено

  • Добавлены математические константы float64_t SQRT3_FLOAT64, SQRT3_X2_FLOAT64, RAD_TO_DEG_FLOAT64 и DEG_TO_RAD_FLOAT64 рядом с их аналогами float32_t в BasicCore.h, а также wrap_angle(angle) в SafeArithmetics.h: он сворачивает угол в градусах любого вещественного типа целыми оборотами в [0, 360] (отрицательный целый оборот даёт 360).
  • Добавлен TwoDimensionalGrid::ClearArea(origin, size), реализованный статической, чанковой и динамической сетками. Он сбрасывает все ячейки обрезанного прямоугольника; сетка чанков освобождает полностью покрытые блоки и опустевшие таблицы слотов. ChunkedTwoDimensionalGrid::GetAllocatedChunkCount() сообщает число выделенных блоков.
  • Добавлена загрузка содержимого других карт в экземпляр карты во время работы. Серверный и клиентский Map.LoadRuntimeStaticItems(mapPid, destHex, idOffset) копируют статические предметы proto-карты mapPid в карту как статические предметы времени выполнения так, что первый гекс источника попадает в destHex, и возвращают идентификаторы копий, каждый из которых — запечённый идентификатор плюс idOffset (перегрузка с sourceHex и sourceSize перед idOffset копирует только предметы этой области, и её первый гекс попадает в destHex); идентификатор, который переполняется, равен нулю, повторяется или уже занят на карте, отклоняет всю загрузку; Map.UnloadRuntimeStaticItems(runtimeStaticItemIds) удаляет их, а клиент освобождает оставшиеся пустыми блоки полей. Серверный Map.GenerateContent(mapPid, destHex) создаёт криттеров и динамические предметы proto-карты как сущности карты и возвращает их идентификаторы. Статические предметы времени выполнения участвуют во всех статических запросах, блокировке и триггерах наравне с запечёнными, не сохраняются и не могут попасть в RemovedStaticItemIds. Серверные Game.LoadStaticMap(mapPid, asyncLoad) и Game.LoadStaticMaps(mapPids, asyncLoad) заранее читают содержимое одной или нескольких proto-карт в вызывающем потоке или в рабочих потоках со сразу возвращающимся вызовом, Game.UnloadStaticMap(mapPid) освобождает его, когда ни один экземпляр карты его не использует, а Game.IsStaticMapLoaded(mapPid) сообщает о завершённом чтении.

Миграция

  • Базовая ревизия 90061a40d4 (2026.1.108-dev) → 2026.1.109-dev; возвращается работа по большим картам, откаченная в 2026.1.103-dev. Настройки, сетевой протокол, маркер MigrationRule Version, Managed ABI, сохранённые данные и схемы ресурсов не меняются; конвертация контента и сохранений не требуется. Скриптовый API только получает перечисленные выше методы. Пересоберите все нативные роли (Server, Client, Mapper, Baker и тесты) и перегенерируйте оба скриптовых бэкенда, потому что меняются шаблон сетки и раскладки MapView и Map. StaticMap::ApplyItemToField() становится приватным членом, StaticMap::MergeFieldInto(hex, field) добавляет предметы карты на гексе в другое поле, а StaticMap::BuildFieldWithout() больше не const, потому что оба отдают предметы карты как изменяемые.
  • Запечённые карты больше не читаются при старте: первый экземпляр карты читает свой файл в создающем потоке, а ошибка в карте, которую никто не создаёт, остаётся незамеченной. Проект, полагавшийся на проверку всех запечённых карт при старте, может вызвать Game.LoadStaticMap(mapPid, false) для каждой из них в отдельной проверке. Нативный код, вызывавший MapManager::GetStaticMap() для отсутствующего файла, раньше получал проваленный поиск, теперь — MapManagerException.
  • Нативный код: замените mspr->SetLight(corner, map->GetLightData(), map->GetSize()) на map->SetupSpriteLight(mspr, corner); MapView::GetLightData() удалён, и прежний вызов плотного буфера больше не компилируется. Найдите вызовы через rg -n "GetLightData|SetLight\(" SourceExt (или нативные корни проекта). Собственный наследник TwoDimensionalGrid должен реализовать ClearArea; чисто виртуальный метод сообщит об отсутствующем переопределении при компиляции.
  • Владельцы приёмки: случаи TwoDimensionalGrid (индекс размером с континент, освобождение области, ограниченные циклы загрузки/выгрузки, ClearArea динамической и статической сеток), ClientMaximumSizeMapLoadsWithoutMapSizedWork, PathFinding::RoutesMatchOnContinentSizedMaps, MapLoadsAndUnloadsContentOfOtherMaps, ClientMapLoadsAndUnloadsStaticItemsOfOtherMaps и существующие случаи статических карт, удаления, крыш, света, прокрутки и hit-test.

2026.1.108-dev - 2026-11-05

Изменено

  • Исправлены тестовые фикстуры для чистых настроек metadata, монтирования ресурсов packaged viewer и переводов строк встроенного профиля в Windows и Linux.

Миграция

  • Миграция проекта не требуется: изменения затрагивают только тесты и сохраняют runtime, resource, ABI и сетевые контракты.

2026.1.107-dev - 2026-11-05

Изменено

  • Отделены начальные SetupConfigAtPath, SetupInternalConfig, SetupResourceConfig и SetupDefaultSettings от частичных Apply* overlays. Каждый setup требует чистого нулевого snapshot; повторный/смешанный setup отвергается до изменения, ошибка file/profile setup допускает повтор. Успешный setup не добавляет clear/default-проход.
  • Packaged marker закрыт в application initialization. Runtime читает режим и identity из settings; C++ pack mounts получают явный режим первым аргументом, auto settings — runtime identity. Форматы config/metadata не меняются.
  • После обновления ресурсного конфига перезапуск требуется только при изменении итоговых движковых настроек или объявлений пакетов. Игровые/custom значения, удалённые настройки и typed caches обновляются до создания ClientEngine; приоритет local/CLI/auto и storage native-полей сохраняются.
  • Адресный отказ для прежних Baking.ResourcesDir, Baking.CacheResources, Baking.PlatformBinaries, Baking.ClientResources и Baking.ServerResources отмечен FO_TEMPORARY_COMPAT(RetiredBakingDirectorySettings, "2026-12-31") в реализации и проверках отказа. Маркер задаёт срок удаления этой диагностики и не добавляет runtime-работы или aliases старых имён.
  • Упаковщик переносит строку Common.ResourcesPath главной секции в первую строку каждого встроенного профиля, чтобы bootstrap находил её сразу. Значение и порядок остальных строк сохраняются; полные ресурсные профили и исходные baked-файлы не меняются.
  • Игровые interthread-клиенты запрашивают common resource descriptor своей общей раздачи; updater-соединения и сетевые игровые клиенты сохраняют выбор platform-specific payload. Проверки хешей и metadata остаются строгими.
  • Разделены полные ресурсные профили (.fomain-server/client) и встроенные профили движка/bootstrap (.fomain-embedded-server/client). Executables и updater runtime modules получают embedded-профиль; загрузка ресурсов и настройки упаковки используют полный профиль. Для упаковки нужны оба выхода.
  • Запуск применяет один полный профиль на нулевой объект: ресурсный при наличии, иначе бинарный. Bootstrap сканирует только зашитую Common.ResourcesPath; невыбранный профиль не разбирается и не применяется. Unpackaged-запуск применяет авторские config/sub-config без reference defaults. Local preferences, CLI и auto сохраняют порядок; CLI и auto вызываются по одному разу. Packaged sub-config сообщает FO_VERIFY_AND_CONTINUE.
  • Config/ClientConfig bakers опускают типизированные нули и сохраняют все ненулевые объявленные game values. Resource config инициализирует чистые settings до overlays; повторные или неверные вызовы запрещены, debug полностью проверяет нулевые поля. Флаг чистоты и replacement copy/allocation успешной загрузки удалены; неудачный частичный Apply восстанавливает нулевой snapshot. Обычные Apply сохраняют overlay-семантику. Updater сравнивает исходный текст до валидации, проверяет изменённый профиль один раз и переносит preferences перед restart при смене cache path.
  • Вместо Baking.ServerResources / Baking.ClientResources используется runtime-настройка Common.ResourcesPath=Resources. Server package хранит собственные паки в корне, клиентскую раздачу — в Client. CLI overrides и Android APK asset URI сохраняются. CMake-параметров каталога ресурсов нет.
  • Metadata Setting содержит только имя/тип; удалены initial-value storage и применение в BaseEngine. Проверка полноты авторских значений сохраняется, включая явно пустые значения. Metadata file version повышена с 5 до 6.
  • Резерв встроенного конфига увеличен с 20000 до 40000 байт; packager проверяет реальную ёмкость каждого бинарника.

Миграция

  • Переименуйте C++ ApplyConfigAtPath, ApplyInternalConfig, ApplyResourceConfig и ApplyDefaultSettings в соответствующие Setup*. Выбирайте один базовый источник до overlays; ApplyConfigFile остаётся для preferences и частичного ввода. Fixtures, читавшие root поверх defaults, должны сразу создаваться из root. Состояние полноты различает fresh/initialized/complete при прежнем смысле HasCompleteConfig. Пересоберите native consumers; смена API не добавляет metadata/serialized/network migration.
  • Основной загрузчик использует существующий StandaloneClient для клиентских writable overlays; server/tool profiles читаются из base packs. Packaged embedded-клоны указывают на дочерний Client серверной раздачи. Диапазоны game integers и разрешение enum проверяются до фильтрации нулей.
  • Baked-профили содержат комментарий native-совместимости. После native-first restart standalone-клиент откладывает прежние/несовместимые optional profiles и применяет embedded fallback с engine/bootstrap-настройками без разбора старых ключей; следующая синхронизация устанавливает соответствующий профиль. Aliases прежних имён и дополнительных Apply нет. При первом внедрении сохраните расположение кэша либо явно перенесите preferences до native-only перехода.
  • Перенесите настройки каталогов в Common: Common.ResourcesPath, Common.CachePath (прежняя Baking.CacheResources) и Common.PlatformBinariesPath. Обновите авторские конфиги, generated/native readers, упаковку и CLI flags; прежние Baking keys отвергаются.
  • База 3d56c1f3f9 (2026.1.106-dev) → 2026.1.107-dev; центральный MigrationRule Version 0.0.86 → 0.0.87. Повторите configure, пересоберите все native-роли/client runtime libraries, выполните один rebake metadata/config/scripts и переупакуйте все поставляемые targets. Metadata v5/трёхколоночный Setting отвергается. Конверсия persisted entities/properties не нужна; Managed ABI остаётся 9.
  • Замените обе старые настройки и native/generated/CLI consumers на Common.ResourcesPath. Создайте серверную поставку заново: <ResourcesPath>/ и <ResourcesPath>/Client/; обновляйте deployment/smoke paths совместно из одного bake. Content Showcase сохраняет Resources-Baked в авторском конфиге. Для rollback храните согласованный прежний native/resource комплект.
  • Resource reader получает ReadResourceConfig(const FileSystem& metadata, bool required). Caller монтирует Metadata view перед чтением. ApplicationInit сканирует каноническую строку embedded ResourcesPath перед поиском ресурсов; ResourceApply не читает binary. При переносе каталога обновите встроенный locator либо задайте CLI override. Выбранный профиль владеет всеми значениями, включая прежние metadata values.
  • Задавайте все обязательные настройки, включая намеренные нули; фильтруйте только baked profiles. Строки 0/false, непустые массивы и runtime directives сохраняют смысл. BootstrapGameSettings выбирает единственные игровые значения, включаемые в embedded config. Обновите fixtures, ожидающие неявные unpackaged defaults или metadata values; явные defaults применяйте только при необходимости fixture.
  • Поставляйте совместимый native runtime до zero-based ресурсов. Native promotion/restart предшествует resource synchronization/restart; платформам без native self-update нужен новый bundle. Не выдавайте эти профили runtime, восстанавливающему defaults или metadata baseline. Offline-смена cache path требует явного переноса preferences; live updater сохраняет существующий destination.

2026.1.106-dev - 2026-11-04

Исправлено

  • Тест переводов генерируемых описаний согласован с существующим описанием Game.SimulateTouchScroll: 5003 переведённые записи в девятнадцати доменах, включая 2596 описаний API. Строгие проверки полноты, стабильных locator и отсутствующих переводов сохранены.

Миграция

  • Базовая ревизия 4375450b39 (2026.1.105-dev) → 2026.1.106-dev. Миграция исходников проекта, контента, генерируемых моделей и сохранённых данных не требуется: обновление меняет только устаревшие ожидания теста и заметки о выпуске. Переведённое описание уже существует в source-owned каталоге. Runtime-декларации, существующие значения, владение, сетевой протокол, MigrationRule Version, Managed ABI и схемы ресурсов остаются прежними; дополнительной границы пересборки или выпечки нет.

2026.1.105-dev - 2026-11-04

Исправлено

  • Изолированная фикстура coverage-companion загружает настоящие обёртки команд CMake перед стадией Applications. AppendSourceProperty теперь имеет ту же реализацию, что при обычной конфигурации; проверки повторного использования библиотек, профилей quick exit и instrumentation помощника хеширования пакетов ресурсов сохранены.

Миграция

  • Базовая ревизия 28b3a9b22a (2026.1.104-dev) → 2026.1.105-dev. Миграция исходников проекта, контента, генерируемого API и сохранённых данных не требуется: меняются только тестовая фикстура и её документация. Production-поведение CMake, runtime-декларации, существующие значения, владение, сетевой протокол, MigrationRule Version, Managed ABI и схемы ресурсов остаются прежними. Выполните python -m pytest BuildTools/tests/test_codecoverage_llvm_objects.py; пять конфигураций платформ упражняют настоящую стадию CMake на хосте и не подтверждают runtime другой платформы. Дополнительной границы пересборки или выпечки нет.

2026.1.104-dev - 2026-11-04

Исправлено

  • Фиксированные ожидания API-теста согласованы с существующим экспортом Game.SimulateTouchScroll: 2593 source-owned символа, включая 2592 experimental и один internal. Независимая сверка inventory исходников и модели сохранена.

Миграция

  • Базовая ревизия 0bd0702354 (2026.1.103-dev) → 2026.1.104-dev. Миграция исходников проекта, контента и сохранённых данных не требуется: обновление меняет только ожидания теста и заметки о выпуске. Runtime-декларации, генерируемые модели API, значения по умолчанию, единицы, идентификаторы, владение, сетевой протокол, MigrationRule Version, Managed ABI и схемы ресурсов остаются прежними; дополнительной границы пересборки или выпечки нет. Миграции предыдущих обновлений по-прежнему выполняются по порядку.

2026.1.103-dev - 2026-11-04

Изменено

  • Откачена интеграция больших карт, опубликованная как 2026.1.102-dev (82ac7d57fe..72c1be91a0): она попала в master без ревью и возвращается pull request’ом. Исходники, скрипты, сгенерированные модели и документация снова соответствуют 2026.1.101-dev.

Миграция

  • Базовая ревизия 72c1be91a0 (2026.1.102-dev) → 2026.1.103-dev. Код, собранный на 2026.1.102-dev и использующий Map.LoadStaticItems, Map.UnloadStaticItems, Map.GenerateContent, Game.LoadStaticMap, Game.LoadStaticMapsAsync, Game.IsStaticMapLoaded, Game.UnloadStaticMap, Game.OnGenerateStaticItemIds, TwoDimensionalGrid::ClearArea или MapView::SetupSpriteLight, не компилируется до принятия pull request; заметки 2026.1.101-dev действуют без изменений. Пересоберите все нативные роли, перегенерируйте оба скриптовых бэкенда и перепеките ресурсы вместе; MigrationRule Version остаётся 0.0.86, Managed ABI — 9.

2026.1.102-dev - 2026-11-04

Изменено

  • Блоки ChunkedTwoDimensionalGrid индексируются двухуровневой таблицей: верхний уровень хранит по одному владельцу на 32x32 слота блоков, а таблица слотов выделяется при первой записи внутри неё. Сетка максимального размера карты больше не выделяет индекс блоков размером с карту (512 МБ для 128 000 ячеек по стороне при блоках по 16 ячеек). Адреса полей, чтение пустых ячеек и семантика изменения размера не меняются.
  • Применённый свет каждого поля клиентской карты хранится в MapView::Field::Light вместо плотного буфера цветов на всю карту. MapView::SetupSpriteLight(mspr, corner) находит гекс спрайта и соседей по углу и записывает эти поля; MapSprite::SetLight теперь принимает три готовых указателя на свет. Resize в Mapper не требует прохода по свету каждой ячейки.
  • Группы крыш на клиенте нумеруются по отслеживаемому множеству полей с крышами в прежнем порядке (сначала x, затем y); у карты без осевой области прокрутки очищаются только ранее заблокированные поля; представления за пределами нового размера карты удаляются по спискам представлений. Номера групп и заблокированные ячейки не меняются.
  • Если у карты больше 65 536 блоков поиска, поиск пути индексирует блоки через хеш-таблицу вместо индекса размером с карту на каждый поиск. Меньшие карты сохраняют плотный индекс; маршруты не меняются.
  • Запечённое серверное содержимое proto-карты читается при первой надобности, а не при старте сервера. MapManager::LoadFromResources() только проверяет, что у каждого .fomap-bin-server есть proto-карта; MapManager::GetStaticMap() читает содержимое при первом использовании (экземпляр карты, Map.LoadStaticItems, Map.GenerateContent или Game.GetStaticItemsForProtoMap) и кэширует его; одновременные первые запросы одной карты используют одно чтение. Повреждённый или отсутствующий файл карты сообщается в этот момент как MapManagerException, а не срывает старт.

Добавлено

  • Добавлен TwoDimensionalGrid::ClearArea(origin, size), реализованный статической, чанковой и динамической сетками. Он сбрасывает все ячейки обрезанного прямоугольника; сетка чанков освобождает полностью покрытые блоки и опустевшие таблицы слотов. ChunkedTwoDimensionalGrid::GetAllocatedChunkCount() сообщает число выделенных блоков.
  • Добавлена загрузка содержимого других карт в экземпляр карты во время работы. Серверный и клиентский Map.LoadStaticItems(mapPid, offset) копируют статические предметы proto-карты mapPid со сдвигом гексов на offset и возвращают идентификаторы копий (перегрузка с sourceHex и sourceSize копирует только предметы этой области, и её первый гекс попадает в offset), которые выбирают обработчики нового серверного и клиентского события Game.OnGenerateStaticItemIds(map, mapPid, offset, itemIds); Map.UnloadStaticItems(ids) удаляет их, а клиент освобождает оставшиеся пустыми блоки полей. Серверный Map.GenerateContent(mapPid, offset) создаёт криттеров и динамические предметы proto-карты как сущности карты и возвращает их идентификаторы. Загруженные статические предметы участвуют во всех статических запросах, блокировке и триггерах наравне с запечёнными, не сохраняются и не могут попасть в RemovedStaticItemIds. Серверные Game.LoadStaticMap(mapPid) и Game.UnloadStaticMap(mapPid) заранее читают содержимое proto-карты и освобождают его, когда ни один экземпляр карты его не использует; Game.LoadStaticMapsAsync(mapPids) читает несколько карт в рабочих потоках и сразу возвращается, а Game.IsStaticMapLoaded(mapPid) сообщает о завершённом чтении.

Миграция

  • Базовая ревизия 20998dd3e8 (2026.1.101-dev) → 2026.1.102-dev. Настройки, сетевой протокол, маркер MigrationRule Version, Managed ABI, сохранённые данные и схемы ресурсов не меняются; конвертация контента и сохранений не требуется. Скриптовый API только получает перечисленные выше методы и событие. Пересоберите все нативные роли (Server, Client, Mapper, Baker и тесты) и перегенерируйте оба скриптовых бэкенда, потому что меняются шаблон сетки, раскладки MapView и Map и список событий.
  • Запечённые карты больше не читаются при старте: первый экземпляр карты читает свой файл в создающем потоке, а ошибка в карте, которую никто не создаёт, остаётся незамеченной. Проект, полагавшийся на проверку всех запечённых карт при старте, может вызвать Game.LoadStaticMap(mapPid) для каждой из них в отдельной проверке. Нативный код, вызывавший MapManager::GetStaticMap() для отсутствующего файла, раньше получал проваленный поиск, теперь — MapManagerException.
  • Нативный код: замените mspr->SetLight(corner, map->GetLightData(), map->GetSize()) на map->SetupSpriteLight(mspr, corner); MapView::GetLightData() удалён, и прежний вызов плотного буфера больше не компилируется. Найдите вызовы через rg -n "GetLightData|SetLight\(" SourceExt (или нативные корни проекта). Собственный наследник TwoDimensionalGrid должен реализовать ClearArea; чисто виртуальный метод сообщит об отсутствующем переопределении при компиляции.
  • Владельцы приёмки: случаи TwoDimensionalGrid (индекс размером с континент, освобождение области, ограниченные циклы загрузки/выгрузки, ClearArea динамической и статической сеток), ClientMaximumSizeMapLoadsWithoutMapSizedWork, PathFinding::RoutesMatchOnContinentSizedMaps, MapLoadsAndUnloadsContentOfOtherMaps, ClientMapLoadsAndUnloadsStaticItemsOfOtherMaps и существующие случаи статических карт, удаления, крыш, света, прокрутки и hit-test.

2026.1.101-dev - 2026-11-03

Исправлено

  • Последовательности направлений native-импорта изображений хранятся в Engine array, устраняющем аварийное завершение GCC 13.3 при агрегатной инициализации FOFRM/FRM и их потребителей Baker/Mapper. Сохранены семь дополнительных направлений, пустые начальные значения, порядок, данные кадров и сериализация SpriteResource v3.
  • Фабрика сервера fixture updater квалифицирована, чтобы обычная и unity-сборки native-тестов выбирали одни и те же ресурсы интеграции.

Добавлено

  • Game.SimulateTouchScroll(pos, offsetPos) передаёт агрегированный жест прокрутки через обычный путь клиентского ввода, обновляя MousePos и отправляя OnTouchScroll со знаковыми координатами в пикселях. Операция доступна скриптам Client/Mapper в обоих backend; встроенные события движка сохраняют скриптовую поверхность только для подписки.

Миграция

  • База 1ad91af9998feab93c63d6abc9932bcc4db21fdc (2026.1.100-dev); новая версия 2026.1.101-dev. Тип native-поля ImageImport::FrameCollection::Dirs заменён с FrameSequence[MAX_DIRS_MINUS_ONE] на array<FrameSequence, MAX_DIRS_MINUS_ONE>. Main остаётся нулевым направлением; семь дополнительных последовательностей сохраняют порядок, независимые длительности, движение/привязку, индексы общих кадров, владение при copy/move и пустое начальное состояние. Миграция хранилища направлений не меняет скриптовые API и авторские assets. Добавление симуляции прокрутки расширяет source-owned API inventory; перегенерируйте bindings и метаданные вместе с обоими скриптовыми backend.
  • Найдите в собственных native-loader FrameCollection, .Dirs, ссылки на C-массив и неявные преобразования в указатель. Сохраните обход диапазона и доступ к элементам; для знакового ненулевого направления используйте collection.Dirs[numeric_cast<size_t>(direction - 1)]. Замените FrameSequence* first = collection.Dirs; на span с размером, где возможно, либо на FrameSequence* first {collection.Dirs.data()}; только на конечной границе внешнего API. Перегрузка только для C-массива и старое неявное преобразование в указатель теперь не компилируются; совместимого преобразования нет. Перекомпилируйте собственные loader с выбранными заголовками, включая подключаемые через ImageBaker::AddLoader.
  • Переконфигурируйте и пересоберите Baker, Mapper, native-тесты и затронутые расширения, перегенерируйте метаданные, затем запеките единый согласованный набор ресурсов клиента и сервера перед упаковкой. Layout native-записи зависит от ревизии: пересоберите бинарные расширения и заменяйте их вместе с host. Преобразование сохранений, переименование свойств/идентичностей, смена сетевого протокола, повышение маркера Managed ABI и смена схемы SpriteResource не требуются; MigrationRule Version остаётся 0.0.86, Managed ABI — 9, контейнер изображений — v3. С добавлением меняются генерируемый dense inventory методов и хеш содержимого ABI; метаданные, bindings и сборки должны происходить из одного bake. Сохраните резервную копию исполняемых файлов и ресурсов и откатывайте их вместе.
  • Проверьте затронутые Fofrm/Frm translation units GCC 13.3, native-случаи импорта/преобразований/зависимостей изображений и неверных loader, затем обычные/unity native-тесты и bake встраиваемого проекта. Проверки компилятора не подтверждают runtime другой платформы и видимую приёмку проекта.

2026.1.100-dev - 2026-11-03

Исправлено

  • Native guard сетевых буферов создаются непосредственно, чтобы Clang Thread Safety Analysis связывал инициализацию фигурными скобками с захватом блокировки. Сохраняются ID сообщений, операции с данными, явные unlock/relock и прежнее время жизни именованного либо временного объекта полного выражения.
  • Scoped lock DNS-поиска объявляется непосредственно для сборок с аннотированной libc++. В двух AngelScript test helpers явно указан локальный тип data_writer; после исправления include форматтера обновлены генерируемые ссылки API на строки исходников.
  • Для слотов кадров Vulkan используется Engine array, устраняющий аварийное завершение GCC 13.3 при создании агрегатного контекста рендерера. Число слотов, начальное состояние и циклическая индексация сохраняются. В native-тестах логирования завершена инициализация платформенного пути пустого журнала фигурными скобками.
  • Отдельное присваивание результата try-lock сохраняет связь захвата в анализаторе Clang для тестов синхронизации. Fixture отказа updater повреждает файл на месте, чтобы закреплённый reader получил изменённые байты; атомарная публикация корректно сохраняет снимок уже открытого reader.

Миграция

  • База 9d838ea0ab99895e2063da56fa128e3a36258546 (2026.1.99-dev); новая версия 2026.1.100-dev. API не добавляются и не удаляются; преобразование сохранений не требуется. Содержимое буферов, ID сообщений, владение и поведение при раскрутке стека сохраняются; сетевой протокол, MigrationRule Version 0.0.86, Managed ABI 9 и схемы ресурсов не меняются.
  • В native-потребителях с guard из результата фабрики внутри фигурных скобок замените auto output {connection->WriteMsg(message)}; на ServerConnection::OutBufAccessor output {connection, message};, auto output {connection->WriteBuf()}; на ServerConnection::OutBufAccessor output {connection, std::nullopt};, а auto input {connection->ReadBuf()}; на ServerConnection::InBufAccessor input {connection};. Эти существующие конструкторы и фабрики остаются доступны. Непосредственное создание устраняет диагностику Clang об освобождении незахваченной блокировки; подавлять её не следует. Для receiver-ссылки используйте make_ptr(&connection). Сохраняйте временные guard временными до прежней границы полного выражения; см. локальные переменные.
  • Переконфигурируйте и пересоберите затронутые native-приложения, тесты и собственные расширения, перегенерируйте метаданные и выпеките единый согласованный набор ресурсов клиента и сервера. Откатывайте исполняемые файлы вместе с соответствующими ресурсами.

2026.1.99-dev - 2026-11-03

Изменено

  • Удалён лимит размера поисковых индексов документации в байтах. Полные английский и русский индексы генерируются без ограничения объёма; состав документов, правила токенов и проверки поиска сохраняются.

  • Опубликованная ветка нативного рефакторинга согласована с master ac37c9d217b314b3f3a1f567f67be535cfe15cac (2026.1.98-dev). Сохранены формат спрайтов v3, независимые временные шкалы направлений, преобразования и зависимости FOFRM, настраиваемые координаты карт, клиентская конфигурация пакетов и обработка ошибок Managed-событий без результата из master.
  • Типы checked_add/sub/mul/div выводятся из одинаковых типов операндов; внутренние количества, размеры и общие индексы используют знаковые фиксированные типы. На границах контейнеров, внешних API и сериализации остаются проверяемые преобразования. Арифметика проверяется до изменения буфера, выделения памяти, рисования и деления.
  • Обычные нативные записи остаются пассивными, их операции вынесены в свободные функции; поведение и владельцы времени жизни инкапсулированы в классах. Essentials, настройки и ExportValueType сохраняют API структур. Уточнены верхний публичный блок запросов и осмысленные [[nodiscard]], смысловые интервалы и описания синхронизации. Определения переменных инициализируются скобками с сохранением выбора перегрузок, размера контейнеров и типов.

Миграция

  • Это шаг интеграции исходников с 2026.1.98-dev на 2026.1.99-dev. Пересоберите Server, Client, Mapper, Baker, тесты и собственные нативные расширения, регенерируйте метаданные и запеките согласованные ресурсы. При обновлении старого feature checkout применяются сохранённые входящие миграции спрайтов v3, FOFRM и конфигурации из версий 64–98 ниже; старые бинарники и метаданные нельзя смешивать с новыми ресурсами. Интеграция не добавляет конверсии сохранений, перенумерации свойств/идентичностей, сетевого формата, Managed ABI или ресурсной схемы сверх изменений master; MigrationRule Version остаётся 0.0.86, Managed ABI — 9. Откатывайте полный согласованный набор исполняемых файлов и ресурсов.
  • Замените checked_mul<int64_t>(a, b) на checked_mul(a, b) после преобразования обоих операндов в int64_t; то же правило действует для add/sub/div. Явные аргументы арифметического шаблона и разные типы операндов дают ошибку вывода типов (MSVC C2672). Приведение после непроверенной операции не исправляет переполнение. Найдите старые вызовы в собственных native-корнях по checked_(add|sub|mul|div)\s*<; сохраняйте numeric_cast между разными числовыми типами. Целочисленное переполнение и неконечный floating-результат дают OverflowException, деление на ноль — DivisionByZeroException, в том числе в Game.DivRem. Конечный underflow, допустимые единицы и результаты сохраняются.
  • Замените потребляющие вызовы FileReader::GetStrNT/GetUInt8/GetInt8/GetBEUInt16/GetBEInt16/GetLEUInt16/GetLEInt16/GetBEUInt32/GetBEInt32/GetLEUInt32/GetLEInt32 соответствующими именами Read*. Старые имена больше не компилируются; продвижение позиции, проверки границ и интерпретация возвращаемых байтов сохраняются. Независимые запросы информации, например GetCurDataSpan, не переименовываются.
  • Пересоберите потребителей записей спрайтов/импорта и используйте знаковый int32_t для нативных величин и общих индексов; сохраняйте Size, Offset, Motion, типизированную покадровую Duration и отдельные массивы кадров направлений из спрайтов v3. Количество остаётся 1–65535, размеры — положительными 16-битными; общий индекс должен быть неотрицательным и ссылаться на предыдущий кадр. Целые миллисекунды последовательности используют uint32 диапазон v3 с положительными длительностями кадров; прежние отказы по uint16 длительности v2 и насыщение ART больше не применяются. Проверяйте широкие произведения пикселей/байтов до выделения памяти. Итоговые ограничения формата и точного размера RGBA применяются после преобразований FOFRM: исходные кадры могут получить там холст, движение и длительность, а широкий PNG — уменьшиться до допустимого выходного размера. Беззнаковые размеры TGA из потока сохраняют установленный старший бит.
  • Замените методы записей объявленными свободными функциями и откажитесь от прямого доступа к закрытым полям реализации; компиляция затронутых потребителей выявляет старые обращения. API настроек/value types, скриптовые типы и сигнатуры событий сохраняются. Инициализация скобками должна сохранять выбранный конструктор: конструктор vector/string по количеству сохраняется явно, если список иначе выбирает initializer_list, а копия JSON остаётся копией объекта. Существующие информационные Get сохраняют [[nodiscard]]; потребляющие и изменяющие методы остаются в блоке операций.
  • Проверьте SafeArithmetics, буферы, импорт/ресурсы/анимацию изображений, обычную и AngelScript-сборки нативных тестов, генерируемые контракты и документацию; затем запеките и проверьте затронутый проект. Нативные Windows-проверки не подтверждают runtime-приёмку другой платформы или renderer.

2026.1.98-dev - 2026-11-02

Исправлено

  • Повреждённая native-загрузка updater восстанавливается в том же запуске: временный файл с неверным размером, hash или префиксом удаляется и запрашивается один раз с нуля, корректный префикс возобновляется; при отказе удаления или повторной ошибке обновление прерывается без замены. ///@ Enum <Name> <Entry> = - отклоняется.

Миграция

  • База d6742fb78664773f64f09d497243db08106aed35 (2026.1.97-dev), новая версия 2026.1.98-dev: преобразование не требуется. Протокол, MigrationRule Version 0.0.86, Managed ABI 9 и схемы ресурсов не меняются.

2026.1.97-dev - 2026-11-02

Добавлено

  • ClientConfigBaker, наследующий ConfigBaker в том же модуле, пишет полные клиентские настройки в прежние выходы .fomain-client. Общий пакет Metadata с обоими пекарями не содержит дублирующих компактных клиентских выходов.

Изменено

  • Удалён токен упаковки OGL. Клиентские пакеты Windows и runtime payloads, подготовленные сервером, больше не содержат бинарников _OpenGL; package.py отклоняет любой токен, отсутствующий в BuildTools/PackageInterface.json.
  • Флаг запуска приложения переименован в AppInitFlags::StandaloneClient. Он отличает приложение клиента игрока, включая runtime DLL, от клиентских движков внутри сервера; правила окна и запуска сохраняются.

Исправлено

  • Несколько внешних снимков проверяются по закреплённым коммитам в двух checkout репозиториев. Текущий HEAD и грязные файлы не заменяют закреплённое содержимое; неизвестные репозитории, отсутствующие коммиты и исходники остаются ошибками.
  • Выбранный клиентский или серверный конфиг читается из Metadata до инициализации приложения; нового выбора профиля и конфигурационного кэша нет.

Миграция

  • База efefc47f3ace19b4e45428a20c2a1b12fc7f7666 (2026.1.96-dev); обновление 2026.1.97-dev.
  • Native-потребители запуска и раннего hook должны заменить AppInitFlags::ClientMode на AppInitFlags::StandaloneClient. Бит флага остаётся 0x01; alias старого имени и дополнительных изменений ABI/сети нет.
  • Сохранён InitApp(args, flags): все приложения предпочитают ресурсный .fomain-server, а при его отсутствии — .fomain-client.
  • Используйте общий пакет Metadata с Bakers=Metadata Config ClientConfig, пересоберите native-роли, выпеките и переупакуйте серверные и клиентские ресурсы вместе. Конфиги теперь лежат в Baking/Metadata; каждый архив сохраняет метаданные своей стороны вместе с выбранным конфигом. Сохраните прежний --config: в клиентские ресурсы входит только выбранный .fomain-client, в серверные — только выбранный .fomain-server. При отсутствии конфигов запуск сохраняет bootstrap; после синхронизации обновлятором объявленный конфиг обязателен. Несколько файлов приоритетного суффикса останавливают загрузку. Обычный Bakers=Config сохраняет выходы. Новых настроек и механизма выбора субконфига, преобразования сохранений не требуется.
  • Уберите OGL из объявлений пакетов и выбирайте OpenGL через --Render.ForceOpenGL 1 или локальную настройку; упаковка больше не вписывает настройки отдельного бинарника во вшитый конфиг. Установленный клиент _OpenGL не найдёт подготовленного runtime-обновления и должен быть заменён обычным клиентом.
  • Совместимость runtime меняется с 0.0.85 на 0.0.86 для потребителей стартовой конфигурации. Host ABI и протокол обновлятора сохраняются. Сохраните приоритет пользовательских настроек и CLI; CLI и вычисляемые настройки применяются один раз. Встроенные настройки остаются только для чтения. Изменение скачанного клиентского конфига требует перезапуска до игры; неизменный текст позволяет продолжить запуск.
  • Проверьте совпадение субконфига встроенного и ресурсного файлов, false/ноль/пустые значения, удалённые настройки, приоритеты, первый запуск, перезапуск после изменения и следующий запуск. Web/mobile отдельно подтверждают сохранение ресурсов и перезапуск.

2026.1.96-dev - 2026-11-02

Исправлено

  • Частично созданный Vulkan-буфер и выделенная для него память освобождаются при отказе выбора типа памяти, выделения памяти или привязки буфера. При отказе выходные дескрипторы вызывающего кода не меняются; владение передаётся только после успешной привязки.

Миграция

  • База 1ab76a88f25c1ee9116275768e227896c5d21039 (2026.1.95-dev) → 2026.1.96-dev: преобразование исходников проекта, настроек, сохранённых данных и ресурсов не требуется. Пересоберите Client, Mapper и остальные цели с Vulkan-рендерером. Успешное выделение, отложенное освобождение готовых ресурсов, ABI, сетевой протокол, маркер совместимости и схемы ресурсов не меняются. При выборе новой ревизии Engine по-прежнему требуется обычная регенерация версии и метаданных; клиенты, серверы и ресурсы должны принадлежать одной согласованной ревизии.

2026.1.95-dev - 2026-11-01

Исправлено

  • CMake-тест интерфейса проекта теперь ожидает 62 настройки, объявленные текущим интерфейсом, включая FO_MAP_MAX_SIZE и FO_MAP_WIDE_COORDS. Сохранены точные количества стадий и helpers, проверка объявлений и их влияния на bake.
  • Тест интерфейса native extensions теперь ожидает все 10 hooks, включая два существующих хука видимости при просмотре карты. Сохранены маршрутизация ролей и отказ для неполной пары роль/путь.

Миграция

  • База c1b3f7114d8c7ec7299ab936fe3c36ee20726dd1 (2026.1.94-dev), новая версия 2026.1.95-dev: преобразование исходников проекта, настроек, сохранённых данных или ресурсов не требуется. Исправления тестов не меняют runtime-контракты, ABI, сетевой протокол, маркер совместимости или схемы ресурсов. Проверьте текущие интерфейсы командами cmake -P BuildTools/tests/validate_project_interface.cmake и cmake -P BuildTools/tests/validate_native_extension_interface.cmake. При выборе новой ревизии Engine по-прежнему требуется штатная регенерация версии/метаданных; клиенты, серверы и ресурсы должны использовать одну согласованную ревизию.

2026.1.94-dev - 2026-11-01

Исправлено

  • Для управления именованными удержаниями симуляции используется scoped-владение mutex, позволяющее Clang проверить каждый захват и освобождение. Сохранены управление при старте, неблокирующая попытка под дренированной внешней блокировкой и VerificationException, когда управление занято.
  • Конфигурации ContentShowcase и PackagingMatrix пересозданы из актуальных настроек Engine.
  • Изолированный тест опций web/баз данных использует настоящие CMake helpers и задаёт значения размера карты по умолчанию, необходимые стадии project-options. В конструкторе Managed mpos(string) восстановлено каноническое форматирование.

  • Изменение размера карты/сетки, вызывающее переполнение площади, отклоняется до изменения состояния карты; размеры статической сетки публикуются только вместе с заменяющими ячейками.

Миграция

  • База 27553fd71d553bb46c47d0c8e7de6b8e8e4301ca (2026.1.93-dev), новая версия 2026.1.94-dev: преобразование исходников проекта, настроек, сохранённых данных или ресурсов не требуется. Пересоберите все затронутые нативные роли (Server, Client, Mapper, Baker и тесты), поскольку шаблон сетки общий. Причины удержаний симуляции, владение паузой, поведение при старте, тип исключения и правила повторной попытки сохраняют прежний смысл; неудачная неблокирующая попытка захвата не меняет удержания. Значения по умолчанию в конфигурациях примеров сохранены. Центральный маркер MigrationRule Version, Managed ABI, сетевой протокол и схемы ресурсов этими исправлениями не меняются. Клиенты, серверы и запечённые ресурсы по-прежнему должны использовать одну настроенную ревизию Engine, как требует предыдущее обновление координат карты.

2026.1.93-dev - 2026-11-01

Добавлено

  • Добавлена CMake-опция FO_MAP_WIDE_COORDS (влияет на запекание, по умолчанию OFF). Со значением ON компоненты mpos и msize становятся знаковыми 32-битными вместо знаковых 16-битных. В нативном коде тип компоненты называется mcoord_t. Оба layout ExportValueType объявляют тип поля mcoord; codegen.py выводит из него int16 или int32 по engine define FO_MAP_WIDE_COORDS и включает выведенные layout в FO_COMPATIBILITY_VERSION. AngelScript регистрирует поля mpos/msize по этому layout метаданных, а сгенерированные структуры Managed C# следуют за ним (short/int).
  • Добавлена CMake-опция FO_MAP_MAX_SIZE (влияет на запекание, по умолчанию 4000), задающая GameSettings::MAX_MAP_SIZE. Значение должно быть от 200 до 32767, диапазона координат int16, а с широкими координатами — до 4194304. 4194304 — это GameSettings::MAP_SIZE_LIMIT, самая широкая сторона карты, которую упорядочивает клиентский ключ порядка отрисовки спрайтов: ключ хранит X ячейки в 22 битах, а экранную строку, не больше удвоенной стороны, — в 24 битах. Конфигурация отклоняет значение вне диапазона с FO_MAP_MAX_SIZE must be an integer from 200 to <limit> (<reason>), а статические проверки в Common.h и MapSprite.cpp повторяют границы; ещё одна проверка удерживает пиксельные позиции в пределах половины диапазона int32 для настроенного размера гекса.
  • Добавлена CI-задача wide-coords, которая запускает validator unit-tests с FO_MAP_WIDE_COORDS=ON; задача engine-update запускает BuildTools/tests/test_codegen_value_type_layouts.py.

Изменено

  • Сгенерированные конструкторы Managed mpos и msize принимают аргументы int при любой ширине. 16-битные поля сужаются в checked-арифметике скриптов (CheckForOverflowUnderflow), поэтому аргумент вне диапазона бросает OverflowException; mpos(string) разбирает текст через тот же конструктор.
  • Площадь карты и хранилища по карте больше не переполняют int32 и 32-битный size_t: isize::square() становится square<R>(): вызывающий код задаёт тип результата, а площадь, перемноженная как int64_t через checked_mul, преобразуется в него через numeric_cast<R>, поэтому square<int64_t>() сохраняет площадь за пределами 32-битного диапазона на любой платформе, а более узкий тип её отклоняет. Места выделения памяти вызывают square<size_t>(): статические и чанковые двумерные сетки, буфер освещения гексов на клиенте, индекс блоков поиска пути (checked_mul<int64_t>), Map.GetVisibleHexes и буферы чтения рендерера бросают OverflowException для размера, который не помещается в size_t, вместо переполнения, а все конструкторы двумерных сеток (DynamicTwoDimensionalGrid, StaticTwoDimensionalGrid, ChunkedTwoDimensionalGrid) больше не noexcept: отрицательный размер теперь бросает исключение вместо записи в журнал и пустой сетки. Нативные вызовы задают нужный им тип. Индексы, выводимые из координат (ячейки и чанки сеток, освещение гексов, блоки поиска пути), считаются в int64_t и преобразуются через numeric_cast<size_t>, поэтому диапазон координат, который 32-битный size_t не может индексировать, обнаруживается вместо переполнения. Буфер освещения гексов на клиенте хранит одну запись на гекс вместо трёх, из которых читалась только первая треть. Отклонение цели пути считается в 64 битах. Ключ порядка отрисовки спрайтов остаётся 64-битным, но упакован как [group 6][primary 24][layer 4][sub-layer 8][secondary 22] вместо [8][24][8][8][16]; взаимный порядок всех ключей, которые движок формировал раньше, не меняется.
  • Загрузка статической карты на сервере и создание MapView на клиенте отклоняют карту, чей Size не положителен (Map size must be positive) или превышает GameSettings::MAX_MAP_SIZE (Map size exceeds the engine maximum). Раньше предел соблюдало только изменение размера в Mapper.

Миграция

  • База 50e1ddb1ea7405d9b52ef44ec338fa4d473e4cac (2026.1.92-dev); неопубликованное рабочее изменение — 2026.1.93-dev. Затронутые роли: native Server, Client, Mapper, Baker и unit tests, codegen.py, backends AngelScript и Managed и CMake-интерфейс проекта.
  • Сборки по умолчанию сохраняют 16-битные координаты. Нативный layout, байты сетевых сообщений, запечённые данные свойств, документы базы данных и схемы ресурсов не меняются. FO_COMPATIBILITY_VERSION всё равно меняется, потому что хешируется объявленный текст layout: пересоберите и разверните клиенты, серверы и ресурсы одной ревизии; смешанные старые и новые сборки не проходят проверку совместимости. Маркер MigrationRule Version остаётся 0.0.85, Managed ABI 9 не меняется. Конвертация данных и MigrationRule не требуются, откат восстанавливает полный согласованный набор артефактов базовой ревизии.
  • Предел размера карты: карта больше 4000 ячеек по стороне, созданная в обход Mapper, раньше загружалась; теперь она останавливает запуск сервера или загрузку карты на клиенте с Map size exceeds the engine maximum. Найдите такие карты командой rg -n "^Size\s*=" --glob "*.fomap" и сравните оба числа с пределом. Чтобы сохранить их, добавьте SetOption(FO_MAP_MAX_SIZE <наибольшая сторона>) в CMakeLists.txt проекта до StartProjectGeneration(), переконфигурируйте, пересоберите и заново запеките ресурсы. Значение вне допустимого диапазона останавливает компиляцию с FO_MAP_MAX_SIZE is out of range, FO_MAP_MAX_SIZE exceeds the sprite draw-order key range или FO_MAP_MAX_SIZE exceeds the int32 pixel range for this hex size.
  • Нативный код: GameSettings::MAX_MAP_SIZE сохраняет имя и значение по умолчанию. Используйте mcoord_t вместо int16_t для координат карты и счётчиков циклов по её размерам, numeric_cast<mcoord_t> вместо numeric_cast<int16_t> при сужении в mpos/msize и sizeof(mcoord_t) * 2 вместо литерала 4 для их размера. Кандидатов найдите командой rg -n "int16_t" SourceExt (или по нативным исходникам проекта) рядом с mpos, msize, GetHex и GetSize. Сборки по умолчанию продолжают компилировать старый код; с FO_MAP_WIDE_COORDS=ON компилятор сообщает о сужении компоненты в int16_t.
  • Нативный код: замените size.square() на size.square<size_t>(), где площадь задаёт размер контейнера или буфера, и на size.square<int64_t>(), где это значение; внутри шаблона по типу размера пишите size.template square<size_t>(). Прежний вызов больше не компилируется, потому что тип результата нельзя вывести (MSVC C2783, GCC/Clang «couldn’t deduce template parameter»), а преобразование бросает OverflowException для отрицательной площади или площади, которую заданный тип не вмещает. Вызовы находит rg -n "\.square\(\)". Конструкторы сеток (DynamicTwoDimensionalGrid, StaticTwoDimensionalGrid, ChunkedTwoDimensionalGrid) больше не noexcept и бросают исключение для отрицательного размера; создавайте их там, где исключение может распространиться.
  • Managed-скрипты: new mpos((short)x, (short)y) и new msize((short)w, (short)h) компилируются с прежним смыслом; приведения больше не нужны, а new mpos(x, y) с аргументами int теперь компилируется и бросает OverflowException для значения, которое не помещается в тип компоненты. Чтение поля в int работает при обеих ширинах; сохранение в short или передача в параметр short компилируется только с 16-битными координатами (иначе CS0266). mpos(string) по-прежнему бросает FormatException для нечислового текста и OverflowException для значения вне диапазона.
  • Скрипты AngelScript видят поля int16 или int32 согласно выбору; конструктор mpos(int x, int y) сохраняет сигнатуру и проверку диапазона. Чтобы не зависеть от ширины, храните компоненты в локальных переменных int.
  • Включение широких координат: добавьте SetOption(FO_MAP_WIDE_COORDS ON), переконфигурируйте, пересоберите все native- и Managed-роли и заново запеките все ресурсы; опция входит в хеш конфигурации запекания, поэтому Baker пересобирает полный набор. Сетевые сообщения и запечённые данные свойств вырастают на четыре байта на позицию; сетки гексов не растут. Документы базы данных хранят координаты числами и загружаются без изменений. Возврат к 16 битам не загрузит ни одну сохранённую координату больше 32767, поэтому сохраните резервную копию базы данных до переключения для отката.
  • Владельцы приёмки: Map coordinates use the configured component width, MapManagerRejectsMapLargerThanEngineMaximum, проверки сгенерированных типов в Test_ManagedScriptBaker.cpp, test_codegen_value_type_layouts.py и полный набор unit tests в обычной задаче unit-tests и в CI-задаче wide-coords.

2026.1.92-dev - 2026-11-01

Добавлено

  • Добавлено клиентское свойство Critter.VisualOffset (ipos, пиксели): изменяемое, несинхронизируемое и несохраняемое смещение, которое CritterHexView::RefreshOffs прибавляет к смещениям движения, дополнительным и анимационным смещениям map-спрайта криттера; клиент пересчитывает смещения в post-setter свойства. Клиентский скрипт может нарисовать криттера не там, где он логически стоит, например по плавной кривой полёта вдоль гексового пути, не меняя логическое состояние. Ноль рисует ровно так же, как раньше.

Миграция

  • База 680c444d1d54d5120e1cb87b080cbe14dd81a081 (2026.1.91-dev) → 2026.1.92-dev: аддитивно; конверсия исходников и данных не нужна. Пересоберите все native-роли, тесты и Baker, затем запеките метаданные и все managed-роли одним комплектом. Новое свойство Critter зарегистрировано после LightColor, поэтому индекс в реестре каждого свойства Critter, объявленного после него, включая все свойства Critter встраивающего проекта, увеличивается на единицу; ручной маркер совместимости растёт с 0.0.84 до 0.0.85, смешение старых и новых исполняемых файлов и ресурсов отвергается. Существующие скрипты, прототипы, карты и сохранения не затронуты: свойство клиентское, не сохраняется и не синхронизируется, по умолчанию ноль и ничего не меняет в отрисовке, пока скрипт его не задаст. Managed ABI 9 не меняется. Откат — совместно исполняемыми файлами и ресурсами.

2026.1.91-dev - 2026-10-31

Исправлено

  • Цепочка события больше не обрывается, когда падает Managed-обработчик без результата. Native.InvokeEvent и сгенерированный AdaptInvoke сообщали о сбое и возвращали StopChain для любого обработчика, поэтому Entity::FireEvent принимал упавший обработчик void или Task за решение и пропускал всех подписчиков с меньшим приоритетом. На клиенте первый упавший обработчик Game.OnStart удерживал подписчика, который подключается к серверу, и игрок оставался на чёрном экране. Обработчик без явного результата теперь возвращает ContinueChain после однократного отчёта о сбое; обработчик, возвращающий EventResult, по-прежнему завершает цепочку через StopChain. Entity::FireEvent сообщает о StopChain от callback-а без явного результата как о нарушении контракта, а ServerEngine::FireEvent и ServerEntity::FireEvent делегируют ему, а не повторяют цикл. См. безопасность исключений.

Миграция

  • База 56683c4737ebbb1386ae3365be49416ac1678432 (2026.1.90-dev) → 2026.1.91-dev: преобразование настроек, данных, ресурсов и сохранений не требуется. Пересоберите все native-роли и перепеките managed-скрипты, потому что меняются сгенерированные адаптеры событий. Managed-обработчик, объявленный без результата, больше не может отказать событию своим сбоем: о сбое сообщается один раз, а результат события остаётся ContinueChain, поэтому шлюзы входа, загрузки и запуска продолжают работу. Обработчик, который должен уметь отказать, возвращает EventResult или Task<EventResult>. Нативный C++-подписчик, возвращающий StopChain, должен задавать EventCallbackData::HasExplicitResult; без этого Entity::FireEvent сообщает о нарушении контракта и всё равно останавливает цепочку. Обработчики AngelScript сохраняют поведение, потому что их исключения по-прежнему доходят до Entity::FireEvent. Центральный маркер миграции, Managed ABI, раскладка кадра события и схемы ресурсов не меняются. Приёмка: выполните нативно EventChainStopsOnlyForCallbacksWithExplicitResult и тесты событий ManagedScriptBaker, затем запустите клиент, у которого обработчик Game.OnStart бросает исключение, и убедитесь, что подписчик подключения выполняется.

2026.1.90-dev - 2026-10-30

Изменено

  • ServerEngine::ValidateServerSnapshotState стал публичной статической предварительной проверкой. Встраивающий проект может применить к сохранённому ServerSnapshotState структурные проверки конструктора восстановления до остановки живой сессии; проверка не читает мир и не решает вопросы совместимости и идентичности контента, которые остаются проверками вызывающей стороны. CreateSnapshot() и восстановление снимка по-прежнему вызывают тот же валидатор.

Исправлено

  • Именованные HoldSimulation(reason) / ReleaseSimulationHold(reason) разрешены под уже дренированным внешним Lock() того же сервера вне main worker. Если управление занято, вызов под этим lock бросает Simulation control is busy; retry after releasing the external lock до изменения hold, а не ждёт контроллер, который сам может ждать этот lock; внешние вызывающие по-прежнему ждут. Callback quiescence, собственный Lock() main worker и обычные job/script-контексты по-прежнему отвергаются до захвата mutex. Unlock() теперь проверяет, что внешний lock принадлежит вызывающему серверу, а первый hold под совпадающим внешним lock дренирует мир через него без повторной блокировки. См. контексты вызова и повтор при занятости.
  • Запрошенная подконфигурация в packaged-сборке отвергается без цикла с безусловным исключением, что убирает MSVC C4702 из LoadAppSettings; первое запрошенное имя по-прежнему попадает в сообщение.

Миграция

База f2a8756706384c0dfe5aa77cb03caf3a7ec04475 (2026.1.89-dev) → 2026.1.90-dev: пересоберите native-роли и цель модульных тестов. Конвертация настроек, данных, ресурсов и сохранений не требуется. Код вне ServerEngine вызывает ServerEngine::ValidateServerSnapshotState(state) и перехватывает ServerSnapshotException; прежнего публичного написания не было. Контроллер, удерживавший внешний Lock(), раньше получал Simulation control must be requested outside a server execution context при изменении именованных hold; теперь он может менять hold под lock, но обязан обработать исключение занятости: освободить lock, затем повторить вызов или согласовать свои предшествующие изменения. Внешние, стартовые и отвергаемые контексты сохраняют поведение. Сетевой протокол, маркер совместимости MigrationRule Version 0.0.84, Managed ABI 9, поколение апдейтера и схема ресурсов не меняются; разворачивайте и откатывайте согласованный набор native-бинарников.

2026.1.89-dev - 2026-10-30

Исправлено

  • Первое сообщение приложения с типом, отличным от handshake, отклоняется как нарушение протокола без отчёта об исключении движка и влияния на другие соединения.
  • В интеграционном тесте явно указано пространство имён серверного helper, чтобы вызов оставался однозначным в Unity-сборках. Проверка покрытия примеров больше не привязана к числам одного снимка документации; отчёт примеров пересоздан для текущего корпуса.

Миграция

  • База 522d825ef32dfdcd3889ffdba664f9f0dfee5293 (2026.1.88-dev) → 2026.1.89-dev: пересоберите нативные роли сервера для изменения обработки неверного ввода. Допустимые сообщения, исходники проекта, настройки, данные, сохранения, ABI, сетевой протокол и форматы ресурсов не меняются; преобразование данных и парное развёртывание не требуются.

2026.1.88-dev - 2026-10-30

Исправлено

  • Перезапущенный сервер снова открывает WebSocket-порт на POSIX, пока закрытые соединения предыдущего процесса держат его в TIME_WAIT. NetworkServer_WebSockets теперь ставит SO_REUSEADDR перед listen на всех платформах, кроме Windows, поэтому штатная остановка и быстрый запуск больше не расходуют ServerNetwork.ListenRetryTime на Address already in use (system:98). Живой listener, с этой опцией или без неё, по-прежнему отклоняет bind; Windows сохраняет значение по умолчанию, потому что там опция позволила бы второму процессу делить порт с живым listener. Каждая строка повтора ServerEngine::StartConnectionServer теперь оканчивается отказом, за которым следует. См. повторы слушателя.

Миграция

  • База e8eb12f279b70c73852bdc0fb1a24ae51b5927bc (2026.1.87-dev) → 2026.1.88-dev: преобразование исходников проекта, настроек, скриптов, контента и сохранённых данных не требуется: API, настройки, сообщения и форматы файлов не добавляются, не удаляются и не меняют смысл. Пересоберите все native-серверные роли с соответствующей ревизией Engine. Строки журнала повторов получают в конце суффикс : <причина> после прежнего текста, поэтому сопоставляйте их по префиксу. Центральный маркер миграции остаётся 0.0.84, Managed ABI 9 и схемы ресурсов не меняются, а опция слушателя не входит в сетевой протокол, поэтому порядок развёртывания и откат не требуют согласованной пары. Сервер, собранный до этого шага, оставляет сокеты TIME_WAIT без SO_REUSEADDR, когда первым закрывает соединения, и один новый слушатель с опцией их не обходит: первый перезапуск поверх такой сборки может по-прежнему ждать их истечения, а другой порт или неограниченный повтор решением не являются. Приёмка: выполните NetworkServerWebSockets* и SecureChannelRunsOverWebSockets нативно на Linux и Windows, потому что регрессия TIME_WAIT может упасть только там, где ядро удерживает порт.

2026.1.87-dev - 2026-10-29

Добавлено

  • Добавлена перегрузка Game.CreateItem(protoId, properties) для Dictionary<ItemProperty, any>. Она применяет изменяемые переопределения, включая составные значения, к копии прототипа через SetValueAsAnyProps до OnItemInit и InitScript. Неизменяемые, отключённые и виртуальные ключи отклоняются до регистрации предмета; неизвестный прототип отклоняется до создания.
  • Открыт MapSpriteHolder.Elevation, применяемый при прикреплении клиентского локального спрайта независимо от Offset.

Исправлено

  • Удалён неопубликованный обход фильтра снимков Common-свойств. Начальные пакеты предметов снова используют обычную фильтрацию PublicSync/OwnerSync и два кеша видимости; неизменяемые Common и NoSync исключены.
  • Группы динамической крыши перестраиваются после изменения покрытия с сохранением выбранного скрываемого гекса. Очистка прежних групп читает отсутствующие ячейки блочной карты без выделения их памяти.

Миграция

  • База f116c907c192b1ca3e243d1538705c831a7dd362 (2026.1.86-dev); неопубликованное рабочее изменение — 2026.1.87-dev. Прежние целочисленные перегрузки CreateItem и StoreData(with_protected) сохраняют семантику. Замените неопубликованное имя CreateItemWithInitialProperties на Game.CreateItem(pid, new Dictionary<ItemProperty, any> { [ItemProperty.Offset] = "7 -11" }); старый метод удалён. Эта перегрузка проверяет Mutable через штатный setter свойств: задавайте неизменяемую структуру в общем прототипе. Обычные изменяемые целочисленные переопределения оставьте прежней целочисленной перегрузке. Native-инициализация предмета по-прежнему сбрасывает поля владения и размещения; для размещения результата вызовите MoveItem. Преобразование бизнес-данных шаблонов и снимков остаётся обязанностью проекта.
  • Entity::StoreData(with_protected) и Properties::StoreData(with_protected) сохраняют обычную сигнатуру и семантику синхронизации. Удалите неопубликованный второй аргумент включения и зависимость от передачи несинхронизируемых Common. PicMap/Offset уже имеют PublicSync; несинхронизируемая структура должна совпадать в общих прототипах. Рабочий барьер совместимости остаётся 0.0.84, чтобы прежний локальный экспериментальный набор артефактов не смешивался с исправленной сборкой.
  • Перегенерируйте модели/справочники API и метаданные; пересоберите native Baker, сервер, клиент, Mapper и тесты, затем заново запеките все затронутые роли скриптов/ресурсов и упакуйте согласованный набор. Новое открытое поле меняет private/native layout держателя: не смешивайте старые объектные файлы и новые заголовки. Развёртывайте согласованные бинарники и ресурсы вместе; смешанные старые/новые артефакты должны отклоняться проверкой совместимости. Managed ABI 9 и схемы БД/ресурсов прежние; эти дополнения не требуют преобразования сохранений. Откат восстанавливает целый согласованный набор базы и прежние совместимые данные снимков/шаблонов проекта, если его миграции их изменили.
  • Сохраните текущую реализацию HasFactory/NativeRefTypeLifetime из опубликованной .29 и последующих исправлений: new MapSpriteHolder() вызывает native-фабрику, очистка отрисовки использует StopDraw(), затем Dispose(). Не возвращайте открытые __Factory, __AddRef, __Release или заменённый конструктор через временную обёртку. Согласование не добавляет нового API владения.
  • Владельцы приёмки: ServerItemCreationAnyPropertiesRespectMutability (изменяемые скалярные/составные переопределения, изоляция прототипа и соседнего экземпляра, отказ неизменяемого ввода до регистрации), PropertiesSnapshotNeverTransmitsUnsyncedProperties (публичная/владельческая фильтрация, исключение неизменяемых Common и NoSync, хранение с прототипом и без него, чередование и инвалидирование кешей), PropertiesOverlayFiltersAndCopies, MapViewDynamicRoofGroupsFollowCoverageChanges, проверки конструкторов/владения Managed ref-type и проектные маршруты инициализации предмета, предпросмотра, миграции и восстановления.

2026.1.86-dev - 2026-10-29

Исправлено

  • Исправлена запись миграции замены Client.UserWritablePath в Docs/contract-change-dispositions.json. Она предписывала проектам передавать --UserWritablePath <path> — написание, которое ResolveWritableRoot никогда не распознавал: ранний поиск writable root сопоставляет только полностью квалифицированную опцию Common.UserWritablePath, поэтому неквалифицированный флаг принимался как посторонний custom setting, а процесс сохранял portable-раскладку относительно working directory. Запись теперь называет --Common.UserWritablePath <path>, как и справочник конфигурации, руководство по эксплуатации релиза и руководство по client updater. Неквалифицированный алиас не добавляется; поддерживаемые написания, *, marker установщика и portable-откат не изменены. Документационный тест теперь связывает поддерживаемое написание с ResolveWritableRoot и отклоняет неквалифицированное написание в английских и русских руководствах и в реестре.

Миграция

База 47f2e992cd0dbbb1c3bad0f8ba52140d50a0c8c4 (2026.1.85-dev) → 2026.1.86-dev: только исправление документации. Конверсия исходников, настроек, данных и сохранений не требуется. Найдите неквалифицированное написание в скриптах запуска, регистрациях служб, Android-лаунчерах и CI командой rg -n --pcre2 '(?<![\w.])--?UserWritablePath\b' и замените каждое вхождение на --Common.UserWritablePath <path> (или -Common.UserWritablePath <path>); * в качестве пути по-прежнему выбирает per-user каталог. Процесс, запущенный с неквалифицированным флагом, работал в раскладке working directory, поэтому записанные им данные остаются там: перенесите их осознанно до переключения, иначе процесс стартует с пустым writable root. Сетевой протокол, маркер совместимости MigrationRule Version, Managed ABI, поколение updater и схема ресурсов не меняются, поэтому смешанные развёртывания остаются совместимыми, а откат возвращает только прежний текст.

2026.1.85-dev - 2026-10-29

Исправлено

  • При неверном или обрезанном кадре пира после рукопожатия или после входа сервер теперь отключает только это соединение, а не сообщает об исключении движка. NotLoggedInPlayerJob() и PlayerJob() считают любое NetBufferException (включая UnknownMessageException) нарушением протокола этим пиром: одно предупреждение с remote host/port, сообщением и контекстными значениями исключения, затем жёсткое отключение с ProtocolError. В неинтерактивном и headless-режиме отчёт об исключении запрашивает завершение приложения, поэтому один кадр Ping без часов отправителя раньше останавливал весь сервер; остальные соединения и исключения других типов не затрагиваются, политика обработки исключений приложения не меняется.
  • В контекстных значениях NetBufferException теперь настоящие позиция чтения, конец кадра и конец буферизованных данных. NetInBuffer и NetOutBuffer брали их после того, как ResetBuf() уже обнулил их, поэтому Invalid read length, Invalid shrink pos, Invalid discard length, Incoming network message extends past buffered data и Property data count exceeds remaining buffer печатали нули.

Миграция

База 843a470bb47c20cb7be609e40c461646dbfdab66 (2026.1.84-dev) → 2026.1.85-dev: серверная обработка неверных кадров пира и контекстные значения исключений. Пересоберите серверные роли и цель unit-тестов; конверсия клиента, исходников, настроек, данных, ресурсов и сохранений не нужна, API скриптов не меняется. Неверный Ping (и любое другое NetBufferException при чтении входа не вошедшего или вошедшего игрока) больше не доходит до exception reporter, поэтому мониторы логов, считающие консольные записи NetBufferException для нарушений формата кадра пиром, увидят вместо них предупреждение Invalid network data from host <host>:<port>: <сообщение> (<контекст>) (Invalid handshake data до завершения рукопожатия); внутренние исключения по-прежнему сообщаются. Обнаружение: ищите эти предупреждения в логах сервера; чтобы убедиться, что проект не зависит от прежнего поведения, найдите имя исключения в собственных мониторах. Маркер сетевой совместимости, runtime 0.0.82 и Managed ABI 9 не меняются; клиентские и серверные сборки одного набора совместимости работают вместе в любом порядке и откатываются независимо.

2026.1.84-dev - 2026-10-29

Исправлено

  • README BuildTools приведён в соответствие с текущим конвейером документации. Он называл 20 генерируемых контрактных моделей для docs_description_translations.py, хотя инструмент инвентаризирует 19 моделей из MODEL_PATHS; обещал последующий переход каталога описаний из registered-translations-current в complete, хотя закоммиченный каталог уже требует complete; и утверждал, что весь generated JSON и Markdown хранится в репозитории, хотя endpoints llms, общий manifest, индексы навигации и поиска и каталоги валидации — игнорируемые выходы, которые пересобирает docs_prepare.py, а публичные корневые endpoints лежат в Workspace/Documentation/. Обе редакции теперь называют фактическое число моделей и отделяют версионированные контрактные модели, справочники, изображения и переводы от этих build outputs. test_docs_description_translations.py сверяет число моделей, названное в обоих README, с MODEL_PATHS, а русский README несёт translation hash нового английского текста. Строгая проверка локализации, отклоняющая любой устаревший hash, не изменена.

Миграция

База c80e173595deea1853b93d70304e2c1c6d729162 (2026.1.83-dev) → 2026.1.84-dev: исправление только документации и теста документации. Конверсия исходников, настроек, данных и сохранений не требуется, пересборка и развёртывание не нужны. Сетевой протокол, runtime 0.0.82, Managed ABI 9, поколение updater и схема ресурсов не меняются, поэтому смешанные развёртывания остаются совместимыми, а откат возвращает прежний текст.

2026.1.83-dev - 2026-10-29

Добавлено

  • Добавлены отдельные native-хуки CheckViewMapCritterVisibilityHook и CheckViewMapItemVisibilityHook с непрозрачным nullable-контекстом Entity и центром обзора. Начальный и последующий допуск динамических объектов используют одни хуки; режимы видимости существ сохраняются и отправляются. Политику null определяет проект; генерируемые заглушки допускают все объекты в пределах времени жизни/радиуса Engine. Player.RefreshViewMapVisibility(map) обновляет правила без перезагрузки карты. См. ограниченный обзор.

Миграция

  • Этот шаг следует за 629ea6f569f7af460a41fc1d582dd948fdcc6a97 (2026.1.82-dev) в 2026.1.83-dev. Во всех вызовах Managed C# и AngelScript замените ViewMapArea(map, hex, radius) на ViewMapArea(map, hex, radius, context); null используйте только когда проектные хуки разрешают полный допуск. ViewMap(map, hex) остаётся отсоединённым полным обзором и передаёт null внутри. Удалите интеграцию неопубликованных ViewMapAreaFilteredItems / RefreshViewMapItemFilter: их селектор свойства и списки ID заменяются хуками с контекстом и RefreshViewMapVisibility, без aliases. Native-методы Player::SetViewMap / Map::SetSpectatorArea принимают nptr<Entity> после радиуса. Открытие и явное обновление требуют покрытия живого контекста. Хуки синхронно читают покрытое состояние без мутаций, callbacks, уступки управления и захвата блокировок; недостающее независимое покрытие получает отложенный native-dispatcher с проверкой идентичности подписки.
  • Пересоберите затронутые native-роли, заново сгенерируйте оба скриптовых backend и запеките согласованные серверные/клиентские метаданные и сборки. Наличие хуков и форма API меняют автоматический runtime digest; центральный маркер миграции текущей правки — 0.0.83, Managed ABI остаётся 9. Сетевые сообщения и схемы ресурсов не меняются. Смешивание предыдущих бинарников/ресурсов не поддерживается; откат возвращает согласованный набор целиком. Контекст и подписки существуют только в рантайме, преобразование сохранённых данных не требуется. Объекты полного обзора теперь также проходят через хуки; переопределяющие их проекты должны явно задать поведение null.

2026.1.82-dev - 2026-10-28

Исправлено

  • Конфиг дистрибутива MinimalMultiplayer повторно сгенерирован с объявленным нативным значением Baking.FilterResources = False. Производный пример соответствует исходнику настроек и сохраняет поставку всех текущих выходов bake.

  • В двух новых UDP-регрессиях явно выбран server factory фикстуры клиент-серверного взаимодействия: поиск helper’а больше не становится неоднозначным, когда Unity batch объединяет другие серверные фикстуры. Имена тестов, проверки и поведение runtime не меняются.

  • Клиентский тайм-аут тишины в фикстуре докачки по UDP ограничен её окном опроса: потерянная негарантированная дейтаграмма отключения больше не заставляет ждать дольше теста. Production-тайм-ауты, пределы опроса и все проверки частичного файла и докачки не меняются.

Миграция

База 59deea3d01c8ca7d306c83e7c65967bcc57d0270 (2026.1.81-dev) → 2026.1.82-dev: преобразование исходников проекта, настроек и сохранений не требуется. Пример теперь явно фиксирует прежнее нативное значение по умолчанию; встраивающие проекты сохраняют выбранную политику фильтрации ресурсов. Проверьте производный пример командой python Examples/MinimalMultiplayer/generate_config.py --check и выполните python BuildTools/tests/test_minimal_multiplayer_package.py. Пересоберите нативную тестовую цель и выполните полный RunUnitTests в обычной и Unity-конфигурациях, включая обе UDP-регрессии. Перед упаковкой повторите конфигурацию, сборку и bake примера с соответствующей ревизией Engine: сгенерированные метаданные содержат версию движка. Runtime 0.0.82, Managed ABI 9 и манифест отбора ресурсов 1 не меняются. Развёртывайте и откатывайте согласованные конфигурацию, бинарные файлы и bake вместе.

2026.1.81-dev - 2026-10-28

Исправлено

  • Установленная сессия UDP завершается как потеря соединения, если транспорт отказал после ответа сервера на рукопожатие. Раньше ClientConnection продолжал считать такую сессию устанавливающейся, поэтому ошибка отправки UDP посреди скачивания или игры открывала поверх неё новое соединение по TCP: сервер видел вторую сессию, игровой клиент падал с «Cur player is already set», а updater получал отказ «Update file list was already received» и завершался как Failed. Откат с UDP на TCP теперь действует только на этапе подключения — от подключения по UDP до ответа на рукопожатие. Более поздний сбой транспорта идёт обычным путём отключения: updater сообщает ConnectionFailed, сохраняет подтверждённые байты временного файла и докачивает их при следующем запуске. Собственная проверка updater «список файлов получен один раз за сессию» не изменена.

Миграция

База fcac7eb0824ea23a67fa4e2bd8804d4e03fdda98 (2026.1.80-dev) → 2026.1.81-dev: исправление поведения подключения на стороне клиента. Конверсия исходников, настроек, данных и сохранений не требуется. Пересоберите и разверните клиентские роли; клиент без исправления продолжает работать с исправленным сервером и наоборот. Сетевой протокол, runtime 0.0.82, Managed ABI 9, поколение updater и схема ресурсов не меняются, поэтому смешанные развёртывания остаются совместимыми, а откат возвращает прежнее поведение.

2026.1.80-dev - 2026-10-28

Исправлено

  • Внутренним именам слота данных препроцессора и диагностических функций валидатора атрибутов AngelScript заданы отдельные имена единицы трансляции: её теперь можно объединять в Unity batch с backend и реализацией удалённых вызовов. Значение слота, текст объявления скрипта и привязка к исходной позиции сохраняют прежний смысл.

  • Внутренние helper’ы тестов AngelScript получили различимые имена, а обращения к общим фикстурам явно выбирают владельца в Unity batches. Имена тестов, проверки и встроенные исходники скриптов сохранены; макросам тестов расширенных операций также заданы отдельные имена.

  • Макросы памяти заголовков сокетов Windows SDK и их транзитивные раскрытия сохраняются после очистки макросов, позволяя поздним подключениям Asio компилироваться в Unity batches.

Миграция

База 28c84c5d9d21f5a33b2122977314383842dfe414 (2026.1.79-dev) → 2026.1.80-dev: пересоберите затронутые нативные цели AngelScript в обычной и Unity-конфигурации. Выполните полный RunUnitTests в обычной и Unity-сборке, чтобы весь список тестовых исходников и зависимая проверка ресурсов использовали соответствующий бэкенд. Пересоберите цели Windows и скомпилируйте настоящие заголовки сокетов SDK после очистки макросов Windows, включая Unity-сборки с поздним подключением Asio. Преобразование исходников проекта, настроек, сохранений и схемы ресурсов не требуется: меняются приватные имена C++ и доступность макросов заголовков Windows. Runtime 0.0.82 и Managed ABI 9 прежние; развёртывайте и откатывайте согласованную нативную ревизию и конфигурацию сборки вместе.

2026.1.79-dev - 2026-10-28

Изменено

  • Фильтрация ресурсов пакетов включается явно через Baking.FilterResources = True. По умолчанию False включает все доступные выходы текущих baker-ов без каталогов ресурсных корней. Свежесть манифеста, обязательные выходы и ограничения сторон пакетов и целевых приложений проверяются в обоих режимах.

Исправлено

  • Нормализованы фикстуры заголовков генератора WinAPI перед явным преобразованием в CRLF: тесты продолженных комментариев проверяют корректные LF- и CRLF-заголовки при любом окончании строк в checkout.

Миграция

  • База a015f258b6e4cfe1c35e53f5439d7d6bf438276d (2026.1.78-dev). Повторите конфигурацию, сборку и bake перед упаковкой. Для прежнего отбора по ссылкам задайте Baking.FilterResources = True; для поставки всех текущих выходов опустите настройку или задайте False и уберите каталоги корней, служившие только фильтрации. Данные FixedType по-прежнему используют .foinfo. Конверсия сохранений не нужна; версия манифеста 1, runtime 0.0.82 и Managed ABI 9 прежние. Откат выполняется согласованными конфигурацией, бинарными файлами и запечёнными артефактами.
  • Нативные вызовы ResourceUsage::CreateManifest передают явный boolean filter_resources после build_hash и config_hash, перед callbacks доступности и зависимостей. Значение true сохраняет прежний отбор.

2026.1.78-dev - 2026-10-28

Исправлено

  • В русском руководстве изображений сохранены fragment ID грамматики FOFRM и скриптовых анимаций криттеров; восстановлены ссылки из истории изменений и руководства корневого движения спрайтов.
  • В реестре контрактов отражён опубликованный переход совместимости часов движения с runtime 0.0.81 на 0.0.82, включая совместную пересборку, развёртывание и откат.

  • Unity-фикстуры изолированы от параметров окружения CI; web/database-фикстуре передан обязательный корректный размер batch; проверенные счётчики корпуса примеров обновлены для нового примера сборки; пунктуация нового комментария теста нормализована; helper’ам нового теста видимости Map явно указаны пространства имён для Unity-компиляции.

  • Выходы bin/obj управляемых инструментов сборки исключены из сайта документации; аудит артефакта отклоняет их публикацию, сохраняя авторские исходники инструментов.

  • Сканирование SDK-макросов учитывает продолженные строки, комментарии и литералы C/C++, исключает похожий на директивы текст документации и сохраняет настоящие директивы после комментариев. Учтены физические переносы в raw-строках и числовые разделители; registry/header-регрессии выполняются в CI проверки обновления Engine. Правила отбора макросов, allowlist и формата вывода сохранены.

Миграция

База 248465a278cadec22004b9c461c2f3be41659a5e (2026.1.77-dev) → 2026.1.78-dev: исправлены сканирование SDK-заголовков, регрессионные фикстуры CI и документация. Пересоберите генератор и выполните его registry/header-тесты; перегенерируйте сайт и пакет документации для ИИ, затем повторите целевые проверки Unity, временной совместимости и примеров. Обновляйте инвентарь SDK только по закреплённым metadata и SDK, сохраняя существующий allowlist. Конверсия исходников, настроек, данных или сохранений не нужна. Runtime 0.0.82 и Managed ABI 9 прежние; согласованные комплекты развёртывания и отката совместимы.

2026.1.77-dev - 2026-10-28

Добавлено

Миграция

  • База 9f07d5b17eb54b0f3b6adceffabbefddaeb603e5 (2026.1.76-dev) → 2026.1.77-dev. API расширен; прежние значения и сохранения не меняются. Перегенерируйте привязки/метаданные, пересоберите native-роли и выпеките согласованные ресурсы. Унаследованный runtime 0.0.82 и Managed ABI 9 сохранены; бинарники, сборки и ресурсы обновляются и откатываются вместе.

2026.1.76-dev - 2026-10-28

Добавлено

  • Добавлена registry-backed генерация Source/Essentials/WinApiUndef.inc через BuildTools/WinApiUndefGenerator/WinApiUndefGenerator.Cli.csproj. Генератор читает официальный Windows.Win32.winmd и установленные SDK headers, добавляет только реальные macro aliases с PInvoke evidence или generic A/W alias, сохраняет macro-only записи и compile-proven allowlist, а активные #undef из allowlist удаляет. Повторная генерация даёт байт-идентичный результат. Закрепляйте версию metadata-пакета и записывайте её хэш.
  • Добавлена отдельная job unity в validate.yml для независимой проверки CMake Unity-сборки. Job задаёт FO_UNITY_BUILD=ON и FO_UNITY_BUILD_BATCH_SIZE=32, запускает configure/build fixtures, а затем обычный validator unit-tests. Она выполняется при all и доступна вручную через job: unity. Существующая job unit-tests сохраняет независимые translation units, а bundled third-party targets не объединяются.
  • Добавлена явно включаемая CMake Unity-сборка собственных core libraries и приложений. FO_UNITY_BUILD=ON выбирает режим BATCH; FO_UNITY_BUILD_BATCH_SIZE по умолчанию равен 32 и принимает только положительные десятичные целые. Обычные независимые translation units остаются режимом по умолчанию, а bundled third-party targets не объединяются. Повторяющиеся внутренние идентификаторы и протекание макросов между исходниками исправляются во владеющих исходниках, без исключения целых подсистем.

Миграция

  • База 6946ad2d1dc7b39487206d2015d1e24f63dea882 (2026.1.75-dev) → 2026.1.76-dev: повторно настройте затронутые build directories. Существующие конфигурации сохраняют FO_UNITY_BUILD=OFF; для включения настройте проект с -DFO_UNITY_BUILD=ON, при необходимости задайте положительное -DFO_UNITY_BUILD_BATCH_SIZE=<N> и пересоберите затронутые targets. Используйте генератор при обновлении инвентаря макросов Win32, просмотрите сгенерированный файл и выполните Unity и обычную Windows-сборку. Callable APIs, сохранённые данные, resource schemas, runtime compatibility markers, Managed ABI и configuration hashes запекания не изменились; миграция исходников, сохранённых данных или runtime не требуется. Откат восстанавливает прежние ревизию Engine, входные данные генератора, конфигурации CI и сборки вместе.

2026.1.75-dev - 2026-10-27

Исправлено

  • Все три генератора конфигураций примеров получают runtime-owned настройки из native-констант SettingNames. Native lexical masker исключает комментарии и литералы, поэтому generated defaults больше не присваивают значения, которые задаёт инициализация runtime.
  • Тесты Mapper удерживают выгруженные карты до завершающих проверок inspector, undo и redo, не читая уничтоженные карты через устаревшие ссылки.
  • Добавлен ScriptExceptions.OpenCaptureScope() для намеренных failure-injection сценариев. Перехваченные сообщения сохраняют исходный текст и все внешние/глобальные счётчики исключений, но не вызывают native-уведомление и автоматическое завершение unattended-приложения. Перехват следует логическому async-потоку и заканчивается при Dispose; посторонние потоки и отложенные ошибки Task сохраняют обычную native-обработку.
  • Регрессии регистрации и документации проверяют общий флаг запуска сервиса; пунктуация комментариев и оформление регрессионных тестов нормализованы без изменения соответствующего исполняемого кода.

Миграция

База 56287b1974adcedd3d0a3ec641e9a9eb49ff5247 (2026.1.74-dev) → 2026.1.75-dev: перегенерируйте каждый пример его generate_config.py, затем выполните --check. Существующим вызывающим конверсия исходников и сохранений не нужна; harness может явно перехватывать намеренно сообщаемые ошибки новым CoreScripts helper, сохраняя точные проверки и подтверждения исключений. Пересоберите native-роли и перепеките managed scripts/resources для согласованного развёртывания. Runtime 0.0.82, Managed ABI 9, существующие API и форматы данных не меняются относительно этой базы; откатывайте соответствующие binaries и ресурсы вместе.

2026.1.74-dev - 2026-10-27

Исправлено

  • Пакеты движения получают монотонное время отправки вместо времени кадра: ложная перемотка больше не телепортирует NPC в конечную точку маршрута.
  • Убран лимит размера полного пакета документации для ИИ: changelog и владеющие руководства сохраняются целиком, без сокращений.

Миграция

База 497af3a8d718fd7cd9074ac278a0021411c63bb6 (2026.1.73-dev) → 2026.1.74-dev: пересоберите native-роли/тесты и перегенерируйте выходные файлы документации; конверсия исходников/данных не нужна. Сгенерированный манифест документации больше не публикует full_context.max_bytes; потребители не должны требовать это поле. Native/script API и layout данных не изменились; runtime повышен с 0.0.81 до 0.0.82, Managed ABI 9 остаётся прежним. Развёртывание и откат выполняются согласованным комплектом.

2026.1.73-dev - 2026-10-26

Миграция

База 00c3c4cf5207ec7080179e4c9d455221ff1149d4 (2026.1.72-dev) → 2026.1.73-dev: изменены только комментарии; миграция не требуется.

2026.1.72-dev - 2026-10-26

Исправлено

  • Исправлены getters synctime на полном диапазоне и bytecode/lifetime/service assertions тестов.

Миграция

  • База 3cc3a490b8f5700a6370a4192f526bcaa1d04ab1 (2026.1.71-dev). Пересоберите/перепеките; конверсия исходников/данных не нужна. Единицы, API, форматы, runtime 0.0.81 и Managed ABI 9 прежние. Откат согласованными артефактами.

2026.1.71-dev - 2026-10-26

Исправлено

  • Исправлены noexcept libc++, типы, поиск, ссылки резервирования и defaults примера.

Миграция

  • От 4dc5c55f59240f45e0e2d9f9f2564261b3ffa471 (2026.1.70-dev). API/настройки/значения/форматы, runtime 0.0.81 и Managed ABI 9 прежние; без конверсии. Пересборка/генерация документации; откат согласованными артефактами.

2026.1.70-dev - 2026-10-26

Исправлено

  • Исправлены сдвиги камеры square, типизированный slot/cleanup handle результатов ScriptFunc и Git-зависимости build hash проекта, включая packed refs/worktrees. Snapshot fixtures используют runtime metadata; сохранены входящие isolation/shutdown checks.

Миграция

  • База fa15b0b7c57535af600b4212e39e2c20fa2abe4d (2026.1.69-dev) → 2026.1.70-dev: переконфигурируйте, пересоберите native/расширения и перепеките ресурсы. Конверсия исходников/сохранений не нужна: borrow результатов, cover, координаты и identity скомпилированного Baker сохраняют смысл. Runtime 0.0.81, Managed ABI 9, persisted formats и wire-аргументы RPC не меняются.

2026.1.69-dev - 2026-10-26

Миграция

База 6cff188c9b644732ab4e330c47a6cbdf739fcbcc (2026.1.68-dev) → 2026.1.69-dev: интегрированы FOFRM/ресурсы/время. Совместимость runtime становится 0.0.81; Managed ABI остаётся 9. Пересоберите и перепеките все роли, разворачивайте только согласованные артефакты. Значения сохранений и сетевые единицы сохраняют смысл.

  • Кадры импорта заменяют Width/Height на isize32 Size, NextX/NextY — на ipos32 Motion. Размещение остаётся Offset: знаковые центры BAM и bbox/center SPR, включая общие кадры, задают размещение; дельты FRM/ART остаются движением. В FOFRM Move/FrameMoves заменяются на Motion/FrameMotions; старые ключи отклоняются до разрешения зависимостей. Пересоберите baker и перезапеките корни BAM/SPR; проверки сужения и layout SpriteResource v3 сохраняются.
  • Native-переименования: GetCurSpr → GetCurrentSprite, GetSpr → GetSprite, GetDir → GetDirection, GetDirCount → GetDirectionCount, GetStateAnim/GetActionAnim → GetStateAnimation/GetActionAnimation, GetSprOffset(frame) → GetSpriteOffset(frame), RefreshParams → RefreshParameters, Sprite::SetDir и overrides → SetDirection. Обновите вызовы; GetCurrentDirection и API направления entity/model сохраняют имена. Размещение читает GetSpriteOffset(frame), движение — GetSpriteMotion().
  • SpriteSheet.GetWholeTicks → GetDuration, DurationMs/GetDurationMs кадров → Duration/GetDuration (timespan). Интервалы моделей/частиц, MovingContext/look-ahead, FogLayer.TransitionDuration и UDP retry типизированы. Секунды Ozz/backend/GPU и миллисекунды JSON отчёта bake остаются граничными преобразованиями. Delay принимает timespan; дробные преобразования сохраняют точность, конструкторы AS проверяют переполнение.
  • Замените целые FogLayer.TransitionDuration и числовые аргументы MovingContext.EvaluateProjectedHex: C# new timespan(150, 2) / new timespan(100, 2), AS timespan(150, 2) / timespan(100, 2). MovingContext.GetElapsedTime/GetWholeTime возвращают timespan; используйте его напрямую либо nanoseconds / 1_000_000.0 (native to_ms<float64_t>()) для дробных миллисекунд. milliseconds отбрасывает доли. Старые числовые вызовы не проходят проверку типов; временные значения не требуют миграции сохранений.
  • Привязки общих обрезанных кадров сохраняются в координатах холста по цепочке ссылок. Явная нулевая длительность native/script-последовательности сохраняет ручной выбор кадра; файловые таймлайны положительны. Обновления движущихся предметов с долями мс и двойная точность расчёта цикла модели сохраняют движение и конечную замороженную позу. Константы интервалов сохраняют значения/единицы; сборщики зависимостей стоят перед входами baker.
  • Удалены TextureAnimation и native-проигрывание текстур; многокадровые текстуры моделей отвергаются. Сохраняются статические Texture/Parent, FOFRM Size и UV полного холста. Перезапеките LFMODINF schema 5; LFMODMSH/LFOZZRIG прежние.
  • Полный bake сохраняет неиспользуемый арт и выпускает Resources.usage.json из типизированных Resource-корней, обязательных выходов и runtime-зависимостей. Упаковка требует согласованный manifest. Помечайте ресурсные свойства Resource; принудительно включайте пути script/GUI/config/непрозрачных форматов через обычные FixedType-массивы ресурсов, не конструкторы. Перед упаковкой выполните bake.

FOFRM и миграция ресурсов

  • Используйте PascalCase ключей/секций, Key = Value и продолжения с одним пробелом (без конечного слеша). Иные порядок/пробелы допустимы. Перенесите направление 0 в корень, разрешив конфликты полей; используйте [HexDir 1]..[HexDir 5] или [SquareDir 1]..[SquareDir 7] активной геометрии. Прежний порядок градусов hex 30/90/150/210/270/330 или square 45/90/135/180/225/270/315/0 соответствует индексам 0..N-1. Старые Dir/именованный ноль отклоняются до разрешения источников, без fallback.
  • fps → Fps; Alias → Source, Effect удаляется. offs_x/offs_y и OffsetX/OffsetY заменяются на Offset = X Y с сохранением carry. frm/Frm/frm_N/Frm_N заменяются взаимоисключающими непустыми Frame/Frames; Count удаляется, активные ссылки/повторы/порядок сохраняются. Frame содержит один полный путь; имена с пробелами в Frames заключайте в кавычки. Старый формат отклоняет FO_TEMPORARY_COMPAT(FofrmLegacyDescriptor, “2026-12-31”); отказы Alias/Effect также ограничены 2026-12-31.
  • NextX_N/NextY_N заменяются на FrameOffsets: одна пара знаковых int32 X Y на активную ссылку до разворачивания; отсутствующее поле означает нули. Пустые, неверные, выходящие за диапазон, несоответствующие числу ссылок и списки без ссылок запрещены. Offset и дочерние смещения кадра складываются один раз без накопления/изменения импортированных дельт; размещение дочерней последовательности отбрасывается, carry Offset сохраняется. Переполнение int32 запрещено. Size/FrameSizes меняет размер W H в 1..65535, смещения остаются в заданных пикселях.
  • Source наследует целые коллекции/направления/размещение/движение/тайминг; корневые преобразования служат умолчанием всем направлениям. Массивы ссылок применяются до grid/разворачивания, FrameIndices — после. Frame/Frames по умолчанию считает 10 кадров/с по итоговым кадрам. Duration/FrameDurations — положительные миллисекунды; локальное время приоритетнее корневого, смена направления сохраняет фазу разных таймлайнов. Fps именованного направления и Fps0 запрещены; legacy-clock ноль нормализуется до 10 fps, положительные доли мс — до 1 мс. Прежние Color/Encoded/Bilinear сохраняют байты; Data/Normal исключают alpha crop и запрещают ColorSpace, Area не увеличивает изображение. Композиция/фильтры: грамматика FOFRM.
  • Корни FOFRM подавляют транзитивные входы между фильтрованными пакетами/overlay. Прямые ссылки game/model/UI/script на потреблённые изображения/промежуточные FOFRM замените отдельными корневыми обёртками; входы монтируйте явно. Фильтры выходов сохраняют зависимости; загрузчики NewName объявляют ResolveOutput. Пропуски/циклы и более 64 узлов FOFRM запрещены до преобразования. Отпечатки содержимого обновляют зависимости и SpriteInfo при прежнем stat, включая отложенную выпечку; удаление последней ссылки возвращает самостоятельный выход. Приватные .baker-cache/Image/ snapshots не поставляются.
  • Sprite v3/SpriteInfo2 требуют полной выпечки изображений. Общие пиксели сохраняют раздельное время/смещения/движение. Конечное продолжение ConfigFile одинаково работает у EOF и с переводом строки; пустые значения проверяет потребитель.

2026.1.68-dev - 2026-10-26

Исправлено

  • Регистрация Windows-службы записывает тот же параметр server-service-start, который читает точка входа службы. Для существующих регистраций с прежним нераспознаваемым суффиксом --server-service администратор должен обновить команду запуска либо пересоздать регистрацию обновлённой утилитой.

  • Нативные потребители именованных аргументов используют общий разбор CommandLineArgs: пути runtime host, выбор конфига/subconfig, writable root, fork и флаги Windows-службы. GetSettings() сохраняет порядок повторов, GetSettingValue(name, std::nullopt) выбирает последнее явное значение. Раннее чтение теперь удаляет пробелы по краям имён опций так же, как обычное применение настроек. Встроенные имена используют константы SettingNames, сформированные из Settings.inc в Common.h; имена только для командной строки остаются в CommandLineSettings. Нативным потребителям нужно заменить CommandLineSettings::CommonNonInteractive, CommonUserWritablePath и ClientForceEmbeddedRuntime на соответствующие константы SettingNames. Идентификаторы констант настроек используют Group_Name, например SettingNames::Common_NonInteractive; нативные обращения с прежним слитным написанием GroupName нужно обновить. Имена ключей конфигурации с точкой и их значения сохраняются.

  • Headless-приложения всегда сообщают о неинтерактивном режиме и записывают ошибку в лог перед запросом завершения с ошибкой, в том числе при Common.NonInteractive = False. IsNonInteractiveMode() доступна через Application.h; обработка сообщений находится в графической и headless-реализациях приложения.

  • Раннее чтение Common.NonInteractive и Client.ForceEmbeddedRuntime использует общий поиск CommandLineArgs::GetSettingValue, сохраняя последнее вхождение, неявное значение флага и интерпретацию текста каждой вызывающей стороной.

  • Common.NonInteractive устраняет блокировку автоматизированных запусков системными окнами ошибок. Сообщение и стек сохраняются в логе, затем выбирается путь завершения с ошибкой, соответствующий Exit, включая прямые вызовы и ошибки до создания приложения.

Документация

  • Сохранены проверенный бюджет полного AI-пакета и состав целых документов из ADR-0003; выдача перегенерируется после интеграции описания CLI и политики ошибок.

Миграция

  • Средствам автоматизированного запуска графических приложений следует передавать --Common.NonInteractive True. Headless-приложения не требуют флага. По умолчанию остаётся False; проект может включить режим в startup hook для агентских сессий. Изменение сетевого протокола, сохранённых данных или вызовов скриптов не требуется.

  • База 5c32423c1f05f1c42aaa81b02497f4fec79afca7 (2026.1.67-dev) -> 2026.1.68-dev. Перед развёртыванием совместно пересоберите native-приложения и пересоздайте API/metadata и baked resources. Существующие settings сохраняют значения и defaults; Common.NonInteractive является новой readonly boolean-настройкой с default False. Конверсия сохранённых данных не нужна; wire 0.0.80, Managed ABI 9, форматы ресурсов и client-host ABI не меняются. Откат возвращает согласованные прежние binaries и resources.
  • Нативный startup использует CommandLineArgs::GetSettingValue(name, implicit_value) и упорядоченный GetSettings(name) с общими именами CommandLineSettings. Views заимствуют argv; вызывающая сторона сохраняет его владельца. Default scalar-значение — "1"; std::nullopt пропускает вхождения без значения. Явная пустая строка и отрицательные числа остаются значениями. Каждое вхождение config/sub-config по-прежнему требует значения; сохраняются порядок append/sub-config и первый допустимый writable root. Существующие script calls не удаляются и не переименовываются; проекты, использующие helpers, пересобираются с текущими headers. Автоматические graphical launchers передают non-interactive-флаг до создания процесса; config/startup hook начинает действовать только после загрузки settings. В этом режиме системные error dialogs заменены записью log/error trace и failed quit. Обычные графические запуски сохраняют модальные ошибки; headless-приложения всегда используют non-interactive-путь.

2026.1.67-dev - 2026-10-26

Добавлено

  • Независимый watchdog наблюдает незавершённые входящие серверные RPC и полные входные фреймы в очереди. Настройки ServerNetwork.RemoteCallWarningTimeMs, RemoteCallDisconnectTimeMs, RemoteCallWarningIntervalMs, MaxPendingRemoteCalls по умолчанию равны 1000, 30000, 10000, 256. Ноль независимо отключает реакцию по возрасту или предел допуска; отрицательные настройки отвергаются при запуске. Диагностика содержит идентификаторы/счётчики вызовов и готовность очереди без аргументов.

Изменено

  • RPC используют общее с ожидающими временными событиями владение завершением script backend. Managed-регистрация передаёт прямые Task-делегаты, включая Task<T>, приведённый к объявленному Task; wire-результат остаётся void, синхронные Action-adapters сохраняются. Detached-завершение RPC может учитываться без script pump; завершение таймера сохраняет скриптовый контекст. Teardown закрывает вход фоновых completion до освобождения backend. Отмена освобождает учёт, не становясь ошибкой скрипта.

Миграция

  • База f29635c8dce0c3c4b39c30fd6d31ab0059f568db (2026.1.66-dev) → 2026.1.67-dev. Маркер runtime-совместимости 0.0.79 → 0.0.80; пересоберите native-приложения/расширения и перепеките все роли скриптов с согласованными CoreScripts. Native BaseEngine::RemoteCallHandler получает четвёртый аргумент shared_ptr<ScriptCallCompletion>: сохраняйте его до завершения/отказа от отложенного native-обработчика. Обычный синхронный native-обработчик может его игнорировать. Интеграции backend используют FuncCallData::Completion; включать CompletionOnAnyThread можно только для detached callbacks. Старые присваивания обработчика с тремя аргументами отвергаются native-компилятором; compatibility shim не добавлен.
  • Проверьте настройки отключения выше с учётом законных долгих обработчиков. Отключение закрывает транспорт с новым DisconnectReason::RpcRuntimeLimit = 11; оно не отменяет произвольные Tasks, не прерывает код и не откатывает игровые эффекты. Значения причин 0..10, wire-аргументы RPC, сохранённые значения, ABI managed-генератора 9 и форматы ресурсов сохраняют смысл. Конверсия сохранённых данных не нужна. Публикуйте согласованные бинарные файлы/ресурсы вместе; несовместимые комплекты отвергаются идентификатором совместимости. Откат восстанавливает прежние согласованные бинарные файлы/ресурсы и конфигурацию вместе.

2026.1.66-dev - 2026-10-26

Исправлено

  • В MigrationRule для Rename, Transform и Remove разрешены legacy source-идентификаторы с whitespace, заключённые в двойные кавычки. Голая последовательность слов, пустые аргументы, незакрытые кавычки и replacement с whitespace отклоняются. Общий tokenizer остальных metadata-тегов не изменён.

Изменено

  • Запрещён whitespace в authored prototype ID после разрешения $Name/file-stem и до разрешения миграций, хеширования или проверки дубликатов. Слеш и знак доллара по-прежнему зарезервированы для адресации вложенных секций.

Миграция

  • Переименуйте authored prototype ID с whitespace и сохраните прежнее имя только как quoted source, например ///@ MigrationRule Proto Modifier Rename "Local knowledge" LocalKnowledge. Обновите native и Python readers совместно, пересоздайте metadata и запеките согласованные ресурсы. Существующие сохранённые ID загружаются через эти правила; изменение runtime compatibility-marker или Managed ABI не требуется.

2026.1.65-dev - 2026-10-26

Добавлено

  • Добавлена native-пауза симуляции с независимым ручным, именованным и стартовым владением. Задачи таймеров/движений и кадровая обработка скриптов останавливаются, а обслуживание соединений, игроков и служебных задач продолжается. Полная quiescence сохраняет уже существующую паузу и отвергает повторный вход в управление до захвата mutex. Состояние жизненного цикла сессии доступно через native-запрос и health-вывод.
  • Снимок формата 4 сохраняет именованные таймеры и движения персистентного мира: границу выданных id таймеров, конкретную сигнатуру callback, остаток задержки, карту, прогресс и лимит разрешённого движения. Исполнение восстанавливается на часах нового процесса без повторного события начала движения. Неподдерживаемые владельцы, delegate-callback и незавершённая Managed-работа блокируют снимок; native-проект может добавить собственную подсчитанную диагностику допустимости.
  • Задержки удерживаемых типов worker сохраняются при подаче, пробуждении и отложенном повторном запуске; весь запрос удержания проверяется до изменения планировщика. Выданные id таймеров резервируются до стартовых callback, а исчерпание id отвергается вместо переполнения до нуля.

Миграция

  • При переходе с 2026.1.64-dev пересоберите native-роли, заново сгенерируйте/выпеките согласованные ресурсы сервера/клиента и Managed-сборки. Маркер совместимости меняется с 78 на 79; Managed ABI остаётся 9. Обновляйте и откатывайте согласованные бинарники, сборки и ресурсы вместе.
  • Native-потребитель снимков должен строго разбирать и заполнять формат 4, включая LastTimeEventId, именованные TimeEvents и CritterMovements с лимитом движения. Формат 1 и донорские 2/3 отвергаются: явно конвертируйте контейнер проекта с согласованным миром либо создайте новый снимок согласованными ресурсами. Движок предоставляет состояние/байты, а не парсер контейнера. Неудачно восстановленную сессию необходимо уничтожить.
  • Владельцы снимка должны быть достижимы обычным восстановлением персистентного мира; отсоединённые/временные владельцы и движение прикреплённых криттеров блокируют снимок. Проект не должен повторно создавать захваченные таймеры в init-callback и обязан добавить проверки собственного состояния, существующего только в памяти. Пауза является native-возможностью встраивания и не включается как игровая политика. Стартовое время заморожено через init/restore/start callback; долговременные именованные удержания явно восстанавливает контроллер проекта. Имеющиеся настройки, id скриптовых методов/событий и значения персистентных свойств сохраняют смысл.

2026.1.64-dev - 2026-10-26

Исправлено

  • Списки ID постоянных серверных держателей больше не изменяются в хранилище при отказе восстановления криттера. Частичный runtime-граф по-прежнему сокращается, но повторная загрузка сохраняет исходные постоянные ссылки и ошибку; восстановление отсутствующего дочернего документа возвращает весь граф. Успешные изменения pre-load и явные миграции продолжают сохраняться обычным образом.

Миграция

  • База 17b4dab02495de2f2877e552d7811dd48951fc41 (2026.1.63-dev) → 2026.1.64-dev. Конверсия данных проекта не требуется: публичные API, схемы сохранений, форматы ресурсов, runtime compatibility 0.0.78 и Managed ABI 9 не изменились. Прежняя низкоуровневая семантика сокращения runtime-списков сохранена; только неуспешное восстановление верхнего уровня больше не записывает частичные списки. Пересобрать затронутые серверные роли и native-тесты, а для развёртывания использовать серверные и клиентские ресурсы одной согласованной выпечки. Откат восстанавливает прежние согласованные binaries и ресурсы вместе.

2026.1.63-dev - 2026-10-25

Исправлено

  • Проекты CMake могут не задавать FO_APP_ICON. Пустое значение больше не вызывает ошибку конфигурации FO_APP_ICON not specified и не создаёт ресурс значка; явный путь к значку сохраняет прежний сгенерированный ресурс.

Миграция

  • База 4588149fa4e4493ed6dddfea0a2fdf65d17c1f3e (2026.1.62-dev) → 2026.1.63-dev. Это расширение только конфигурации, а не изменение runtime, сети, сохранённых данных или ABI. Совместимость runtime остаётся 0.0.78, Managed ABI 9 и версия контейнера спрайтов прежними. Конверсия сохранений не требуется. Откат восстанавливает согласованные предыдущие исходники CMake и сгенерированные справочники.
  • Проекты, которые уже задают FO_APP_ICON, не нуждаются в изменении исходников или контента: выполните обычные reconfigure и rebuild, сохранив тот же абсолютный путь значка и ресурс 101 ICON. Пример и validation-проект без значка теперь конфигурируются успешно и получают пустой .rc вместо 101 ICON "". Объявления ищутся через rg -n "FO_APP_ICON" <project-cmake-and-interface-paths>; прежняя ошибка была диагностикой configure FO_APP_ICON not specified. Не подставляйте значок другого проекта и не восстанавливайте удалённый ресурс только ради старого требования.
  • Перегенерируйте модель CMake и справочники через python BuildTools/docs_cmake.py --write, затем выполните целевые тесты конфигурации/документации и полный contract diff. test_actual_scaffold_configures_without_app_icon запускает настоящий configure validation-проекта и проверяет отсутствие ресурса значка. Конфигурации с непустым значком требуют прежних проверок сборки и пакета. Маркер совместимости runtime, сетевой протокол, сохранённые свойства, схема ресурсов и идентичность updater не меняются.

2026.1.62-dev - 2026-10-24

Исправлено

  • Выполняющееся TimeEvent остаётся зарегистрированным и приостановленным во время managed await и AngelScript Yield. Изменения контекста и срок повтора применяются после окончательного завершения скрипта; отмена и очистка владельца исключают восстановление события поздним завершением. Сохраняется прежняя политика ошибок: явный Repeat контекста действует после ошибочного вызова, Stop имеет приоритет, а ошибка без явного перевзвода удаляет событие.

Изменено

  • Во все overloads Game/entity CountTimeEvent (callback и ID) Managed и AngelScript добавлен bool excludeExecuting = false. По умолчанию считаются все подходящие зарегистрированные записи; true исключает выполняющийся или приостановленный в await/Yield callback до финализации. Изменение и отмена по-прежнему обращаются к зарегистрированной записи.

Миграция

  • Собственные native-dispatcher используют TimeEventManager::FireAndAdvance(entity, event_id) вместо удалённого результата FiredTimeEvent и раздельной публичной пары FireTimeEvent / PostFireTimeEvent. Менеджер владеет приостановленным выполнением и финализацией; вызывающая сторона сохраняет блокировку владельца и повторно ставит задание с возвращённой optional-задержкой. Schedule/cancel hooks сохраняются до остановки всех производителей продолжений. Найти в собственных native sources FiredTimeEvent, FireTimeEvent и PostFireTimeEvent; прежние прямые вызовы не компилируются C++.

  • Сигнатуры таймеров, ID, единицы, интервалы по умолчанию и форматы сохранений прежние. Исправлено преждевременное завершение: проверить код, который рассчитывал на перекрытие повторов или раннее удаление одноразового события. Пересобрать все затронутые native-роли, managed assemblies и согласованные ресурсы одной запеканкой. Конверсия сохранений не нужна. Runtime меняется с 0.0.77 на 0.0.78 для native/managed completion bridge; Managed ABI остаётся 9. Смешанные старые/новые binaries или ресурсы не поддерживаются. База: af0770a5ef98ef31fa57c448f27ed4ce3fa86ee4 (2026.1.61-dev); этот шаг — 2026.1.62-dev.

  • Проверить все вызовы CountTimeEvent (rg -n "CountTimeEvent" <script-and-native-source-dirs>). Singleton guards, активный статус и ожидание completion сохраняют включающий выполнение подсчёт по умолчанию. One-shot остаётся зарегистрированным до terminal completion, поэтому коалесцирование снимков явно исключает выполнение: Managed owner.CountTimeEvent(Callback, excludeExecuting: true) или Game.CountTimeEvent(id, excludeExecuting: true); AngelScript owner.CountTimeEvent(Callback, true) или Game.CountTimeEvent(id, true); native manager.CountTimeEvent(entity, func_name, id, true). Рядом с выполняющимся снимком можно поставить отдельный one-shot. Старый scheduler сохранял повторяющиеся записи, но удалял one-shot после возврата первого вызова; ни одно значение флага не воспроизводит эту смешанную политику времени жизни целиком. Прежние аргументы, ID и единицы сохраняют смысл. Перед bake пересоздать оба backend и скомпилировать Server/Client/Mapper.

2026.1.61-dev - 2026-10-24

Исправлено

  • Сохранены дробные миллисекунды при перемещении спрайтов предметов: на клиентах с высокой частотой кадров больше не теряется часть перемещения на каждом обновлении.

Изменено

  • Отозваны предложенные в ПР #227 клиентские/мапперные Map.BlockHex(mpos hex, bool full) и Map.UnblockHex(mpos hex). Серверные ручные блокировки не передаются клиентам, поэтому независимые локальные флаги не обеспечивают согласованный поиск пути и приводят к повторным серверным коррекциям движения. Локальные флаги, нативный setter и их тесты удалены: неполный механизм больше не предоставляется проектам.

Миграция

  • База 57424cb5d2ac132b1fa8ba83e353d07cb6ca75e0 (2026.1.60-dev) → 2026.1.61-dev. Опубликованный API master не изменён; отзыв затрагивает только пользователей прежних вершин ПР #227 9c8237b0520041e3de78d878829c25c59ed5e030 и 6f31a6404207310332a39703ef784f26b054e644. Удалить клиентские/мапперные вызовы Map.BlockHex и Map.UnblockHex из AngelScript/managed-кода, а также нативные обращения к MapView::SetHexManualBlock и флагам Field::ManualBlock / ManualBlockFull. Замены клиентского API нет: будущий серверный механизм должен синхронизировать начальное состояние и обновления до предоставления проектам. Существующие серверные методы сохраняют поведение и не заменяют клиентские вызовы.
  • Найти затронутые исходники командой rg -n 'BlockHex|UnblockHex|SetHexManualBlock|ManualBlockFull' <project-source-dirs> и проверить сторону каждого использования: клиентские/мапперные вызовы скриптов не компилируются с пересозданными bindings; нативные обращения не компилируются из-за отсутствующих объявлений. Пересоздать метаданные, пересобрать затронутые binaries и совместно перепечь соответствующие ресурсы клиента/маппера. Обычные препятствия предметов/карт и синхронизация их свойств прежние. Конверсия сохранённых данных и формата ресурсов не требуется; маркер runtime остаётся 0.0.77, Managed ABI 9 и контейнер спрайтов v2 прежние. При откате восстанавливать binaries и baked-ресурсы вместе; прежние сборки ПР возвращают несинхронизированный API.

2026.1.60-dev - 2026-10-23

Добавлено

  • Добавлена перегрузка Game.LoadCritter(crId, forPlayer, map) для обоих scripting backends. Управляемый игроком криттер или NPC восстанавливается непосредственно на сохранённой карте, hex и направлении с прежним порядком preload/init/load, инвентарём, отказом дубликатам и сохранением восстанавливаемых записей при неудачной загрузке отсоединённого графа. Прежняя перегрузка с двумя аргументами сохраняет глобальную карту; обе перегрузки теперь объявляют существующую гарантию покрытия результата через FO_PROVIDES_COVER. Предварительное чтение сохранённого поля выполняется через Game.DbGetRecord. При локальном восстановлении OnMapCritterIn вызывается перед init; первичная видимость обрабатывается после init, поэтому созданные в нём подписки получают первые появления. Если callback переместил восстановленного криттера, локальное восстановление сообщает об отказе исключением, сохраняя его валидные последствия. Рассылка видимости предметов прекращается при уничтожении наблюдателя или его уходе с карты.
  • Добавлены нативные ServerEngine::OnPlayerPreLogin до любого пути регистрации/reconnect и OnPlayerPreProcess перед каждым полным сообщением вошедшего игрока. Pre-login отказ или недействительный кандидат прекращают вход до мутации; per-message отказ, уничтожение, отключение или замена соединения прекращают dispatch; без подписчиков политика допуска не устанавливается.
  • Добавлена opt-in настройка ClientNetwork.RequireInterthreadTransport (по умолчанию false): она требует внутрипроцессный listener и немедленно отклоняет подключение без него; выключенная настройка сохраняет прежний выбор транспорта.
  • Host/interthread и dedicated/TCP проверяются двумя клиентами с одним gameplay worker: все 64 запроса изменения мира должны дойти до обработчиков без потерянных обновлений.

Миграция

  • При переходе с 2026.1.59-dev пересоберите нативные роли и заново сгенерируйте/запеките серверные и клиентские script resources на одной ревизии Engine. Центральный compatibility marker повышен с 76 до 77 из-за границы допуска сообщений игрока и metadata новых API/настройки; клиенту и серверу нужны согласованные пересобранные ресурсы. Не смешивайте предыдущие binaries и baked metadata. Откат восстанавливает прежний согласованный комплект binaries, assemblies и ресурсов.
  • Прежние методы, события, настройки, сохранённые свойства, числовые id, единицы таймеров, resource schema и Managed ABI 9 не удалены и не переосмыслены. Game.LoadCritter(crId, forPlayer) сохраняет загрузку на глобальную карту; преобразование сохранённых данных не требуется. Нативный EntityManager::LoadCritter теперь принимает (cr_id, for_player, nptr<ident_t> stored_map_id, bool& is_error): обновите нативные вызовы, передав выходной borrow для сохранённого id карты либо nullptr, если он не нужен, перед последним флагом ошибки. Загрузчик записывает восстановленный id карты до очистки MapId отсоединённого криттера; более ранний отказ не меняет выход, а назначение проверяет вызывающий код. Нативный ServerEngine::LoadCritter(cr_id, for_player, nptr<Map> map = nullptr) теперь обрабатывает оба назначения; обычные вызовы с двумя аргументами используют отсутствие карты по умолчанию, а явная карта сохраняет восстановление на сохранённой карте. Обе скриптовые перегрузки предоставляют покрытие свежего криттера; только перегрузка с картой требует уже подготовленного покрытия целевой карты вызывающим кодом. Перегенерируйте bindings обоих backends, чтобы Managed-анализатор видел гарантию покрытия результата обеих перегрузок. Перекомпилируйте Managed-код: FOSYNC015 теперь может отвергнуть лишний Sync.Widen уже покрытого результата. Если вызов только проверял время жизни, замените его проверкой IsDestroyed; сохраните захваты, нужные для других сущностей или после освобождения покрытия.
  • Embedded-клиенты могут включить ClientNetwork.RequireInterthreadTransport = True; обычные клиенты оставляют false. Нативные расширения подписываются на события допуска непосредственно: это не ///@ EngineHook entry points и не экспортированные события скриптов Game.On*. Pre-login отказ предшествует регистрации, работе с БД, замене соединения и login success; per-message отказ прекращает queued input до dispatch. Аутентификацией, допуском кампании и автоматическим восстановлением roster владеет проект. Необязательное использование ищется через rg -n "RequireInterthreadTransport|OnPlayerPreLogin|OnPlayerPreProcess|LoadCritter" <project-source-paths>; неиспользуемые hooks и restore API не требуют правок скриптов. Проекты с явной инициализацией всех настроек Engine должны добавить ClientNetwork.RequireInterthreadTransport = False, сохранив обычные сетевые клиенты; config baker отклоняет неинициализированную настройку.

2026.1.59-dev - 2026-10-23

Исправлено

  • Замороженный проектом выбор позы/движения сохраняет действие на слой 3D-locomotion, пока действие в очереди проигрывается независимо. Добавлена регрессия перекрывающихся выборов; сохранён контроль для замороженного действия в очереди.
  • В fixture повторного входа в sprite cache используется явное mutable-заимствование ячейки наблюдателя. Время жизни наблюдаемой копии сохраняется без поля-ссылки класса.

Документация

  • Инструкции агентам переработаны в компактный вход с маршрутами и обязательными общими правилами. Подробные контракты native-кода, жизненного цикла, managed-кода, конфигурации и документации остаются в профильных руководствах.
  • В английских руководствах и русских переводах уточнены смысловые группы кода, безопасность исключений, владение свойствами и временем жизни, представления неизменяемых данных и границы проверок.

Миграция

  • База 62102cfedbd165d9ce73c600f78cb4e5750afbdc (2026.1.58-dev) → 2026.1.59-dev. Новых API/настроек проекта или конверсии сохранений нет: существующие числовые идентификаторы, единицы и форматы прежние. Замороженный выбор позы/движения продолжает отключать визуальный слой locomotion, пока действие в очереди использует собственные параметры воспроизведения; логическое перемещение не меняется. Пересобрать затронутые клиенты/Mapper. Runtime 0.0.76, Managed ABI 9 и sprite container v2 прежние. При обновлении с более ранних версий необходимо выполнить предыдущую миграцию ниже. Перегенерировать и проверить документацию; откат восстанавливает согласованные предыдущие binaries, документацию и версию вместе.

2026.1.58-dev - 2026-10-23

Изменено

  • Накопление дельт, проекция цикла, перенос фазы, выбор кадра и визуальная компенсация выделены в AnimationMovement. CritterHexView сохраняет состояние движения и привязки; арифметика, жизненный цикл, скриптовые API и форматы ресурсов прежние.

  • Обычные смещения спрайтов хранятся в SpriteSheet::_sprOffset, покадровые дельты визуального переноса — в _sprMotion. SetFrame(offset, motion) записывает соответствующие поля; нативный GetSprOffset(frame) читает обычное смещение, а GetSprMotion() заменяет прежний span дельт GetSprOffset(). CritterHexView вычисляет накопленный перенос, компенсацию и фазу цикла по дельтам motion. Общие GetSpriteFrameOffset/GetSpriteFrameMotion и явные массивы offsets,motions предоставляют эти значения игровым скриптам.

  • Абсолютные смещения кадров хранятся в SpriteSheet; используются исходные общие спрайты атласа без отдельной обёртки AtlasSprite для каждого смещения. Перемещения кадров, позиция света и логические опоры остаются независимыми.

  • Перенести загрузку спрайтов, фабрики, кеши шаблонов/ошибок и инвалидацию в ResourceManager. Оставить SpriteManager отрисовку; выделить CritterFramesCache и модели превью Mapper. Сохранить независимое воспроизведение, повторные попытки, очистку и скриптовый API.

  • Удалены настройки движка View.GlobalDayColorTime и View.GlobalDayColor: кривые суток принадлежат коду/контенту проекта, вычисленные цвета передаются через Map.SetDayColors.

  • Перенести в проекты выбор воспроизведения и движения анимаций, позы превью, препятствия для пути, плоскую отрисовку персонажей, исторические игровые сообщения и тематические ресурсы/defaults. Native идентификаторы анимаций непрозрачны; параметры контекста/воспроизведения задаются явно. Android сохраняет значок платформы, если проект не указал свой.

  • Перенесены из ResourceManager в скрипты проекта правила имён Fallout, опорных смещений, выбора кадров и склейки. Два специализированных события заменены на OnCritterAnimationSprite и общие операции чтения/создания 2D-спрайтов. Копии источников и кеш handle разделены по атласам.

Исправлено

  • Не отдавать квант планировщику в последнем коротком интервале precise_sleep: другой готовый поток мог задержать возврат на целый квант. Существующие пороги тестов сна сохранены; вытеснение потока ОС всё равно может задержать ожидание.

  • WebSocket-регрессия завершения соединения ожидает callback победившего вызова Disconnect перед проверкой счётчика. Конкурирующие вызовы могут завершиться, пока IO-поток ещё сообщает об отключении; тест по-прежнему требует ровно один callback до и после остановки endpoint. Сетевой код не изменён.

  • Тест вложенной синхронизации ограничивает время отсутствия прогресса и общую длительность, удерживая криттеров до завершения обоих потоков даже при остановке сервера по таймауту. Медленное продвижение больше не считается взаимоблокировкой; реализация синхронизации движка не менялась.

  • Handle спрайта удаляется из активных до остановки ресурса, поэтому исключение Stop не оставляет его действительным. Прямой вызов сохраняет исключение остановки; cleanup резолвера диагностирует его, сохраняя результат резолвера либо исходное исключение.

  • Правки свойств в Mapper применяются через нативные setter и post-setter после проверки всех затронутых предметов. Состояние изменений и история отмены остаются у редактируемой карты, если обработчик переключает карты, выгружает карту или удаляет другой затронутый предмет.

  • Ключ кеша кадров персонажей теперь хранит полный кортеж модели, состояния и действия со штатным хешером; подстановка анимации не меняет ключ исходного запроса. При повторном входе в разрешение анимации возвращается уже вставленная запись кеша, включая сохранённое отсутствие анимации.

  • Область ABI для возврата значений AngelScript сохраняется при исключении нативного вызова; явно освобождаются только принадлежащие вызову результаты-handle.

Миграция

  • Маркер runtime повышен с upstream 0.0.75 до 0.0.76 для переноса игровой политики и API в проект. Клиенты, сервер, metadata и ресурсы пересобираются и устанавливаются согласованным набором; смешанные артефакты должны отклоняться проверкой совместимости. Ниже сохранены миграции upstream 36–57, включая проверку свойств динамических предметов на картах и актуальные контракты файловой системы/сохранения данных.

  • База aafc7fe74bb8fa35e6395e04d8c6d2a66a91831a (2026.1.57-dev), цель 2026.1.58-dev. Полная миграция скриптовых анимаций описывает обе удалённые сигнатуры событий, замену нативного resolver, оба backend, владение, массивы, смещения, единицы длительности, поиск, сборку/bake и откат. Runtime 0.0.76, контейнер sprite v2 и Managed ABI 9 прежние. Преобразование сохранений не нужно; смыслы enum остаются игровыми и не меняются.

2026.1.57-dev - 2026-10-20

Документация

  • Нормализованы нативные комментарии и проверки документации резервирования JSON/SQLite; описана грамматика пути и объединены заметки ClassExtension.

Миграция

  • База 6c88391e77d519885d54f8894d0781a7d0a14ee6 (2026.1.56-dev) → 2026.1.57-dev. Существующие API, конфигурация, форматы данных/ресурсов и значения не меняются; сетевой маркер 0.0.75, Managed ABI 9. Преобразование не требуется. Перегенерируйте и проверьте документацию, пересоберите согласованные нативные метаданные/приложения и перепеките ресурсы. Откат возвращает предыдущие согласованные артефакты.

2026.1.56-dev - 2026-10-20

Добавлено

  • fs::write_file_durable_new эксклюзивно записывает новый файл с flush descriptor через существующие native path и stream primitives. Существующие имена сохраняются; атомарная публикация через stage остаётся контрактом fs::write_file/fs::replace_file.
  • DataBase::TryInsert и типизированный CompareExchange действуют внутри одного экземпляра, видят pending-очередь и сериализуются с обычными мутациями, восстановлением snapshot и очисткой очереди. Game.DbTryInsertRecord и Game.DbCompareExchangeRecordString доступны с целочисленными и строковыми ключами в обоих скриптовых backend.

Удалено

  • Удалена неиспользуемая заготовка ClassExtensionAttribute. Она не связывала глобальную функцию с методом класса; в C# используются языковые extension methods, соответствующий тег AngelScript не планируется.

Исправлено

  • Отвергать встроенный NUL на всех границах файловых путей и неверный UTF-8 до native conversion на каждой платформе. Использовать общую проверку UTF-8 code points за один проход вместе с проверкой NUL, сохраняя запрет маркера ошибки U+FFFD и отвергая суррогатные кодировки; проверять также результат native-to-string. Учитывать ошибки I/O conversion и сохранять буквальные обратные слеши POSIX. Согласовать noexcept всех файловых операций с результатом, локально обрабатывая ошибки native conversion, создания/чтения собственного потока и итераторов. Неожиданные C++-исключения на внутренних границах STL возвращают результат отказа операции. Преобразования путей, standard-stream interop, чужие stream/visitor могут бросать; partial listing и hash до EOF сохраняются.
  • Standalone archive-проба LibreSSL использует lean Windows headers, чтобы макросы WinCrypt не конфликтовали с X509 declarations; проверки AES, TLS, X509 и SRTP сохраняются при включённом и выключенном assembly.
  • Поколения активных чтений БД не дают конкурентному читателю скрыть завершённый commit от более раннего чтения и допустить условную мутацию по устаревшему значению.
  • JSON/SQLite сохраняют внутренние пробелы в каталоге хранилища, разбирая весь остаток после имени провайдера с удалением внешних пробелов, в том числе при внешних пробелах строки подключения.

Миграция

  • База 8af9a71307196a1937c79389e83036d2face5ceb (2026.1.55-dev); обновление 2026.1.56-dev. Существующие файловые helpers, обычные методы БД и допустимые строки подключения сохраняют смысл. Создание нового файла показывает имя во время записи и синхронизирует только содержимое; если читателям нужна готовая публикация, используйте приватный stage и атомарную замену. Успех условной операции ставит мутацию в очередь одного владеющего экземпляра; это не durable commit, межпроцессная транзакция или native backend CAS.
  • Пересоберите native-потребителей/Baker и выпеките все скриптовые роли для согласования generated API/метаданных и assemblies. Потребители могут явно применять два новых метода; переименование существующих вызовов и автоматическое включение игровой функции не требуются. Для внутренних пробелов пути JSON/SQLite escaping не нужен; снятие буквальных кавычек не входит в грамматику подключения. Токены Memory/Mongo и диагностика отключённых провайдеров прежние.
  • Преобразований entity/property, JSON/CBOR/BSON/oplog, snapshot, baked-resource или wire format нет. Ручной runtime marker меняется с 0.0.74 на 0.0.75; Managed ABI 9 прежний; пересоздайте производные API/compatibility-метаданные и выкатывайте согласованные binaries/resources. Откат использует соответствующие прежние build/resources без преобразования данных. Проверьте native contention/pending/restore barriers, обе привязки, повторное открытие local providers с пробелами, файловые успехи и отказы на каждой заявленной платформе.
  • Передавайте в filesystem полные пути без NUL в корректном UTF-8 на каждой платформе. Не-UTF-8 POSIX-имена больше не поддерживаются fs. Чистые преобразования теперь отвергают неверный путь через filesystem_error; результатные примитивы отказывают без обращения к префиксу. Пересоберите native consumers из-за exception specifications read/write/hash/comparison/listing. Операции с результатом теперь передают стандартные interop errors результатом отказа; чрезмерный размер полного чтения отвергается до выделения буфера. Engine terminate-on-OOM policy прежняя. Исключения visitor и потока вызывающего кода продолжают передаваться; корректные пути, пустые пути и гарантии публикации/durability сохраняются.

  • Удалите [ClassExtension]; используйте стандартные extension methods C# и пересоберите скрипты с текущими CoreScripts. Компилятор отвергает удалённый атрибут. Немаркированные вспомогательные методы, атрибуты точек входа, биндинги, форматы данных/ресурсов, сетевой формат и ABI 9 не меняются. Преобразование или дополнительное повышение маркера совместимости не требуются. Откат возвращает предыдущие согласованные CoreScripts/сборки.

2026.1.55-dev - 2026-10-20

Изменено

  • Mapper и MapBaker отклоняют локальные несинхронизируемые переопределения Common или Client у динамических предметов, включая неизменяемые игровые свойства без Persistent. Проверяются серверный и клиентский наборы свойств, в том числе у скрытых предметов. Серверные свойства и контекст размещения разрешены; постоянная геометрия задаётся прототипом. Автоматическое слияние mesh действует только для статических предметов.
  • Изменение NoBlock, ShootThru и LightThru пересчитывает все зарегистрированные клетки клиентского контура предмета.
  • Автономная регрессионная проба LibreSSL выбирает облегчённые Windows-заголовки до заголовков OpenSSL; проверки OtherName, IP/mask и SRTP сохранены.

Миграция

  • База d947827d42ab7a8a6c5f0c168cdea5680423ddf9 (2026.1.54-dev); результат 2026.1.55-dev. Сетевая совместимость остаётся 0.0.74; новых флагов свойств и сетевой раскладки нет.
  • Перенесите отличающиеся несинхронизируемые значения Common или Client динамических размещений в прототипы или наследуемые варианты; для необходимых изменений во время игры используйте существующий канал синхронизации. Пересоберите затронутые нативные цели и ресурсы. Явные ноль, false и пустое значение считаются переопределениями. Статические размещения, серверные поля, имена, типы, умолчания и признаки сохранения не меняют смысла. Существующие сохранённые миры требуют штатного проектного разбора обновления контента; миграция исходника карты не является миграцией БД. Откат возвращает согласованные базовые бинарники и авторские ресурсы.

2026.1.54-dev - 2026-10-19

Исправлено

  • Сериализовано изменение состояния закрытия WebSocket с I/O-циклом backend. Disconnect и уничтожение обёртки ставят close в очередь, захватывая только слабую ссылку: прямой close() из потока движка больше не гоняется с завершением websocketpp. Native-проверка покрывает обрыв peer, повторный disconnect, однократное уведомление и обёртку, пережившую уничтожение listener.
  • Восстановлена полная доставка AI-документации после превышения корпусом предела размера. Бюджетом владеет манифест; описание маршрута и тесты репозитория больше не дублируют его текущее значение. Состав документов, детерминированный UTF-8/LF и отказ при переполнении не меняются.
  • При ошибке упаковки удаляется ZIP текущей target, включая нехватку места при записи ZIP и последующую ошибку установщика. Ошибка удаления выводится в журнал, не подменяя исходное исключение упаковки; поведение общего архива для строк только с SingleZip не меняется.
  • В X509- и SRTP-парсерах встроенного LibreSSL сохраняется const у результатов поиска в строке. Парсер IP-ограничений использует отдельный изменяемый указатель для собственной копии. Устранены предупреждения текущих host headers без приведений, подавления диагностики и изменений crypto/API; нативные пробы проверяют OtherName, IP/mask, SRTP, AES и TLS с ASM и без него.

Миграция

  • База d74075954cbf3742f0f717ff2b23ff309aa735a4 (2026.1.53-dev); обновление 2026.1.54-dev. Перегенерируйте затронутые API-модели и справочники через python BuildTools/docs_api.py --write, python BuildTools/docs_reference.py --write и python BuildTools/docs_public_api.py --write, затем запустите python BuildTools/docs_prepare.py, проверьте через python BuildTools/docs_validate.py, затем соберите сайт через python BuildTools/docs_site_build.py. Бюджет доставки берётся из ai_delivery.full_context.max_bytes в Docs/documentation-manifest.json. BuildTools/tests/test_docs_ai_delivery.py сохраняет независимые проверки переполнения и детерминизма байтов; усекать документы или отключать ограничение нельзя. Файлы доставки остаются игнорируемыми результатами сборки и не требуют дополнительного коммита.
  • Центральный маркер сетевой совместимости повышается с 0.0.73 до 0.0.74 для исправления WebSocket lifecycle. Перегенерируйте метаданные, пересоберите согласованные нативные клиент/сервер, Baker и тесты и перевыпеките scripts/resources; развёртывайте этот согласованный набор вместе. Проверка совместимости должна отклонять смешанные старые/новые артефакты. Нативные/script API, конфигурация, сохранения, схема ресурсов и Managed ABI 9 сохраняют прежний смысл; конверсия сохранений не нужна. Python-правка упаковки действует при следующем запуске; повторяйте его после устранения причины ошибки хранилища или установщика. Откат возвращает весь прежний согласованный набор артефактов, политику доставки и сохранение ZIP после ошибки без конверсии данных.

2026.1.53-dev - 2026-10-19

Исправлено

  • Сохраняются постоянные деревья custom entities при штатной остановке сервера. Runtime teardown освобождает внутренние ссылки singleton и зарегистрированных держателей до сброса родителей и владения реестра; обычное удаление custom entity не вызывается, сохранённые ID держателей не изменяются.

Документация

  • Уточнены компоненты свойств Critter, Location и других владельцев: bool-маркеры, поля с точкой, отключение наследования, Managed Has и миграция сохраняемых имён.

Миграция

  • База 2860bb2755621976d199883e254d66808a659ec1 (2026.1.52-dev) → рабочая правка 2026.1.53-dev. Затронут путь ServerEngine::Shutdown → EntityManager::DestroyAllEntities, общий для скриптовых backend и провайдеров БД. Обычный игровой DestroyCustomEntity по-прежнему удаляет явно уничтоженную сущность и её детей.
  • Callable API, настройки, свойства, идентичности, формат хранения, маркер сетевой совместимости (0.0.73) и Managed ABI (9) прежние; преобразование проектного кода или данных не требуется. Постоянные ID держателей и документы детей должны переживать остановку процесса. После смены версии/ревизии переконфигурируйте и пересоберите затронутые native-роли сервера/тестов, обновите метаданные и согласованно перезапеките ресурсы.
  • Ранее удалённые документы нельзя восстановить по оставшимся вторичным индексам. Если данные уже потеряны, восстановите проверенную резервную копию по процедуре владеющего проекта; не удаляйте индексы, чтобы скрыть отсутствующие сущности. Откат требует согласованных бинарников/ресурсов и проверенной копии; предыдущая сборка сохраняет дефект удаления при остановке.
  • Владелец приёмки: ServerShutdownPreservesPersistentCustomEntityTreesAcrossRestarts в Source/Tests/Test_ServerEngine.cpp. Он должен сохранять точные ID, дерево держателей и контрольные значения через две штатные перезагрузки на реальном JSON-хранилище, включая custom child постоянного NPC. Подключающие проекты также проверяют используемый backend и вход аккаунта на изолированной базе.

2026.1.52-dev - 2026-10-18

Добавлено

  • Серверное readonly-свойство Critter.MapTransfersLocked доступно в обоих скриптовых backend. Оно читает существующий native-счётчик вложенных блокировок под покрытием криттера, позволяя отложить перенос до вызова native-защиты. Хранимого свойства или новой блокировки нет; native-защита сохраняет окончательное решение.

Миграция

  • База 219fbd7568f2388f4a3b47e5a22fb38b8e259a0d (2026.1.51-dev); обновление 2026.1.52-dev. Пересоберите нативных потребителей и заново выпеките скрипты/ресурсы вместе для регенерации метаданных и Managed-привязок методов. Существующие скриптовые вызовы и значения входов сохраняют смысл; сохранённые данные, форматы ресурсов, версия миграции сети 0.0.73 и Managed ABI 9 не изменены. Конверсия сохранённых данных не требуется. Новый экспорт изменяет генерируемые отпечатки клиент/серверной совместимости и Managed-манифеста методов при неизменных версиях их схем. Пересобирайте и развёртывайте согласованные серверные и клиентские бинарники с заново выпеченными скриптами; не смешивайте артефакты базы и обновления. Rollback возвращает согласованные артефакты базы без конверсии данных.
  • Читайте свойство под покрытием живого криттера непосредственно перед переносом, без yield или освобождения покрытия между проверкой и вызовом. Истинное значение временно: перед ожиданием освободите покрытие, после его повторного получения заново проверьте операцию. Getter не резервирует будущий перенос. Проверьте вложенные блокировки через EntityManagerCppApi/MapTransfersLockedExportObservesNestedLocks и продолжение переноса в embedding-проекте.
  • Увеличить проверяемую ёмкость полного контекста документации на 16 КиБ, до 2 342 912 байт, чтобы сохранить полные накопленные примечания миграции. При превышении лимита генератор по-прежнему завершается ошибкой; эта правка ёмкости не усекает и не исключает документы. Runtime и сохранённые данные не затронуты.

2026.1.51-dev - 2026-10-18

Исправлено

  • Документы постоянных NPC и их инвентаря сохраняются при выгрузке криттера и очистке после ошибки восстановления. Явное уничтожение NPC по-прежнему удаляет его документы; принадлежность персонажа игроку больше не определяет удаление документа при снятии регистрации.
  • Нативные регрессии проверяют выгрузку/загрузку постоянного NPC, принадлежность предметов инвентаря, окончательное уничтожение и восстановление после отсутствующего документа предмета.

Миграция

  • База 1f2f8e4e55b51899ba07ad83f9e05287d365a78f (2026.1.50-dev); обновление 2026.1.51-dev. Внутренняя нативная декларация в Source/Server/EntityManager.h меняется с UnregisterCritter(ptr<Critter> cr) на UnregisterCritter(ptr<Critter> cr, bool delete_from_db). Найдите собственные нативные вызовы через rg -n 'UnregisterCritter\(' Source <native-extension-directory>: замените UnregisterCritter(cr) на UnregisterCritter(cr, false) для выгрузки/очистки после ошибки загрузки либо на UnregisterCritter(cr, true) только для окончательного уничтожения NPC. Прежний вызов с одним аргументом не компилируется; аргумента по умолчанию и совместимой перегрузки нет. Сохраните ограничение уничтожения только NPC и порядок очистки инвентаря. Смысл script API и незатронутых нативных вызовов прежний.
  • Повторите конфигурацию и сборку нативного сервера и тестов; обновите метаданные ревизии обычным согласованным процессом Baker/ресурсов. Запустите ServerUnloadLoadKeepsPersistentNpcAndItemRecordsUntilDestroy и ServerFailedNpcLoadKeepsRecoverableRecords, проверяя зафиксированные документы криттера/предметов до выгрузки, после неё, после загрузки и после окончательного уничтожения. NPC уже должен быть явно постоянным; следование за игроком не переводит временную сущность в постоянную. Свойства, конфигурация, авторский контент, формат БД, схема ресурсов, Managed ABI 9 и runtime compatibility 0.0.73 не меняются. Прежние ID, принадлежность предметов и смысл временных сущностей сохраняются; конверсия сохранений не требуется, ранее удалённые документы исправление не восстанавливает.
  • Развёртывайте согласованные пересобранные артефакты. Откат возвращает прежние бинарники/ресурсы без конверсии данных и возвращает дефект удаления документов NPC. Прежняя runtime-приёмка не подтверждает более новую базу Engine; этот локальный перенос истории не означает новую сборку, игровую квалификацию или публикацию.

2026.1.50-dev - 2026-10-18

Исправлено

  • ACM-потоки с нулевым заявленным числом сэмплов отклоняются до декодирования или записи выпеченного результата. Пути эффектов и музыки сохраняют ошибку с именем файла; регрессии загрузчика и Baker проверяют весь пакет и выбранный файл без создания результата для отвергнутого источника.

Миграция

  • База 370b268aa01099e731a2d93a8ae65222eb06c816 (2026.1.49-dev); обновление 2026.1.50-dev. Пересоберите Baker с поддержкой ACM и нативные тесты, выполните AudioBaker и AudioBakerAcm; исправьте источник, отклонённый с ACM stream declares no samples, и повторно запеките затронутый ACM. У корректных непустых потоков сохраняются смысл сэмплов, частоты, выбора каналов по пути и дополнения усечённого тела нулевыми битами. Миграция скриптов, настроек, прототипов, сохранённых данных и схемы ресурсов не нужна. Сетевая совместимость 0.0.73, Managed ABI 9 и границы updater не меняются; новых ограничений смешанных версий и порядка выкатки нет. Откат возвращает соответствующие прежние бинарники/ресурсы без преобразования данных и восстанавливает принятие некорректного пустого потока. Эти инструкции не утверждают, что нативная/runtime-приёмка уже выполнена.

2026.1.49-dev - 2026-10-17

Исправлено

  • Windows console Ctrl+C и Ctrl+Break после инициализации frontend запрашивают обычный выход приложения. Handler только устанавливает общий для процесса атомарный флаг; закрытие консоли, выход из системы, остановка ОС и принудительное завершение сохраняют прежнее поведение.
  • Закреплён существующий read-only контракт startup Common.UserWritablePath: непустое присваивание из config отклоняется до подстановок и append-разбора, а пустое сгенерированное присваивание не сбрасывает разрешённый root.

Миграция

  • База c7a19d2c833c3b16c741fb02cf170c14e5c251c5 (2026.1.48-dev); обновление 2026.1.49-dev. Найдите авторские входы командой rg -n 'Common\.UserWritablePath\s*=' --glob '*.fomain*' --glob '*.cfg'. Удалите каждое непустое присваивание из main/sub-configs, записей local-config cache и исходников упакованного internal config; передавайте --Common.UserWritablePath <path> при запуске процесса. Непустое присваивание теперь вызывает SettingsException: Writable root is resolved before settings при runtime или baking. Просматривайте local cache через владеющий им инструмент конфигурации; непрозрачный cache-файл не является текстовым config. Пустые сгенерированные присваивания остаются допустимыми no-op. Приоритет CLI, *, выбор через installer marker и portable-поведение с пустым root не меняются.
  • Пересоберите нативные приложения и Baker, затем выполните обычную выпечку для обновления метаданных ревизии и проверки упакованных configs. Проверьте разрешение CLI, пустые значения config, отказ main/sub/local-присваиваний и обычный shutdown после обоих console events в отдельном дочернем процессе/консоли. Windows service control и POSIX signals прежние; GUI-приложение без консоли использует обычное действие выхода. Изменений script API, persisted data, map/resource schema, network compatibility marker, runtime 0.0.73 и Managed ABI 9 не требуется. Откат — согласованные binaries/resources без преобразования сохранений.
  • Обработка Windows console Ctrl+C и Ctrl+Break устанавливается безусловно после инициализации frontend. Handler только устанавливает флаг выхода; каждое приложение выбирает безопасные точки выхода, обслуживая IsQuitRequested(). Собственные native-циклы, которым нужен кооперативный ранний выход, должны опрашивать IsQuitRequested(). Batch-инструменты и тесты, не наблюдающие выход, могут завершить текущую работу (без гарантии немедленной отмены). POSIX signal setup и Windows service control не меняются. Subprocess-матрица проверяет оба Windows events для application-loop quit и deferred observation.

2026.1.48-dev - 2026-10-17

Исправлено

  • Первая альфа-маска 3D-спрайта подготавливается при обновлении спрайта до первого наведения или клика. Picking только читает готовую маску и запрашивает обновление; render update запускает последующие копии по запросу не чаще раза в 100 мс и каждый кадр опрашивает готовность незавершённого чтения. Это предотвращает выбор фонового предмета при холодной первой маске и поддерживает актуальность силуэта под курсором без копирования каждый кадр.
  • Сгенерированная запись версии миграции API и справочники согласованы с опубликованным исходником 2026.1.47-dev: Source/Common/Common.h уже объявляет Version 0 0 73, а производная модель ещё содержала 72. Исправление документации не вводит дополнительного изменения совместимости runtime.

Миграция

  • База 617a0d6f1af16a6bcf3da951e5299ddf31c26158 (2026.1.47-dev); обновление 2026.1.48-dev. Пересоберите нативных потребителей клиента/Mapper и тесты; выполните обычную выпечку проекта для обновления метаданных ревизии. Миграция скриптов, настроек, прототипов, выпеченных форматов и сохранённых данных не нужна: точный выбор по альфе и смысл всех прежних входных значений сохраняются. Сетевая совместимость 0.0.73 и Managed ABI 9 не меняются; новых ограничений смешанных версий и порядка выкатки нет. Откат возвращает базовые нативные бинарники без преобразования данных.
  • Проверьте ModelSpritePreparesItsHitMaskDuringRenderUpdate, ModelSpriteHitMaskThrottlesRequestedCopiesButPollsPendingPixels, проверки повторов/перерисовок и первые клики с предварительным наведением и без него в отрисованном клиенте. Ограничьте срок кэша сущности под курсором встраивающей игры, чтобы найденный фоновый предмет не скрывал уже готовую маску. Появление окна взаимодействия проверяйте отдельно от отправки команды. Picking не добавляет выбор по прямоугольнику и ожидание GPU; асинхронный опрос готовности не зависит от интервала копирования 100 мс.

2026.1.47-dev - 2026-10-17

Исправлено

  • Измерение ParseLargeConfig вынесено из функционального ConfigFile в явно выбираемый кейс ConfigFilePerformance ([!benchmark][config]) по соглашению скрытых измерений TextureAtlasLayoutPerformance и PropertiesPerformance. Обычный функциональный запуск больше не повторяет его на каждом из 29 путей SECTION; ConfigFilePerformance сохраняет прежнее измерение ParseLargeConfig на входе 128x12. Ускорение всего CI не измерялось и не заявляется.
  • Незавершённый запрос clear для work_thread подтверждается worker’ом до осмотра очереди, dispatch или wait. Очередь jobs очищается, и clear() возвращается при любой форме очереди, включая пустую и содержащую только future-dated jobs, и через pause/resume; запрос, попавший вокруг раннего уведомления о подтверждении, больше не оставляет clear() спящим на done signal worker’а.

Миграция

  • База d498fcf07d1425cf31e71b060fe8aeae87aeb37d (2026.1.46-dev); следующее обновление 2026.1.47-dev. Пересоберите тестовый исполняемый файл; функциональный фильтр ConfigFile по-прежнему выполняет те же 136 проверок. Для измерения производительности выбирайте ConfigFilePerformance или явный тег benchmark вместо непреднамеренного запуска измерений в ConfigFile. Поведение парсера, API, настройки, скрипты, контент, сохранения, сеть, система обновления, схема ресурсов, Managed ABI 9 и runtime 0.0.73 не изменены; только для этого исправления расписания тестов миграция игры/данных и повторная выпечка не требуются. Откат восстанавливает прежнюю раскладку тестов без преобразования данных. Черновик не означает публикацию.
  • Пересоберите Essentials и нативных потребителей и тесты, которые его линкуют, включая focused-набор WorkThread с новой регрессией живости подтверждения clear. API, настройки, скрипты, контент, сохранения, сеть, система обновления, схема ресурсов, Managed ABI 9 и runtime 0.0.73 не изменены; конверсия данных и миграция формата ресурсов не требуются. Embedding-проекты выполняют обычное обновление revision-metadata и квалификацию bake для этой ревизии Engine: авторский контент не меняется, поэтому квалификация остаётся обычным проверочным шагом, а не миграцией формата. Rollback восстанавливает согласованные предыдущие артефакты без конверсии данных и возвращает дефект подтверждения clear. Черновик не означает публикацию или квалификацию выпуска.

2026.1.46-dev - 2026-10-17

Исправлено

  • Вложенный доступ к настройкам Managed и AngelScript использует общий разбор канонических путей. Полные runtime-ключи сохраняются; built-in настройки остаются read-only, Managed properties — get-only, а custom настройки AngelScript сохраняют setters.
  • Пути групп AngelScript с подчёркиваниями различаются; конфликты property/group отклоняются до использования скриптом. Общий парсер отвергает пустые сегменты; Managed дополнительно проверяет коллизии экранированных C#-имён.
  • Пути environment FO_DOTNET_DIR нормализуются только на Windows, сохраняя символы POSIX-пути и производные каталоги runtime, payload и stamp.
  • Стадия полной записи строится от нативного родителя файлового пути, сохраняя буквальные ведущие пробелы, POSIX backslash и платформенное толкование пути. Обрезание пробелов и нормализация ресурсных разделителей больше не меняют дисковые имена.
  • После успешной публикации cleanup освобождает владение именем стадии: завершившийся писатель не удаляет файл следующего писателя, занявшего то же имя.
  • Добавлены проверки буквальных путей, отказа readonly cache/bootstrap, CRT readers без delete sharing и безопасности загруженных библиотек. Уточнена граница Windows: успешная замена атомарна, но открытый поток или образ может отклонить публикацию без изменения назначения.

Миграция

  • a627da59d2b408e4b618b125bcd7766879c03d41 (2026.1.45-dev) → 2026.1.46-dev: Domain.Name сохраняет Settings.Domain.Name; Android.GradleDependency.Sample теперь порождает вложенный доступ Managed; AngelScript сохраняет вложенный доступ с однозначными типами групп. SettingsPath.A_B.Value и SettingsPath.A.B.Value различаются. Пустые сегменты дают Setting path (Managed baker оборачивает её в Managed setting); исправьте авторский ключ. Конфликты namespace/property после экранирования C# также дают Managed setting. Смысл прежних корректных группированных путей сохраняется; AngelScript по-прежнему принимает корректные негруппированные custom настройки. Одинаковые канонические ключи Managed дедуплицируются.
  • Внутренние типы AngelScript GlobalSettingsGroup_* теперь обрамляют сегменты их длинами. Замените явные сгенерированные типы прямым доступом: GlobalSettingsGroup_Android_GradleDependency group = Settings.Android.GradleDependency; string value = group.Sample; заменяется на string value = Settings.Android.GradleDependency.Sample;. Старые явные имена типов дают ошибку компиляции; алиасов нет. Перед пересборкой найдите GlobalSettingsGroup_ в авторских скриптах.
  • Повторите configure; пересоберите native-компоненты и Baker; регенерируйте и скомпилируйте Server/Client/Mapper, включая весь bytecode AngelScript; выполните полный, затем инкрементальный bake. Разворачивайте согласованные sources/assemblies/bytecode/resources; rollback восстанавливает предыдущий комплект. Переименование конфигурации и конверсия сохранений не нужны. Сигнатуры листовых свойств скриптов, ID, смысл значений конфигурации, save/wire форматы, Managed ABI 9 и runtime 0.0.73 сохраняются. См. конфигурацию и источники данных.
  • Native-сигнатуры строковой/байтовой fs::write_file и fs::replace_file сохраняются; переименование вызывающего кода, backend или роли не требуется. Прежнее написание пути сохраняет нативный смысл. Корректный относительный " dir/data.bin" записывается именно в этот каталог; POSIX "/tmp/back\\slash/data.bin" сохраняет буквальный backslash вместо разделителя.
  • Повторите configure/сборку native-ролей и Baker, затем регенерацию и выпечку всех затронутых сторон с согласованной Engine-ревизией. Проверьте DiskFileSystem, DiskFilePrimitives, CacheStorage, ClientRuntimeBootstrap*, NullRenderer, включённый scripting backend и интеграционные bake/runtime. Windows-only тесты не квалифицируют POSIX-исполнение.
  • false по-прежнему означает, что новый файл не опубликован: сохраняйте прежнее значение/selector, при необходимости закрывайте блокирующих читателей либо используйте delete-sharing fs::disk_read_file. Замена native loaded DLL images и CRT streams не обещается на любой Windows/файловой системе. Не добавляйте delete-then-rename или откат, который сам может отказать.
  • Конверсия settings, properties, prototypes, saves, network, updater и resource schema не нужна; runtime 0.0.73, Managed ABI 9, сохраняемые значения и порядок успешного bake прежние. Атомарная видимость не обещает directory durability при отключении питания. Rollback возвращает согласованные бинарники/ресурсы 45-dev без конверсии сохранений и возвращает её отказ на буквальных путях. См. Essentials и baking.

2026.1.45-dev - 2026-10-16

Исправлено

  • Генератор регистрации Managed C# callbacks свойств приведён к объявленному C++-профилю форматирования. Имена callbacks и байты генерируемого C# сохраняются.
  • Null renderer допускает начало scissor за пределами render target, согласуя обрезку частично скрытых панелей GUI с GPU backend. Отрицательные размеры scissor и выход за границы текстуры при чтении/записи остаются ошибками.

  • Из комментариев Windows-замены файлов убраны завершающие точки по правилам авторского текста; нативное поведение прежнее.

Миграция

  • База 5cc571ef888291d132de3fdab30ac0914a10ef48 (2026.1.44-dev); следующее обновление 2026.1.45-dev. Конверсия API, настроек, скриптов, авторского контента, сохранений, runtime 0.0.73 и Managed ABI 9 не требуется.
  • Переконфигурируйте и пересоберите инструменты и headless-приложения для новой версии Engine и исправления Null scissor; проверьте формат, существующую регрессию имён callbacks и NullRenderer. Откат использует согласованные артефакты 44-dev без преобразования сохранений и возвращает более строгую проверку начала scissor в Null. Черновик не означает публикацию или платформенную приёмку.

2026.1.44-dev - 2026-10-16

Исправлено

  • fs::write_file стал единственным атомарным helper полной записи строк и byte spans, включая NUL и пустой ввод. Эксклюзивный соседний временный файл, flush и атомарная замена сохраняют прежнее назначение при ошибке и поддерживают открытые readers/mapped DLLs. disk_write_mode::create_new отвергает существующий путь; алиаса write_file_atomic нет.
  • Общий helper используется для кэша, managed staging, маркеров клиентской сессии/bootstrap, результатов/отчётов/отпечатков Baker, зависимостей частиц, JSON-записей и SQLite restore scratch. Ошибка публикации сохраняет кэш; явное удаление — RemoveEntry. Windows rename names завершаются NUL, а отдельная path probe не зависит от линковки Engine.
  • Согласованы сводные решения по контрактам без удаления прежних записей аудита. Полные руководства и миграции сохранены в проверенном AI-пакете 2 MiB + 224 KiB; manifest, EN/RU-руководства и policy-тесты используют один предел. Обязательные начальные маршруты, состав и отказ при превышении не изменены.

Миграция

  • База: 1d88ee229d2d5208dd6c4c86814e032598a06e4c (2026.1.43-dev). Это единое неопубликованное обновление объединяет локальные исправления атомарной записи и документацию; перед адаптацией примените опубликованные миграции до 43 включительно. Промежуточные локальные версии не являются этапами выпуска.
  • Native-сигнатуры fs::write_file(path, string_view) и byte-span сохранены; запись теперь заменяет готовый файл целиком вместо обрезания назначения. Проверьте права родителя, symlinks, hard links и метаданные назначения. Для streaming/in-place с сохранением идентичности используйте fs::disk_write_file; проверяйте write и flush. WinApi/Posix open_new_write_file добавляет необязательный exclusive=false, сохраняя вызовы с двумя аргументами. Экспериментальные локальные вызовы write_file_atomic замените на write_file; второго helper и совместимого алиаса нет.
  • Повторите configure/сборку Essentials, Common, Client, Server, Tools и Managed; перегенерируйте bindings, references, EN/RU, site/routes и AI, затем запеките ресурсы новым Baker. Проверьте filesystem/cache/database/selector/baking tests, публикацию с открытыми assembly readers и сохранение назначения при ошибке. SetDataChecked == false означает, что новое значение не зафиксировано; SetString журналирует ошибки. Для отката сохраняйте прежний полный пакет.
  • Относительно опубликованной версии 43 нет преобразования managed callers, settings, prototypes, persisted properties, saves, network, updater или resource schema. Смысл JSON keys/content, selector validation, порядка successful markers и unchanged timestamps сохранён. Совместимость остаётся 0.0.73, managed ABI identity — 9, sprite container — v2. Атомарная видимость не обещает directory durability при потере питания. См. Essentials.

2026.1.43-dev - 2026-10-15

Исправлено

  • При отказе направления в согласовании активной/завершённой остановки отправляется авторитетный CritterDir; позиции прежние.

Миграция

  • 54f4e6393c60aad893dbd60b596a9b7c8088ba0c (2026.1.42-dev) → 2026.1.43-dev; совместимость 0.0.72 → 0.0.73. Пересоберите baker/сервер/клиентов/Mapper; обновите метаданные, запеките и выложите серверные/клиентские ресурсы вместе. Формат и смысл пакетов/API, Managed ABI 9, позиции/направления и сохранения прежние; конверсия не нужна. Откат возвращает согласованные исходные binaries/ресурсы.

2026.1.42-dev - 2026-10-15

Исправлено

  • Серверный поиск пути с gag-проверкой отклоняет статические блокировки, в том числе когда на том же гексе стоит динамический gag. Удаление статики в экземпляре карты учитывается; разрешённые маршруты через динамические gag сохраняются.
  • Проверка равной экранной строки исправлена для hex- и square-геометрии.

Изменено

  • Resize разреженной двумерной сетки обходит сохранённые ячейки вместо площади старой и новой карты; сохраняет значения пересечения и удаляет вышедшие за границы ячейки.

Миграция

  • База eedcaa955ff4be79e43384766f7a47cbda0788d1 (2026.1.41-dev); обновление 2026.1.42-dev. Пересоберите нативные потребители и выполните обычную выпечку для обновления метаданных ревизии. Исходники карт, запечённые форматы, скриптовые сигнатуры, конфигурация, сохранённые данные, runtime 0.0.72 и Managed ABI 9 прежние; преобразование данных не требуется.
  • Смысл статической блокировки сохраняется: gag-предикат может разрешить динамический gag, но не обходит целую статическую преграду. Уберите обходные решения, опирающиеся на ошибочно разрешённые пути через стены; при фактическом удалении статического предмета используйте удаление в экземпляре карты. Проверьте заблокированную точную цель, массовую достижимость, динамические gag и переход после удаления. Откат возвращает согласованные бинарники/ресурсы базы без преобразования сохранений.

2026.1.41-dev - 2026-10-15

Исправлено

  • Исправлены ссылки/границы SPARK, C#-стиль/EOF, локальные типы, DB sort/POSIX startup; описан перенос lock.

Миграция

  • c727e6f549fe54095e21dad4c272b99761083e0f (40-dev) → 41-dev. API/конфигурация/данные, ABI 9, runtime 0.0.72 прежние. Пересоберите роли/runtime cache, перезапеките SPARK, обновите docs. Проверьте эти исправления и порядок эффектов. Откат: согласованные бинарники/docs/пакеты базы.

2026.1.40-dev - 2026-10-14

Изменено

  • Подходящие языковые пакеты добавляются до одной стабильной сортировки; ёмкость растёт геометрически, бинарные размеры ограничены. Сортировка выполняется только при успехе; отказ сохраняет исходное исключение и может оставить неотсортированные записи. Успешный повтор восстанавливает порядок.
  • Нативный TextPack::LoadFromBinaryData и его helper добавления принимают const_span<uint8_t>; декодированные строки владеют своей памятью.
  • Текстовые пакеты явно сортируются после успешной загрузки; единственный путь завершения не требует scope guard.
  • Деструктор scope_success стал условно noexcept: исключение callback передаётся вызывающему коду при успешном выходе; при раскрутке стека callback пропускается.
  • Исправлены документация и комментарии экспортов: безындексный GetText уже выбирает случайный вариант с равными вероятностями; выбор по индексу сохраняет порядок загрузки.
  • Разделители Windows-пути из переменной окружения FO_DOTNET_DIR нормализуются перед обработкой CMake; приоритет кэша сохраняется. Проверки каталога сравнивают пути, а codegen fixtures подключают действующие определения helpers.

Миграция

  • База 92ee4cb67d66e586c026e181e576b830deb7112a (2026.1.39-dev); обновление 2026.1.40-dev. Из-за общего заголовка пересоберите все нативные потребители и Baker, обновите метаданные и выпеките ресурсы. Преобразование скриптов, конфигурации, контента или сохранений не нужно; раскладка текста, языковой фильтр, подстановка коллекции и порядок дублей прежние.
  • Неверные размеры вызывают DataReadingException до выделения памяти; отказ загрузки не сортирует и не откатывает, чтение неотсортированного пакета отклоняется. Проверьте исключение/раскрутку/return guard, пакетную эквивалентность, повтор и настроенные языки. Совместимость 0.0.72, Managed ABI 9 и схемы прежние; откат не требует преобразования сохранений.
  • Перекомпилируйте нативные вызовы TextPack::LoadFromBinaryData; аргументы-векторы преобразуются неявно. Обновите явно типизированные указатели на метод под сигнатуру со span. Закодированные байты и скриптовые API прежние.

2026.1.39-dev - 2026-10-14

Исправлено

  • Отбор клиентских предметов карты учитывает переопределения Static и Hidden размещения. Нативная регрессия обоих направлений проверяет точные ID предметов.
  • Полный корпус документации сохранён с проверенной прибавкой лимита на 32 KiB; состав документов и отказ при превышении сохранены.

Миграция

  • База: 48c437b01e85858e7c702c4be834dd647cd180cb (2026.1.38-dev); следующая версия — 2026.1.39-dev. Пересоберите Baker, заново запеките все карты и распространяйте согласованные серверные и клиентские пары. Сохранённые карты загрузят обновлённую статику. Конверсия API, конфигурации, бинарных/сетевых схем, managed ABI и сохранений не нужна; авторский смысл свойств размещения сохраняется. Откат возвращает прежние Baker/карты без конверсии сохранений.

2026.1.38-dev - 2026-10-14

Исправлено

  • Callbacks Managed C# регистрируют канонические имена компонентов (Weapon.UseMode), сохраняя обычные подчёркивания во всех перегрузках getter и setter.

Миграция

  • 4c594d1bef (2026.1.37-dev) → 2026.1.38-dev: пересоберите Baker; перевыпеките server/client/Mapper. Сигнатуры, IDs, сохранения, сетевые форматы, ABI 9 и runtime 0.0.72 неизменны. Выкатывайте согласованные сгенерированные исходники/сборки; откат возвращает прежний Baker/сборки. Миграция исходников/сохранений не нужна.

2026.1.37-dev - 2026-10-14

Изменено

  • Все исходники тестов зарегистрированы безусловно, а guards бэкендов находятся внутри translation units. Native-проверки движка, сущностей, карт, сети и rendering доступны обоим бэкендам; проверки AS-привязок выделены в Test_AngelScript* с общими header-фикстурами.
  • Добавлены проверки настоящего ManagedScriptBaker/runtime bridge для server, client и Mapper: инициализация, события, передача аргументов и результатов, исключения и изоляция одновременно работающих серверов.

Исправлено

  • Managed-точки входа native-вызовов с Dictionary<K,V> регистрируются через существующий dictionary bridge вместо пропуска их сигнатур как неподдерживаемых; результаты callback-словарей копируются через accessor вызывающего, а managed-объекты удерживаются GC roots во время преобразования.
  • Тест ASIO accept callback захватывает отчёт отдельного потока обработки исключения и ожидает его до восстановления глобального состояния тестов; намеренная диагностика больше не попадает в журнал следующих проверок логирования.
  • CMake отслеживает packed/loose Git refs только файловыми зависимостями.
  • Сторона EntityHolder фильтруется до проверки держателя; заглушки общего держателя сохраняются.
  • Persistent-потомки Game и их постоянные потомки сохраняются; обычные остаются временными.

Миграция

  • База: 91d8bf21ac89e5342db17aab8e25332e049e900e (2026.1.36-dev); следующая версия — 2026.1.37-dev. Повторите конфигурацию сборки тестов после разделения исходников. В инструментах с путями к тестам используйте имена Test_AngelScript*, а в точечных фильтрах Catch2 — имена разделённых AS-cases с этим префиксом. Managed runtime tests требуют .NET SDK для настроенного target framework и комплект managed runtime. Пересоберите все включённые роли и проверьте оба бэкенда; обновите метаданные, справочники и маркеры запекания согласованными бинарниками. Конверсия игровых правил, script API, конфигурации, сохранений и сети не нужна: существующие dictionary-сигнатуры теперь используют свой прежний bridge. Managed ABI 9, runtime 0.0.72, спрайты v2, схемы ресурсов и сети сохраняют идентичность. Развёртывайте согласованные бинарники и runtime payload вместе; откат возвращает предыдущие согласованные бинарники без конверсии сохранений.
  • Пересоберите сервер/baker и запеките метаданные. Согласуйте исторические ID потомков, которые не были сохранены. Декларации, формат документов и протокол не меняются.

2026.1.36-dev - 2026-10-13

Исправлено

  • В проверке аудио названы Test_AudioBaker, Test_AudioBakerAcm и Test_AudioManager; ACM требует FO_AUDIO_ACM.
  • Двуязычный ADR согласован с датированным измерением AI delivery; документы включены целиком, лимит байтов сохранён.
  • Шесть диаграмм переведены на LF без видимых изменений; четыре датированные записи проверки сохранены как исторические доказательства.

Миграция

  • cd5c1168f8f4bdab63a2909ceacb049ba87e070a (2026.1.35-dev) → 2026.1.36-dev: только документация, генераторы и тесты. Конверсия API, скриптов, конфигурации, ресурсов, хранимых данных и БД не нужна. Смысл аудио, ABI 9, runtime 0.0.72, спрайты v2, схемы updater и сети прежние.
  • Запустите docs_audio.py --write, docs_diagrams.py --write, затем docs_prepare.py из BuildTools/. Проверьте тесты документации аудио, диаграммы, хеши EN/RU, версию, site/routes и полный AI delivery. Метаданные кода, сборки и пакетов должны совпадать; принудительная перепечка не нужна. Native audio и слышимые проверки платформ выполняются отдельно. Откат возвращает документацию, генераторы и метаданные базы; сохранения не меняются.

2026.1.35-dev - 2026-10-12

Исправлено

  • Исправлены пустой return теста ImageBaker для GCC и nullable-формат; runtime прежний.
  • API-проверки сохраняют равенство исходникам и явную классификацию: 2573 символа, 2572 experimental, один internal.
  • Сокращены метки URL AI-пакета; полные документы, ссылки, состав и прежний лимит размера сохранены.

Миграция

  • База: d5bef2f554019e4c6c45366a1f422c11e9229878 (2026.1.34-dev); далее 2026.1.35-dev. Сохраните прежнее принятие владения, ACM и Arcanum. API, конфигурация, данные, sprite v2, ABI 9 и runtime 0.0.72 прежние.
  • Пересоберите и запеките все роли; выполните format/API/native-тесты и python BuildTools/docs_prepare.py для ссылок, EN/RU, сайта и AI. Откат использует согласованные код, тесты и metadata базы 34; конверсии игры нет.

2026.1.34-dev - 2026-10-12

Исправлено

  • Первый загруженный sprite sheet независим от cached prototype. Усечение сокращает оба массива кадров; копирование ограничено размером назначения и задаёт размер/привязку нулевого кадра/направления.

Миграция

  • База 5170fa03ccdcc8efb6a592f9aba3baebfd544cb6 (2026.1.33-dev); новая версия 2026.1.34-dev. Пересоберите native clients/Mapper и перезапустите. Конверсия scripts/config/content или БД не нужна: first/last selection, directional deltas, state/action tags и atlas sharing сохраняют смысл.
  • Независимое проигрывание теперь соблюдается с первой загрузки. Усечение не сокращает последующие загрузки; LastFrame по-прежнему суммирует обе оси. Проверьте повторные загрузки, усечённые копии и видимые animation/directions/stop-start.
  • Runtime 0.0.72, Managed ABI 9 и sprite container v2 прежние. Запечённые изображения пригодны; обновите обычные generated metadata/bake markers, выкладывайте согласованные binaries. Откат возвращает baseline binaries без конверсии сохранений.

2026.1.33-dev - 2026-10-12

Добавлено

  • FOFRM Alias сохраняет направления, привязки, смещения и время бинарного источника. ART $r=0..7 выбирает одну ротацию.

Исправлено

  • DAT 2.1 принимает имена с завершающим нулём и без него, нормализует регистр/слеши и читает флаги как биты. ART использует 8-битный заголовок, присутствующие палитры, таблицы по ротациям и ограниченные потоки raw/RLE с исходными правилами привязки.
  • Исключения DAT, ZIP/embedded ZIP, cached-directory и вложенных изображений сохраняют причину и контекст источника. FileReader сообщает границы чтения; DAT отклоняет усечённые записи, неверные распакованные размеры и повреждённые окончания потоков.

  • Пустые HTML-якоря исключены из ключевых слов документационного поиска; видимый текст, стабильные ID и примеры кода индексируются. Пересоберите site/search и AI delivery с прежними лимитами.

Миграция

  • Версия 2026.1.33-dev следует за опубликованной 2026.1.32-dev. База: 6875e109534e94657c37fed55c559550901e9313. Включайте FO_DATA_SOURCE_DAT и FO_IMAGE_ART по необходимости; обе по умолчанию OFF. Выключенные источники указывают нужную опцию. Владельцы — DataSource-Dat и ImageBaker-Art; FOFRM использует ImageImport::Context::Resolve. PNG/TGA/FOFRM, callbacks и существующие опции компонентов прежние.
  • $r3/$R3 по-прежнему выбирают палитру 3. Замените донорский Alias = Actor$r3.art на Alias = Actor$r=3.art; тот же селектор работает в ссылках frm. Обычная композиция не требует конверсии; Alias нужен для полного набора источника. Другой FOFRM нельзя использовать как псевдоним. Руководство по изображениям описывает проверку селектора, выбор запасной палитры, пределы холста/смещений, длительность до 65535 мс, выбор кадров при fps ноль и привязку по категориям; сохраняйте пути art/critter/, art/monster/, art/unique_npc/, art/wall/, art/portal/ и art/roof/.
  • Найдите входы через rg --files -g '*.art' -g '*.dat' -g '*.fofrm' и rg -n 'Alias|\$[rR]=?[0-7]' <source-roots>. Переконфигурируйте/пересоберите baker, затронутый native runtime и метаданные версии; принудительно перезапеките нужные пакеты через BakeResources. Замените outputs, перезапустите клиентов, визуально проверьте палитры, привязки, смещения, псевдонимы и обе геометрии карты.
  • Обрабатывайте DataSourceException при неполном чтении cached-directory; исправьте DAT/ZIP и обновите индексы каталогов. Поиск отсутствующих файлов и владелец логирования прежние. Контейнер спрайта v2, runtime 0.0.72, script ABI identity 9, схемы updater/пакетов, транспорт и хранимые данные не меняются относительно опубликованной базы. Конверсия БД/сохранений и проприетарные ресурсы не нужны. Выкладывайте согласованные ресурсы/бинарные файлы; откат восстанавливает оба набора вместе.

2026.1.32-dev - 2026-10-12

Исправлено

  • Нормализованы комментарии native RefType и bindings; runtime-токены и API прежние.
  • Происхождение FOFRM Count привязано к загрузчику и чтению; ART отклоняется.
  • Governance соблюдает опубликованный лимит 2 MiB + 192 KiB, полноту документов и отказ при превышении.
  • Проверки переводов учитывают 4866 записей: 2576 API, 106 аудио, 79 CMake; пропуски и устаревшие переводы отклоняются.
  • Восстановлены заголовок и якорь optional-archive providers.
  • Исполняемая проверка CMake учитывает 58 опций.
  • Managed bin/obj исключены из сайта; rendered-аудит сохраняет авторские исходники.
  • Аннотации поиска ограничены 224 символами; слова полного документа и лимит байтов сохранены.

Миграция

  • База: 2026.1.31-dev, b197060d30d01ac74d7a203039a6bdb379c17948. Сохраните владение RefType (29), требуемое принятие ACM (30), ограниченный обзор (31): ABI 9, runtime 0.0.72. Новых миграций скриптов, конфигурации, схем ресурсов и данных нет; runtime-семантика прежняя.
  • Выполните python BuildTools/docs_prepare.py для моделей, EN/RU, фрагментов, сайта/маршрутов и AI; проверьте governance, происхождение, переводы и версию. Пересборка/упаковка использует 2026.1.32-dev. Откат возвращает документацию/тесты базы 31 и согласованные сборки без изменения игры и владения.

2026.1.31-dev - 2026-10-11

Добавлено

  • Player.ViewMapArea(map, hex, radius) открывает живой фиксированный обзор области, сохраняя управление персонажем на глобальной карте. Динамические объекты фильтруются гексным расстоянием с включённой границей; появление и уход обновляются событиями движения и предметов. Клиент первоначально центрирует камеру и закрывает внешнюю область независимо от настройки обычного тумана.
  • Player.ReturnFromViewMap() восстанавливает обычное отображение управляемого персонажа. Существующий отсоединённый ViewMap сохраняет полный административный обзор карты.

Исправлено

  • Камера ограниченного обзора поддерживает обычную прокрутку без переноса области видимости. Смена размера сохраняет положение камеры в авторских скролл-границах. Внешняя маска использует переопределяемый primitive-эффект тумана с плавным краем внутрь области и полной непрозрачностью снаружи.
  • Ограниченный обзор карты учитывает авторские границы прокрутки камеры при центрировании, смене масштаба и размера экрана. Область видимости остаётся вокруг центрального гекса, даже когда камера останавливается у края карты.

Миграция

Сетевое сообщение ViewMap теперь содержит int32 радиус после центрального гекса (ноль для прежнего полного обзора). Сетевая совместимость повышена с 0.0.71 до 0.0.72; обе стороны и метаданные скриптов пересобираются вместе. Миграция постоянных данных карты, предметов или персонажей не нужна: подписки и границы обзора существуют только в рантайме. Ограниченный обзор передаёт актуальные позиции при смене гекса и не передаёт будущие маршруты движения. Возврат требует полного графа начальной информации управляемого персонажа; состав глобальной группы отправляет проект под покрытием группы.

При подключении плавного края ограниченного обзора перепеките ресурсы, чтобы включить Effects/Primitive_ViewAreaFog.fofx. Проект может переопределить эффект, сохраняя полную непрозрачность внешней области. Для прокрутки нужны обычные обработчики ввода проекта на экране ограниченного обзора; центр и радиус видимости по-прежнему определяет сервер.

База: e1a3815ff96c7d88f47314984e9d9242e37bc585 (2026.1.30-dev); эта обновлённая правка ограниченного просмотра — 2026.1.31-dev. Сначала выполните предыдущую миграцию владения Managed RefType и пересоберите/перезапеките все роли вместе.

2026.1.30-dev - 2026-10-11

Добавлено

  • Опциональный встроенный импортёр Interplay ACM под FO_AUDIO_ACM, по умолчанию OFF. AudioBaker-Acm.* владеет состоянием unpacker на каждый декодер и соглашением Fallout о каналах; AudioBaker регистрирует загрузчик только при включённой опции. Регрессионные фикстуры декодера перенесены в Engine; проверяются автоматическое запекание Vorbis и запросы при выключенной опции.

Миграция

  • База: 2026.1.29-dev, 3a366761742204d15aa86726cc23168c9b7ec81d; версия этого изменения — 2026.1.30-dev. Defaults WAV/Ogg, точные пути, воспроизведение, громкость и значения существующих исходников сохраняются. Импортёр относится только к Baker и не зависит от backend/platform; новая сторонняя библиотека не требуется.
  • Проекты с локальным ACM-загрузчиком задают SetOptionValues(FO_AUDIO_ACM ON) перед StartProjectGeneration, удаляют его исходники/тесты из AddEngineSources, include и регистрацию audio_baker->AddLoader(LoadAcmAudio, {"acm"}) из SetupBakersHook. Остальные проектные bakers/hooks сохраняются. Прямые пользователи декодера включают AudioBaker-Acm.h и используют AudioBakerAcm::Decoder, AudioBakerAcm::DecoderException и AudioBakerAcm::Load(string_view, FileReader); объявления доступны только при включённой опции. Перед миграцией ищите AcmDecoder, LoadAcmAudio, .acm и FO_AUDIO_ACM в CMake, presets, окружении и нативных расширениях. Проекты только с WAV/Ogg оставляют OFF; миграция их исходников не требуется.
  • Сохраните префикс sound/music/ без учёта регистра для стерео ACM; остальные ACM-пути означают моно даже при стерео-заголовке. Частота исходника положительна, число PCM-сэмплов образует полные непустые кадры. Unpacker сохраняет исходную арифметику переполнения/дополнения; выход остаётся Vorbis по авторскому пути. Добавляйте acm в проектный Audio.SoundFileExtensions, только когда нужен каталог инспекции; default Engine остаётся wav ogg.
  • Выполните реконфигурацию, пересоберите baker и затронутые нативные цели, затем запеките все пакеты с Audio. FO_AUDIO_ACM участвует в FO_BAKING_CONFIG_HASH: отсутствующий/изменённый fingerprint вызывает полное запекание и записывается только после успеха. При OFF запросы ACM для коллекции и отдельного пути падают до incremental skipping с Audio importer is disabled; enable FO_AUDIO_ACM и путём. Проверяйте тесты декодера, enabled/disabled bake, счётчики/пути/каналы реальных ACM-пакетов и воспроизведение в клиенте с активным устройством.
  • Конвертации сохранённых сущностей/БД, migration rule, изменений сетевого marker (upstream 0.0.71), схемы sprite/resource и host/runtime ABI нет. Поставляйте запечённый Vorbis по прежним путям. Откат восстанавливает прежний baker и проектные исходники/регистрацию загрузчика вместе, затем выполняет полное запекание; не смешивайте регистрации двух владельцев.

2026.1.29-dev - 2026-10-11

Исправлено

  • Managed C#-конструкторы с фабрикой создают пригодный нативный объект и разделяют учёт фабрики. Типы без фабрики не имеют публичного конструктора без аргументов; динамические DTO сохраняют обычное создание.
  • Обёртки с подсчётом ссылок автоматически удерживают одну нативную ссылку. Фабрики и PassOwnership передают её; остальные результаты, аргументы callback/событий и элементы коллекций получают собственную. Забытое владение ставится в очередь очистки потока движка; shutdown очищает очередь и живые обёртки до сборки сущностей/unbind. Нативные вызовы удерживают обёртки.

Добавлено

  • Стандартное владение IDisposable/using скрывает __Factory, __AddRef и __Release из публичного managed API. Нативное действие Dispose без аргументов выполняется до возврата ссылки: FogLayer.Dispose() удаляет слой и закрывает обёртку одним вызовом.

Миграция

  • База: 6a1f03880a84e097cfedee6d331178aad89e390d (2026.1.28-dev); сначала примените версии 26–28 ниже. Проверенные более ранние исходники 16f1608794 имеют дефект конструктора с нулевым указателем. Меняются все managed-роли; нативные/AngelScript-сигнатуры, ID, значения по умолчанию и схемы свойств/данных прежние.
  • Замените __Factory() на new, уберите ручной __AddRef(), замените __Release() на Dispose()/using. Полученные от движка обёртки автоматически удерживают нативные объекты. C#-алиасы разделяют освобождение; независимые обёртки имеют собственное владение. Динамические DTO и обёртки без подсчёта ссылок не получают интерфейс.
  • Найдите создание без аргументов SpritePattern, FogLayer, VideoPlayback, TimeEventContext, MovingContext и используйте создающие API. Скомпилируйте все роли для проверки алиасов и target-typed new().
  • Держите holder Map.DrawMapSprite до последнего отрисованного кадра, затем StopDraw() и Dispose(). Область using должна включать этот кадр; срок GC не определён. Прямой fog.Dispose() и using выполняют нативную очистку и закрытие обёртки; уберите прежние два шага. Повторный вызов и освобождение после shutdown безопасны. Получение указателя и boxed/packed-аргументы закрытой обёртки отклоняются. Ошибка очистки сохраняет владение для повторной попытки без повтора выполненного нативного действия.
  • Пересоберите согласованные нативные компоненты и перевыпеките все роли с ABI identity 9. Совместимость runtime меняется с 0.0.70 на 0.0.71; бинарники/ресурсы и клиент/сервер обновляются вместе. Предыдущие неопубликованные ABI 8/runtime 0.0.70 также требуют пересборки. Следуйте порядку пересборки. Конверсия сохранённых данных и резервных копий не нужна.
  • Откат пересобирает/перевыпекает прежние согласованные исходники для всех сторон, возвращая их ручное владение и поведение конструкторов. Прежние требования к компонентам, хранилищу, блокировкам выпечки, миграции документов и серверной сетке ниже сохраняются.
  • Тесты генератора проверяют публичный API; тесты времени жизни — автоматическое получение ссылок, нативную очистку, GC, повторные попытки, алиасы, конструкторы, shutdown и изоляцию backend. Приёмка runtime проверяет свойства, отрисовку, using/освобождение и штатное завершение. См. правила времени жизни и проверки.

2026.1.28-dev - 2026-10-11

Исправлено

  • Удалены лишние завершающие пустые строки из шести native-файлов запросов дисплея; локальные hstring в обработке метаданных и тестах объявлены явно. Оба const-контейнера, выбирающие прокси свойств только для чтения, и пояснения анализатору сохранены.
  • Регрессия фрагментов согласована с проверенным корпусом из 470 примеров и 311 нормативных фрагментов; сокращены формулировки руководства по конфигурации и нормализованы четыре CMake-комментария. Полное нормативное покрытие и проверки отказов сохранены.
  • Ссылки на владельцев импорта изображений и правила переноса пользовательских native-загрузчиков согласованы с выделенными модулями.

Миграция

  • База: 2026.1.27-dev, 5ef9334595f45522c8d580c25e22ed4556ab137b; сначала выполните её миграцию блокировок и сборочного glue. Эта очистка не меняет runtime, API, опции, ABI, форматы ресурсов/сохранений или сетевую совместимость (0.0.70). Повторите конфигурацию и пересоберите согласованные native-хосты и ролевые метаданные/скрипты для 2026.1.28-dev; перегенерируйте EN/RU, фрагменты, сайт/маршруты и AI delivery. Проверьте форматирование, native/process-lock тесты и переход версии.

2026.1.27-dev - 2026-10-11

Добавлено

  • Перемещаемый fs::exclusive_file_lock и неблокирующий fs::try_lock_file: захват без усечения, Unicode/long paths, явное освобождение, передача владения и ненаследуемые native-дескрипторы. Web возвращает недоступную блокировку.

Исправлено

  • Канонический выходной каталог запекания защищён соседним file lock до удаления report/hash и до завершения записи отчётов. Отказ сохраняет прежние outputs даже при повторном использовании MasterBaker. Принудительная пересборка не удаляет inode блокировки.
  • Компиляция ролей AngelScript и пакетов на порядке скриптов последовательна только при AS_DEBUG; diagnostic lock рабочего каталога защищает между Baker-процессами. Release сохраняет заданный параллелизм.
  • Только native baker записывает скомпилированный resource build hash под output lock. Убрана незаблокированная запись CMake после завершения baker; генерация hash native binaries прежняя.

Миграция

  • Версия Engine — 2026.1.27-dev, следующая minor после опубликованного master 2026.1.26-dev. Повторите конфигурацию и сборку native bakers и метаданных версии, затем штатное запекание. Script bindings, network marker, sprite format, БД и сохранения не требуют конверсии.
  • Оставляйте <BakeOutput>.lock рядом с выходным каталогом и AS_DEBUG.lock в рабочем каталоге. Игнорируйте эти производные файлы в проектах: наличие файла безопасно. Не удаляйте их для снятия contention; остановите или дождитесь владельца, проверьте права и повторите запуск. Отказы lock предшествуют изменениям outputs/report/hash; корни файловых систем запрещены как BakeOutput.
  • fs::try_lock_file не создаёт родителей, не усекает содержимое и не ожидает. Незахваченный lock также означает недоступный путь или неподдерживаемый Web, а не только другого владельца. В POSIX exclusion advisory: участники должны использовать один inode. Держите владельца lock до завершения защищённой работы и отчётов.
  • Debug-bake с AngelScript требует доступного для записи diagnostic lock; разные рабочие каталоги допускают независимое debug-запекание. Обычная Release-компиляция остаётся параллельной. Защита относится к MasterBaker, а не произвольным внешним процессам AngelScript.
  • Пользовательские CMake wrappers не должны писать Resources.build-hash после возврата native Baker. Скомпилированный baker записывает его до освобождения lock; сохраняйте WriteBuildHash только для native binary markers. Контракт revision/hash остаётся привязанным к скомпилированным исходникам. При rollback возвращайте старый baker и build glue вместе и завершайте запекание до использования outputs.

2026.1.26-dev - 2026-10-11

Изменено

  • CMake TemporaryCompat задаёт срок ограничениям, включая неактивные ветки. Выбор БД не запрещён для Web.
  • Проекты выбирают соседние модули архивов/БД/изображений под guards через положительные SetOptionValues; регистрация source/header безусловна. Memory и PNG/TGA/FOFRM обязательны. ZAR/TIL разделяют decoder под guard с сохранением порядка каналов.
  • JSON-файлы используют обычный JSON, BLOB SQLite — CBOR, BSON принадлежит только Mongo. Внешние ZIP/BOS опциональны; Embedded/APK сохраняют zlib/minizip. Опции с отметкой влияния на бейкинг инвалидируют ресурсы независимо от ревизии проекта; БД и служебные опции исключены.

Миграция

  • В явных входах temporary_compat.py укажите Engine/BuildTools/cmake и файлы CMake проекта. Ограничения помечайте TemporaryCompat(Id "YYYY-MM-DD"); CI проверяет истечение срока, сохраняя воспроизводимость конфигурации.
  • Предыдущая версия: 2026.1.25-dev, 16f1608794eafeb6c05001b997071105dbc403b9. Выбор компонентов перечисляет опции, роли, зависимости и диагностику; persistence задаёт новую схему/пределы.
  • Удалите FO_DISABLE_MONGO/FO_DISABLE_SQLITE из CMake, presets, окружения и кеша (cmake -UFO_DISABLE_MONGO -UFO_DISABLE_SQLITE ...). Явно включите используемые FO_DATABASE_JSON, FO_DATABASE_SQLITE, FO_DATABASE_MONGO, FO_DATA_SOURCE_DAT, FO_DATA_SOURCE_ZIP, FO_IMAGE_* через SetOptionValues. Все optional defaults OFF; старые опции и выключенные компоненты завершаются ошибкой, без aliases/fallback.
  • Найдите native-вызовы ImageBaker::FrameShot, FrameSequence, FrameCollection, LoadFunc, MAX_DIRS_MINUS_ONE: замените префикс на ImageImport::. Аргумент четыре loader становится const ImageImport::Context&; используйте context.Files, context.Resolve(path). Необязательный аргумент три AddLoader задаёт выходное имя. Подключите соседние DataBase-{Memory,Json,SQLite,Mongo}.h; фабрики теперь DataBaseMemory::Create, DataBaseJson::Create, DataBaseSQLite::Create, DataBaseMongo::Create, инициализация — DataBaseSQLite::InitializeRuntime. BSON-конвертеры/инициализация allocator приватны Mongo.
  • Используйте новые пустые каталоги JSON/SQLite. Для старых Extended JSON/BSON BLOB нет reader и миграции; для отката сохраните старые binaries/storage вместе. Mongo сохраняет представление. Правил преобразования entity/property нет; codecs сохраняют текущие AnyData по owning-документу persistence.
  • Повторите configure, генерацию bindings/metadata, совместную сборку затронутых native-ролей, full bake и упаковку matching outputs. Resources.baking-config-hash/report bakingConfigHash независимы от Resources.build-hash; отсутствие/смена конфигурации бейкинга удаляет stale outputs. Контракт отпечатка учитывает геометрию, модели/эффекты, скрипты и частицы вместе с загрузчиками архивов/изображений. Совместимость 0.0.69 → 0.0.70: смешанные binaries/snapshots запрещены; поставляйте matching client/server metadata, откатывайте полный комплект binaries/resources/storage. Протокол updater, идентификатор client-runtime ABI и версия baked sprites сохраняются.
  • Перегенерируйте contracts/snippets, EN/RU, сайт/routes и AI delivery. Проверьте minimal/full suites БД/архивов/изображений/baker, reopen/recovery и ошибки выключенных компонентов; platform/runtime proof фиксируйте отдельно. Публикация не подразумевается.

2026.1.25-dev - 2026-10-10

Исправлено

  • При уничтожении существа связи снимаются без рассылки снимка attachments от участника, который уже уничтожается. Живые участники получают штатное уведомление, проверки состояния сущностей сохраняются.
  • При финализации клиентского представления существа освобождается кеш идентификаторов прикреплённых существ; живые участники сохраняются, проверки очистки в деструкторе остаются. Native-регрессии охватывают обычное отсоединение, уничтожение любого участника, исходящие уведомления attachments и сообщения об исключениях.

Миграция

  • Повторите конфигурацию и сборку native-клиентов, серверов и unit-тестов, затем выпечку ресурсов проекта перед проверкой. Преобразование вызовов проекта или данных не требуется. Смысл API, настроек, сетевой совместимости 0.0.69, ABI, схем ресурсов и сохранений не изменился; правило миграции не требуется.
  • После интеграции обновления перегенерируйте фрагменты документации, состояние перевода, сайт, поиск, маршруты, оценку материалов для ИИ и AI delivery.

2026.1.24-dev - 2026-10-10

Добавлено

  • Клиентские скрипты получают размер рабочего стола и режимы монитора текущего окна через Game.GetDisplaySize и Game.GetDisplayModes. Из результатов SDL исключаются неверные и повторяющиеся размеры; при недоступности сведений возвращаются нулевые размеры или пустой список. Headless-окна и заглушки возвращают тот же признак недоступности.

Миграция

  • Предыдущая версия — 2026.1.23-dev, ревизия e08ca424e4f24561d6610686b2b9f9548b9365db. Обновление конфигураций примеров сохранено; эти методы дисплея не требуют дополнительных преобразований настроек проекта.
  • Смысл существующих вызовов, настроек и сохранённых данных сохраняется; преобразование вызовов или данных не требуется. Перед использованием двух новых методов перегенерируйте привязки и запеките скрипты. Ограничения разрешения, стандартные варианты и резервный список при недоступных сведениях определяет вызывающий проект.
  • Пересоберите Engine и native-бинарники проекта вместе из-за дополнительных виртуальных методов IAppWindow и поставляйте соответствующие запечённые метаданные. Сетевая совместимость остаётся 0.0.69; сетевые форматы, схемы ресурсов и сохранения не меняются. При переходе на 2026.1.24-dev повторите конфигурацию native-метаданных версии и ревизии, перегенерируйте API-справочники, состояние переводов, сайт, поиск, маршруты и AI-доставку.

2026.1.23-dev - 2026-10-10

Исправлено

  • Пересозданы полные конфигурации MinimalMultiplayer, ContentShowcase и PackagingMatrix после замены серверных настроек сеток. Все три используют Server.ProtoMapGridType = Dynamic и Server.MapInstanceGridType = Dynamic, сохраняя прежний динамический режим по умолчанию. Существующие проверки актуальности и пакетов примеров контролируют эти сгенерированные входы. См. generated content.

Миграция

  • Предыдущая версия — 2026.1.22-dev, ревизия bf673df1818c10aaf77c586077caf60cbd2e904f. Дополнительная миграция проекта не требуется: обновлены конфигурации примеров Engine для настроек, введённых в указанной версии. При переходе с более старого Engine соблюдайте её заметки о миграции. Native-поведение, host/runtime ABI, сетевая совместимость, схемы ресурсов, форматы карт и сохранений, правила базы данных не меняются; преобразование данных не требуется.

2026.1.22-dev - 2026-10-10

Добавлено

  • Скрытые замеры ServerMapGridMemoryDynamic и ServerMapGridMemoryChunked для пустых/населённых карт, растущей истории записей полей, уничтожения и остановки. Сравнение новых процессов сообщает private bytes и проверяет одинаковые число сущностей и поведение полей без лимита памяти. См. тестирование.
  • Скрытый benchmark ServerMapGridOperationsCost для настоящих серверных операций пути, достижимости, трассировки, чтения полей и изменения блокировок во всех девяти сочетаниях плотной, чанковой и хеш-сетки прототипа и экземпляра. Он проверяет одинаковые результаты и сообщает пять прогретых замеров стены и CPU без временных порогов. См. тестирование.
  • Независимые строковые настройки сеток общих прототипов и экземпляров карт: Server.ProtoMapGridType и Server.MapInstanceGridType по умолчанию Dynamic и принимают только Static, Chunked или Dynamic. Неизвестное или пустое значение прерывает запуск сервера. Это три соседние реализации; сетка чанков не наследуется от статической. Сторона блока задаётся через GameSettings::SERVER_MAP_CHUNK_SIDE (16). См. хранение серверных полей.

Исправлено

  • Единый массив полей клиентской карты заменён плотными блоками 16x16 с прямой индексацией, создаваемыми при первой записи. Большая карта больше не требует одного непрерывного выделения для всех полей. Пустое чтение, прокрутка, пересечение координат resize Mapper и unload сохраняют поведение; буферы освещения остаются плотными. Добавлены проверки памяти настоящей большой карты, границ блоков и владения, а также скрытое сравнение стоимости нативного доступа к полям. См. хранение полей клиента. Сторона блока задаётся параметром шаблона; MapView выбирает её через константу времени компиляции GameSettings::CLIENT_MAP_CHUNK_SIDE (16).

Миграция

  • Предыдущая версия — 2026.1.21-dev, ревизия cfa468f17bd5dff82cebc6f05b568620fc34163c. ChunkedTwoDimensionalGrid — новый нативный тип хранения; StaticTwoDimensionalGrid и DynamicTwoDimensionalGrid сохраняют свои контракты. Закрытое поле MapView::_hexField использует новый тип. Native clients, embedded clients и Mapper на всех платформах/backend требуют пересборки всех потребителей заголовков MapView: меняется закрытая C++ компоновка. Преобразование смысла координат, формата карт, сохранений или базы данных не требуется. Старые native objects нельзя смешивать с новыми заголовками.
  • Соблюдайте порядок generated content: configure/codegen, пересборка затронутых native applications и тестов, выпечка соответствующих metadata/resources, переупаковка пары host/runtime. Версия host/runtime ABI, схемы ресурсов, сетевая совместимость 0.0.69 и database MigrationRule не меняются. Замените опубликованные булевы настройки ProtoMapStaticGrid и MapInstanceStaticGrid соответствующими строками ProtoMapGridType и MapInstanceGridType. Для каждого слоя прежние флаги static/chunk переводятся в Dynamic при static=false, в Static при static=true и chunked=false, в Chunked при обоих true. Ранние незакоммиченные ключи ProtoMapChunkedGrid, MapInstanceChunkedGrid, ProtoMapStaticGridChunked и MapInstanceStaticGridChunked удалены; псевдонимов нет. Перегенерируйте bindings и выпеките соответствующие metadata. Нативные вызовы StaticMap теперь передают (size, grid_type); конструктор Map больше не имеет noexcept, неверный выбор вызывает SettingsException. Откат использует целый предыдущий native package; восстановление базы не требуется.
  • Выполните ClientLargeMap*, TwoDimensionalGrid, регрессии client-map/lifetime, ServerMapGridSelectionPreservesFieldBehavior, проверки неверного выбора и освобождения владельца при ошибке конструктора, а также server-map/lifetime, sprite/atlas/roof, сравните повторные запуски ClientMapFieldAccessCost и ServerMapGridOperationsCost и проверьте обычный отрисованный вход на карту в проекте. Заготовки памяти конструктора и стоимости доступа не доказывают отсутствие OOM в долгом 32-битном сеансе, FPS всей игры или пропускную способность тиков сервера. После интеграции перегенерируйте snippets, состояние перевода, сайт/поиск/маршруты, оценку для ИИ и AI delivery.

2026.1.21-dev - 2026-10-10

Исправлено

  • Изменяемые списки и словари Managed-событий записываются через accessor коллекции вызывающей стороны после преобразования записей. Нативные прокси сохраняют адреса элементов контейнера после добавления и роста вектора, обновляют порядок словаря, соблюдают вставку повторного ключа и запрет записи в const-контейнер.
  • Добавлена переиспользуемая native-проба boxed-событий коллекций из исходников Engine: GC, внешний script context, shutdown и тот же отрицательный контроль без обратной записи. Нужны заданная Managed unit-сборка GCC/Clang Ninja и подготовленный runtime хоста; квалификация других payload/toolchain остаётся отдельной.
  • В синхронных контекстах документов базы данных AngelScript и Managed хранятся гарантированно ненулевые заимствования ptr<const AnyData::Document>. Чтение документов, проверки срока жизни callback и поведение миграций не изменились.
  • При восстановлении сущностей и глобального состояния явно отброшен признак наличия изменений миграции документа. Оба вызова по-прежнему сохраняют выходной набор обновлений и пропускают исключения миграции; устранены два предупреждения Clang nodiscard.
  • Применён штатный формат clang-format 20 к include backend AngelScript и Managed-привязкам миграций документов; CI форматирования больше не создаёт diff этих файлов.
  • Проверен полный AI-контекст из 112 документов: версия 20 достигла 2 228 855 байт. Жёсткий лимит увеличен на 32 KiB до 2 260 992 байт; документы целиком, история миграций и действующая политика состава сохранены.

Миграция

  • Пересоберите нативные скриптовые backend и выполните выпечку затронутых ролей. Действующие обработчики событий с ref List<T> и ref Dictionary<K, V> теперь передают итоговые коллекции вызывающей стороне и следующим подписчикам; менять сигнатуры обработчиков и scalar ABI не требуется.
  • Потребители AI delivery должны учитывать увеличение full_context.max_bytes в манифесте с 2 228 224 до 2 260 992 байт. Пересоздайте производные данные командой python BuildTools/docs_prepare.py до тестов исходников и актуальности, затем выполните полные проверки сайта и браузера. Превышение бюджета по-прежнему завершает проверку ошибкой, без обрезания пакета.
  • Script/native API, runtime-конфигурация, сериализованные данные, сеть, ABI, схема ресурсов и сохранения не меняются. Пересоберите метаданные версии для этой ревизии; версии документационных зависимостей и маршруты публикации сохранены.

2026.1.20-dev - 2026-10-09

Исправлено

  • Проверка архитектурной схемы и снятие скриншотов ожидают загрузки ленивых изображений. Задержанный ответ SVG больше не даёт ложного отказа; отсутствующее изображение остаётся ошибкой в каждом профиле.
  • В CI документации добавлена регрессия задержанного и отсутствующего изображения в настоящем браузере.

Миграция

  • Script/native API, конфигурация, сериализованные данные, сеть, ABI, схема ресурсов и сохранения не меняются. При обновлении пересоберите метаданные версии. Версии браузерных зависимостей и полный набор маршрутов/профилей сохранены.
  • После штатной установки закреплённого Chromium запустите npm --prefix BuildTools/docs-browser run test:diagram и полный браузерный аудит. Перегенерируйте документацию, переводы, сайт/поиск/маршруты и AI delivery для новой версии.

2026.1.19-dev - 2026-10-09

Исправлено

  • Исправлена пунктуация комментариев документных миграций.

Миграция

  • Изменены только комментарии; API и сохранения не требуют конвертации. Пересоберите метаданные версии и перегенерируйте документацию.

2026.1.18-dev - 2026-10-09

Добавлено

  • Добавлен MigrationRule Property <Owner> Remove <Old> как постоянный запрет имени. Старое значение в документе/тексте пропускается; живое объявление под этим именем отклоняется, включая поля RefType.
  • Добавлена поддержка документных Property/Proto Transform в AngelScript: [[PropertyMigrator]]/[[ProtoMigrator]], типизированное значение &inout, const DatabaseDocument&inout, автоматическая проверка исходников/байткода и связывание, синхронная атомарная подготовка результатов. Квалифицированное имя функции — Namespace::Function; AngelScript-скрипты нужно перепечь для нового зарегистрированного типа и callbacks. Массивы/словари RefType освобождаются путями своих контейнеров.

  • Добавлены атомарные обработчики Property Transform: native PropertyMigratorCallback, Managed C# [PropertyMigrator], PropertyMigrator<T> и контекст исходного DatabaseDocument. Канонические поля подготавливаются до загрузки сущности.

  • Добавлены документные обработчики [ProtoMigrator] для Proto Transform. Цепочки исходного документа разрешаются до поиска с обнаружением циклов и подготовкой _Proto; обычный lookup и bake применяют только Rename/Remove.

Изменено

  • Правила переименования свойств требуют явного действия Rename и существующего назначения. Transform проверяет существование Persistent-свойства; серверные пользовательские владельцы и их правила следуют фильтрации роли метаданных.

Миграция

  • Для удалённого свойства сохраняйте ///@ MigrationRule Property Owner Remove Old без замены. Rename и Transform остаются формами из пяти частей; Property и Proto Remove имеют четыре. Повторное имя запрещено независимо от нового типа свойства.
  • Замените каждую декларацию ///@ MigrationRule Property Owner Old New на ///@ MigrationRule Property Owner Rename Old New в native/скриптовых исходниках, генераторах, инструментах и фикстурах. Старые имена должны указывать на существующие текущие поля, включая вложенные RefType. Старая форма из четырёх частей отклоняется; Правила Proto также требуют явного действия: Rename Old New, Remove Old или Transform Old QualifiedType.Function. Прежняя замена remove отклоняется; Enum, Entity, EntityHolder и Version сохраняют формы.
  • Для переноса значений задайте ///@ MigrationRule Property Owner Transform Property QualifiedType.Function и статическую синхронную функцию с [PropertyMigrator], результатом bool и параметрами ref T, DatabaseDocument, где T точно соответствует managed-типу свойства. false оставляет исходное представление, true сериализует результат. Нельзя сохранять контекст, менять сущности, выдавать награды или определять тип ссылки по совпадению текста. Проект задаёт смысловые условия, политику коллизий, идемпотентность и фикстуры старых сохранений/перезапуска. Managed C# связывает функции автоматически; несвязанная функция отвергает перенос.
  • Пересоберите native-бинарники и выполните bake метаданных и всех managed-ролей вместе. Правила Property и Proto Rename/Transform содержат пять частей, Remove у обоих видов — четыре; внешний заголовок метаданных не меняется. Ручной маркер совместимости повышен с 68 до 69: смешанные старые/новые бинарники и ресурсы не поддерживаются. Схема БД, типы хранимых полей, сообщения транспорта, состав платформенных пакетов и поведение прочих свойств не меняются; добавленный native callback API требует пересборки встраивающих бинарников.
  • Загрузка БД переносит Game, Player, обычные и пользовательские сущности, включая пакетные пути. Исключение при подготовке оставляет документ и очередь записи нетронутыми; гарантия относится к одному документу, не ко всем документам мира. Сохраняйте правила на поддерживаемый горизонт сохранений и проверьте копию БД перед production. Перегенерируйте API/справочник, snippets, переводы, сайт/поиск и данные для ИИ.

2026.1.17-dev - 2026-10-09

Исправлено

  • Существующие деревья READY, скачанные кэши workspace, готовые входы prebuilt и свежие опубликованные managed runtime проверяются по непустым embedding-заголовкам, основным managed-сборкам и входным архивам линковки выбранной платформы. Неполные деревья восстанавливаются существующим путём кэша/повторной публикации вместо сообщения о готовности runtime без нужных линкеру файлов.

Миграция

  • Миграция скриптового/native API, ключей конфигурации, сериализованных данных, сети, ABI, схем ресурсов и сохранений не требуется: изменение проверяет входы подготовки сборки и сохраняет смысл комплектных runtime. При переходе на эту ревизию Engine повторите конфигурацию и сборку native-метаданных версии и ревизии.
  • Для восстановления неполного дерева READY запустите обычный target SetupManagedRuntime (либо BuildTools setup-mono <os> <arch> <config>). Без workspace-кэша действующие маркеры исходников/объектов позволяют повторить публикацию без перекомпиляции Mono; настроенный кэш принимает комплектные записи и пересобирает неполные попадания. Комплектные деревья сохраняют прежний ключ кэша и имена маркеров.
  • FO_MANAGED_RUNTIME_PREBUILT должен указывать на комплектное дерево выбранной платформы: заголовки managed backend, CoreLib и System.Runtime.dll, статические архивы платформы и JavaScript glue браузера, если он нужен. Замените неполный prebuilt комплектным опубликованным деревом платформы; неполный вход отклоняется до копирования и записи READY. После обновления руководства перегенерируйте локализацию, сайт/поиск/маршруты, оценку ИИ и данные для ИИ.

2026.1.16-dev - 2026-10-09

Изменено

  • Авторская конфигурация Jekyll перенесена в Docs/Site/_config.yml. Файлы зависимостей Ruby/домена и публичные корневые endpoint генерируются в игнорируемом Workspace/Documentation/; docs_site_build.py собирает и экспортирует сайт в Workspace/DocumentationSite/. Публичные URL сохраняются.

  • Индексы доставки документации и каталоги проверок создаются при сборке, а не коммитятся: docs-manifest.json, оба endpoints llms, навигация, поиск и шесть generated-отчётов. Вход сопровождающего с checkout остаётся AGENTS.md; сайт сохраняет публичные URL для получения документации.
  • Документационные outputs подготавливаются перед проверкой CI и рендерингом сайта. Проверенный Pages artifact публикуется только после прохождения проверок версии и документации при push в master.

Исправлено

  • Значения Engine по умолчанию применяются до загрузки обычной конфигурации приложения. Настройки, пропущенные в конфигурации проекта или пакета, получают defaults из Settings.inc; явные значения конфигурации, подконфигурации, локального кэша и командной строки сохраняют прежний приоритет, включая явно заданные нули.

Миграция

  • Замените прямые команды Jekyll на python BuildTools/docs_site_build.py; после подготовки установите зависимости через bundle install --gemfile Workspace/Documentation/Gemfile. Gemfile, .ruby-version и CNAME выводятся из исходного manifest и больше не хранятся в корне как версионируемые копии.

  • Перед локальными проверками документации или Jekyll выполните python BuildTools/docs_prepare.py. Модели публичных контрактов, Markdown, правила, переводы и SVG/PNG остаются версионируемыми и обязаны проходить freshness checks. Игнорируемые результаты доставки не добавляются в индекс.
  • Перед первым push в master с этой правкой выберите GitHub Actions источником сборки Pages; прежняя сборка из ветки не может создать игнорируемые файлы. Проверьте первый опубликованный артефакт и существующие публичные endpoints. Правка рабочего дерева не переключает удалённые настройки и не публикует сайт.
  • Повторите конфигурацию и сборку затронутых нативных приложений, затем bake и проверку профилей запуска встраивающего проекта. Проверьте ранее пропущенные настройки: теперь они получают объявленные defaults вместо нулей от инициализации значением. Имена настроек и объявленные defaults не меняются, явные значения сохраняют смысл.
  • Нативный и скриптовый API, сетевая совместимость 0.0.68, ABI, схемы ресурсов и сохранённые данные не меняются. Преобразование исходников проекта или сохранённых данных не требуется.

2026.1.15-dev - 2026-10-09

Изменено

  • Маршруты и отчёт переводов объединены в docs-manifest.json. Навигация и данные для ИИ ссылаются на VERSION; сборка Jekyll читает его значение вместо хранения копий версии. Поиск исключает технические HTML-комментарии, а полный контекст для ИИ оставляет хэши документов в публичном индексе.

Миграция

  • Потребители документации должны заменить Docs/generated/document-routes.json на docs-manifest.json#/routing, а Docs/generated/translation-status.json — на docs-manifest.json#/translation_status. Это разделы JSON одного файла, а не пути файловой системы. Схема данных для ИИ — 3, схема сайта — 4; смысл полей отчётов и хэши проверки переводов сохраняются. Прежние отдельные отчёты удалены.
  • Перегенерируйте локализацию, сайт/поиск/маршруты, оценку ИИ при необходимости, затем данные для ИИ. Шаблон Jekyll включает VERSION напрямую; сохраняйте includes_dir: . в _config.yml для локальной сборки и GitHub Pages. Публикуйте корневой VERSION побайтно. Миграция native/скриптового API, конфигурации, сериализованных данных, сети, ABI, схем ресурсов и сохранений не нужна.
  • При переходе на эту ревизию Engine повторите конфигурацию и сборку native-метаданных версии и ревизии.

2026.1.14-dev - 2026-10-08

Исправлено

  • Восстановлен выбор моделей после отказа отправки или ожидания SDL_GPU readback. Неуспешный запрос сообщает об ошибке и не отдаёт неподтверждённые пиксели; альфа-маска модели освобождает неуспешный reader и повторяет чтение, сохраняя последнюю готовую маску.

Миграция

  • Миграция конфигурации, вызывающего кода, сериализуемых данных, сетевого или ресурсного формата не требуется. Для восстановления чтения нужно пересобрать клиент. Существующие пороги альфа-канала и результаты успешного чтения сохраняют свой смысл; сетевая совместимость, ABI, схемы ресурсов и сохранения не меняются. При переходе на текущую ревизию Engine повторите конфигурацию и сборку native-метаданных версии и ревизии, затем перегенерируйте состояние перевода, сайт, поиск, маршруты, оценку материалов для ИИ и AI delivery.

2026.1.13-dev - 2026-10-06

Исправлено

  • Руководство Managed C# и диагностика загрузки теперь различают промежуточные файлы компиляции и опубликованные ресурсы сборок. Baker, упаковщик и backend используют описанные здесь каталоги ролей со строчными именами.

Миграция

  • Преобразование вызовов проекта, конфигурации или данных не требуется: исправлена документация существующего расположения ресурсов. Опубликованные DLL остаются в Assemblies/Assemblies-<target>/ (server, client, mapper); Assemblies/<Target>Assemblies/ содержит промежуточные файлы MSBuild. Существующие пакеты сохраняют пригодность. Смысл API, настроек, сетевой совместимости 0.0.68, ABI, схем ресурсов и сохранений не изменился. При переходе на 2026.1.13-dev повторите конфигурацию и сборку native-метаданных версии и ревизии.
  • После интеграции исправленного руководства и этой датированной записи перегенерируйте фрагменты документации, состояние перевода, сайт, поиск, маршруты, оценку материалов для ИИ и AI delivery.

2026.1.12-dev - 2026-10-06

Исправлено

  • Проверка сгенерированной конфигурации только из макросов теперь охватывает версию и ревизию Engine, добавленные контрактом версионирования. Фиксированные значения заготовки исключают зависимость теста от текущей рабочей копии.
  • Существующие проверки codegen и аргументов по умолчанию выполняются в задаче CI engine-update с явной зависимостью от pytest.
  • Объяснение отдельного кеша тестов сокращено по стандарту комментариев Engine; владение кешем и очистка не изменились.

Миграция

  • Преобразование вызовов проекта или данных не требуется. Имена, значения и порядок сгенерированных макросов сохранены; API, настройки, сетевая совместимость 0.0.68, ABI, схемы ресурсов, сохранения и поведение пакетов не изменились. Повторите конфигурацию и сборку native-метаданных версии и ревизии для этого обновления Engine.
  • Задача Ubuntu engine-update устанавливает python3-pytest и выполняет python3 -m pytest -q BuildTools/tests/test_codegen_default_args.py до проверки диапазона публикации. Локальным проверкам исходников требуется pytest; при runtime-изменениях проверки native и использующего движок проекта остаются обязательными. При интеграции этой ревизии перегенерируйте фрагменты документации, состояние перевода, сайт, поиск, маршруты и материалы для ИИ.

2026.1.11-dev - 2026-10-06

Изменено

  • Managed script projects, managed host и принадлежащие движку C#-инструменты компилируются с проверкой целочисленного переполнения. Runtime fragments и live patches используют тот же профиль. Переполнение арифметики и сужающих приведений теперь вызывает OverflowException; результаты, помещающиеся в диапазон, сохраняют смысл.
  • ucolor упаковывает маскированные компоненты цвета беззнаковой арифметикой, сохраняя все прежние значения младших байтов при включённой проверке переполнения.

Миграция

  • Полное руководство по checked-арифметике и заметки о миграции помещаются в существующий проверенный лимит full-context 2,228,224 байта. Потребители AI delivery должны соблюдать объявленный full_context.max_bytes; включение целых документов и fail-closed validation остаются обязательны.
  • Пересоберите managed baker, пересоздайте проекты host и Server/Client/Mapper, скомпилируйте каждую включённую managed-роль, запеките ресурсы и упакуйте новые assemblies. Скопированные проекты C#-инструментов собирайте с CheckForOverflowUnderflow=true; проекты движка уже задают его. Runtime fragments и patches, скомпилированные после обновления, получают checked автоматически.
  • Проверьте намеренное целочисленное оборачивание и битовые приведения signed/unsigned. Найдите в C#-исходниках умножения хешей и приведения упакованных RGBA; используйте локальный unchecked только там, где оборачивание или усечение битов является контрактом алгоритма. Например, замените оборачивающее присваивание хеша hash *= prime на hash = unchecked(hash * prime), а преобразование цвета вершины (int)color.value на unchecked((int)color.value). Обычная игровая арифметика сохраняет checked.
  • Проверьте OverflowException при переполнении сложения и сужающих приведений, оборачивание в явном unchecked и неизменность прежних корректных цветов/хешей. NaN/infinity floating point по-прежнему требуют явной проверки конечности; эта опция компилятора их не отвергает.
  • Конвертация persisted properties, saves, prototypes, native ABI, wire protocol и resource schema не требуется. Ширина числового хранения и runtime compatibility markers этим обновлением не меняются. Поставляйте новые managed assemblies вместе с соответствующей native-сборкой; предыдущий пакет служит границей rollback. Старые API aliases и миграция данных не добавляются.

2026.1.10-dev - 2026-10-05

Исправлено

  • Неопубликованные исправления интеграции TLA перебазированы на опубликованный master b1e3fa58021a171877177a19c3d26127abf486be. Изменения прежних merge-коммитов сведены в один локальный шаг; сохранены опубликованные правила Git, версия и двуязычные записи изменений.
  • Сохранены фактические имена запечённых изображений в нижнем регистре и регрессия композиции кадров, отдельные кеши тестовых процессов, условие 2D/AngelScript для теста и предусловие видимости наземных предметов. Тесты обновления клиента проверяют свободный локальный TCP-порт вместо предположения, что кандидат свободен.
  • Согласованы руководства изображений, запекания и тестирования и производная документация. Полная доставка AI сохраняет проверенный предел 2228224 байта, необходимый для этих локальных пояснений.

Миграция

  • Повторно сконфигурируйте и соберите native-клиенты, серверы и метаданные версии/ревизии вместе. Rebase не вводит преобразований вызовов TLA, настроек, протокола, ABI, схем ресурсов или сохранений; совместимость остаётся 0.0.68. Проверенный native-код не изменился. При обновлении с более раннего опубликованного движка выполните предыдущие миграции временных меток и движения по порядку.
  • Потребители доставки должны учитывать увеличение max_bytes полного контекста с 2195456 до 2228224 байт относительно этой опубликованной базы. Сохраняются включение документов целиком и отказ при превышении бюджета. Тестовые процессы используют отдельные кеши; пользовательские настройки и история маппера остаются целыми.

2026.1.9-dev - 2026-10-05

Исправлено

  • Добавлена версия опубликованной правки правил Git (8697fcd9d9); согласованы проверки и руководство версионирования.

Миграция

  • Получите upstream; переносите rebase только незалитые коммиты, даже при наличии upstream. Разошедшиеся опубликованные истории объединяйте merge; сохраняйте опубликованные предки. Миграция исходников/данных не нужна: API, настройки, протокол 0.0.68, ABI и ресурсы сохранены. Пересконфигурируйте/пересоберите метаданные версии.

2026.1.8-dev - 2026-10-05

Исправлено

  • Восстановлена обязательная запись версии и миграции после удаления значков README в 3904dc3e84.

Миграция

  • Миграция исходников проекта и данных не требуется: входящее изменение затрагивает только документацию. Повторно сконфигурируйте и соберите метаданные 2026.1.8-dev; API, настройки, протокол 0.0.68, ABI и схемы ресурсов сохранены.

2026.1.7-dev - 2026-10-05

Исправлено

  • Оценка задержки отклоняет непредставимые временные метки отправителя до изменения выборки и ограничивает опоздание перед переводом миллисекунд в наносекунды.

Миграция

  • Пересоберите нативные клиенты и серверы. Допустимые метки и настройки сохраняют смысл; формат сообщений, совместимость 0.0.68, ABI, ресурсы и сохранённые данные не меняются. Миграция вызовов или данных не требуется. Недопустимая метка вызывает Sender timestamp is outside the native clock range; проверьте оба предела знакового 64-битного числа и обычные выборки задержки.

2026.1.6-dev - 2026-10-05

Исправлено

  • Даты записи движения EN/RU исправлены на 2026-10-05 UTC.

Миграция

  • Пересоберите метаданные версии; для обновления с 2026.1.4-dev выполните миграцию движения ниже. Выполнение и данные не меняются.

2026.1.5-dev - 2026-10-05

Изменено

  • Движение с удержанием направления трассирует и продлевает планы, меняет их при поворотах и может скользить вдоль препятствий. Пошаговые аренды ограничивают продолжение движения на сервере и у наблюдателей при задержке связи управляющего клиента.
  • Общая синхронизация движения измеряет обычное время передачи, догоняет опоздавшие планы и присоединяет план на уже пройденном шаге. Это затрагивает и движение по клику; поиск пути к выбранной точке сохраняется. Наблюдатель может плавно догонять движение вместо немедленного скачка. См. движение и сетевую модель.
  • Регрессионный тест хеша сборки размещает настоящие CMake helpers рядом с временным проектом и поддерживает checkout и временный каталог Windows на разных дисках.

Миграция

  • Обновите сервер, управляющие клиенты и наблюдателей вместе. SendCritterMoveLease и CritterMoveLease расширяют сетевой протокол; маркер совместимости повышен с 0.0.66 до 0.0.68. Повторно сконфигурируйте и соберите нативные приложения и библиотеки runtime, перепеките обе стороны из одной ревизии исходников. Не обходите проверку совместимости ради смешанных ревизий. Это изменение движения не переименовывает сохраняемые свойства/прототипы и не требует преобразования сохранений.
  • Проверьте новые Network.LinkDelayWindowMs, Network.LinkDelayRebaseMs, Network.MoveLateCatchUpMinMs, Network.MoveLateCatchUpMaxMs и Network.MovePlanJoinMaxSteps во всех затронутых конфигурациях. Смысл прежних настроек сохранён. Ищите точные ключи в исходниках конфигурации; отсутствующий ключ получает документированное значение по умолчанию. Нулевой предел присоединения отключает его.
  • Проверьте новые Client.DirectMoveTraceSteps, Client.DirectMoveExtendAheadSteps, Client.DirectMoveLeaseSteps, Client.DirectMoveLeaseRenewSteps, Client.DirectMoveRetargetMinMs, Client.DirectMoveRetargetImmediateAngle и Client.DirectMoveSlide. Пределы продления/возобновления должны быть меньше пределов трассы/аренды. Переписывать заданные точки движения и обычные вызовы движения по клику не требуется.
  • Проверьте новые Client.MoveCatchUpRate и Client.MoveCatchUpSmoothMaxMs для воспроизведения движения наблюдателем. Перегенерируйте API скриптов и справочник настроек, скомпилируйте затронутые скрипты; все четырнадцать дополнений — настройки только для чтения, а не изменяемое состояние скриптов.
  • Проверьте движение прямо с удержанием направления, повороты, остановку и края препятствий управляющим и наблюдающим клиентами, затем обычные цели по клику и прерывания. Повторите с задержкой, джиттером и зависанием передачи, проверяя истечение аренды и согласование поздних планов. Для диагностики доступна прежняя Network.MoveSyncTrace; вне диагностических запусков она должна быть выключена. Проверка поведения и проверка производительности имеют отдельные результаты.
  • В копии тестового проекта хеша сборки размещайте три настоящих CMake helper-файла рядом с ним вместо относительного пути через границу дисков. Поведение маркеров в производственной сборке не меняется.
  • Перегенерируйте конфигурации MinimalMultiplayer, ContentShowcase и PackagingMatrix их владельцами generate_config.py, чтобы включить четырнадцать настроек движения. Реестр нативных тестов включает Test_LinkDelay.cpp; проверки двуязычной документации и примеров теперь учитывают две страницы политики версий.
  • Потребители поиска документации должны учитывать проверенный max_bytes манифеста для каждой локали, повышенный с 1 835 008 до 1 867 776 байт ради полного корпуса движения/настроек и миграции. Состав документов, правила токенов и отказ при превышении лимита сохранены; лимит полного контекста для ИИ не меняется.

2026.1.4-dev - 2026-10-04

Исправлено

  • Установка POSIX-обработчиков сбоев и повторное возбуждение сигнала с действием по умолчанию компилируются, когда операции над наборами сигналов в Darwin SDK заданы функциональными макросами. Пять вызовов сохраняют маски, флаги и значения сигналов; прежнее поведение функций в Linux сохранено.

Миграция

  • После обновления ревизии движка пересоберите затронутые нативные цели macOS. API проекта, настройки, сохранённые данные, ABI, протокол и формат ресурсов не меняются, поэтому миграция вызывающего кода и данных не требуется.

2026.1.3-dev - 2026-10-04

Исправлено

  • Тест документации конфигурации и инструментов учитывает все 194 обязательных актуальных перевода, включая страницы правил версий и истории изменений. Требования точного списка, отсутствия пропущенных переводов и полной локализации сохранены.
  • Оба руководства по переводу документации показывают тот же актуальный список страниц, что и сгенерированная модель локализации.

Миграция

  • Миграция проекта и преобразование данных не требуются: изменяются только документация и ожидания её теста. API игры, настройки, сохранённые свойства, нативный ABI, совместимость сети и форматы ресурсов сохраняют действующие контракты.

2026.1.2-dev - 2026-10-04

Исправлено

  • Хранилище сохранённого нативного контекста трассировки стека в macOS теперь вмещает контекст libunwind из SDK. Выравнивание на шестнадцать байт сохранено; остальные поддерживаемые платформы сохраняют прежний размер хранилища.
  • Форматирование нативных и управляемых исходников и поясняющие комментарии приведены к действующим проверкам стиля. Английское и русское руководства по отладке описывают границу платформенного контекста.
  • Проверки полноты документации учитывают новые страницы правил версий и истории изменений и их нормативные примеры, сохраняя точный список документов и контроль полноты.

Миграция

  • API игры, настройки, сохранённые свойства, протокол, ABI и формат ресурсов не заменяются. Существующие допустимые входные данные и маркеры совместимости выполнения сохраняют смысл, поэтому миграция данных проекта не требуется.
  • После обновления ревизии движка повторно сконфигурируйте и соберите нативные цели. Компиляция macOS должна использовать её SDK для проверки утверждения о размере сохранённого контекста; тесты Linux не подтверждают эту ветку macOS. Версия проекта и хеши сборок пакетов/обновления клиента остаются под управлением проекта.

2026.1.1-dev - 2026-10-04

Добавлено

  • CalVer движка из VERSION проверяется при конфигурации CMake, встраивается в FO_ENGINE_VERSION и выводится в логах запуска нативных приложений. FO_ENGINE_REVISION содержит SHA Engine и отметку -dirty при изменении отслеживаемых файлов отдельно от хеша сборки игрового проекта.
  • Ссылка версии в документации открывает эту историю изменений на выбранном языке. Данные навигации и маршрутов, а также данные для ИИ получают версию движка из того же исходного файла.
  • Двуязычные заметки и проверки выпуска задают владельца значимых для разработчиков изменений и обязательных инструкций миграции.

Изменено

  • Поддержка только актуального API Engine сохраняет первоначальный смысл существующих значений. Замены удаляют старый API и обеспечивают явные ошибки компиляции/перепекания/валидации и исчерпывающие двуязычные миграции; существующее преобразование сохранённых свойств через MigrationRule остаётся узким исключением.
  • Каждый опубликованный шаг master увеличивает minor и фиксирует год/дату UTC; релизные линии сохраняют год/major/minor среза и увеличивают patch, используя -rc при стабилизации. Правки только документации, CI, тесты и зависимости тоже учитываются.

  • Историческая заглушка 2022.1.0.wip в VERSION заменена идентификатором разработки в формате CalVer. Существующие исторические аннотации API Since сохраняют прежние значения.

Миграция

  • Ограничение полного контекста увеличено с 2 162 688 до 2 195 456 байт, чтобы включить полные обязательные правила обновления/миграции. Потребители данных документации учитывают объявленный full_context.max_bytes, а не фиксированный прежний буфер; включение документов целиком и проверка превышения лимита сохранены.

  • Прежняя черновая нотация YYYY.M.PATCH заменена. Используйте YEAR.MAJOR.MINOR-dev в master и YEAR.MAJOR.MINOR.PATCH[-rc] в release/YEAR.MAJOR; major — номер линии, месяц записан в дате заметки. Первое принятие политики задаёт 2026.1.1-dev. Потребители прежнего синтаксиса версии должны принимать эти точные формы и отвергать прежние суффиксы/окончательные трёхпольные версии; общий парсер — BuildTools/engine_version.py. Перед обновлением выполните полный список обновления, последовательность среза релиза и запись миграции.

  • Политика версий в манифесте документации теперь использует схему версии 3 и объявляет engine: {scheme: calver, source: VERSION, master_format: YEAR.MAJOR.MINOR-dev, release_format: YEAR.MAJOR.MINOR.PATCH[-rc]}. Собственные потребители, перегенерирующие эти артефакты, должны включить эту политику и предоставить файл VERSION движка. Обновляемая документация по-прежнему соответствует master.
  • Повторно сконфигурируйте и соберите нативные бинарники, чтобы получить идентификаторы движка. Версия игры, хеши сборок пакетов и обновления клиента, хеш совместимости выполнения, версии ABI и схем ресурсов сохраняют свои контракты; это изменение не требует миграции данных или повышения версии схемы ресурсов.

Предыдущая история

Поддерживаемый журнал начинается с подключения версии движка. Предыдущая работа доступна в истории репозитория и реестре изменений контрактов конкретных ревизий. Это свидетельства аудита, а не восстановленная последовательность опубликованных выпусков Engine.

Введите запрос.