Введение

Обновление игрового движка посреди разработки — одно из самых пугающих рутинных решений в геймдеве. Новая версия Godot может исправить баг, который вас блокирует, — а может незаметно сломать сцену, в которую вложено полгода работы. Именно поэтому опытные разработчики в сообществе Godot относятся к обновлению версии как к решению о рисках, а не как к рутинной задаче.

Это руководство не агитирует «всегда обновляйтесь». Это чек-лист управления рисками для миграции между версиями Godot 4.x: как решить, стоит ли обновляться вообще, как подготовиться, чтобы можно было безопасно откатиться, что, как известно, ломается между версиями, и — самое главное — как на деле убедиться, что ничего не сломалось.

Стоит ли обновляться вообще?

Прежде чем что-либо трогать, честно ответьте на этот вопрос. Обновление имеет реальную цену (работа по миграции + повторное тестирование), поэтому и выгода должна быть столь же реальной.

Обновляйтесь, если…

  • Вас блокирует баг, уже исправленный в движке. Если ваша проблема уже решена в новом релизе, обновиться обычно дешевле, чем вечно обходить её костылями.
  • Новая возможность даёт вашей игре ощутимую пользу. Не «звучит неплохо», а нечто, что экономит реальное время разработки или открывает нужное вам дизайнерское решение.
  • У вас длинный цикл разработки. Если проект займёт годы, небольшие частые шаги (по одной минорной версии за раз) намного безопаснее одного гигантского прыжка в конце. Разрыв со временем только растёт.

Не обновляйтесь, если…

  • Релиз уже близко. Недели перед выпуском — худшее время для изменений на уровне движка. Сначала выпустите игру, обновляйтесь потом.
  • Вам нужны C# + веб-экспорт. Веб-экспорт для C#-проектов в Godot 4.x по-прежнему недоступен (отслеживается в godot#70796). Если вы полагаетесь на него в 3.x, переход на 4.x его отнимет.
  • Ваша целевая аудитория — старое железо. Godot 3.x работает на GPU класса OpenGL 2; рендерер Compatibility в Godot 4 требует OpenGL 3.3 / WebGL 2. Если ваши игроки сидят на старых машинах, 3.x может действительно быть правильным движком.
  • Критически важные аддоны ещё не обновлены. Если плагин, от которого зависит проект, не поддерживает новую версию, вы взваливаете на себя его проблемы миграции вдобавок к своим.

Практическое правило: обновляйтесь, когда конкретная выгода перевешивает конкретную, заранее оценённую цену — а не потому, что вышла новая версия.

Перед обновлением — подготовительный чек-лист

Каждый шаг здесь существует для того, чтобы в случае неудачного обновления вы потеряли полдня, а не проект.

  1. Закоммитьте всё и создайте ветку для обновления. Никогда не обновляйте единственную копию проекта. Отдельная ветка (или полная копия папки, если вы не пользуетесь git) означает, что откат — одна команда, а не спасательная операция.
  2. Запишите свою текущую точную версию (например, какая именно сборка 4.x.y, обычная или .NET). Она понадобится, если придётся откатываться или заполнять баг-репорт.
  3. Сохраните старый бинарник редактора. Версии Godot устанавливаются параллельно — редактор представляет собой один исполняемый файл, поэтому хранить обе версии ничего не стоит, и вы в любой момент сможете открыть старую ветку старым редактором.
  4. Перечислите свои аддоны и проверьте поддерживаемые версии каждого. Пройдитесь по addons/, отметьте, откуда взят каждый, и на его репозитории или странице в Asset Library убедитесь, что он поддерживает целевую версию.
  5. Прочитайте официальные заметки об обновлении для каждой версии, через которую перескакиваете. Официальные руководства по миграции написаны для каждой версии отдельно — если вы переходите с 4.2 на 4.4, прочитайте заметки и для 4.3, и для 4.4.
  6. Зафиксируйте «заведомо рабочее» состояние. Сделайте скриншоты ключевых сцен, запишите короткий ролик геймплея или — лучше всего — напишите автоматизированные тестовые сценарии (подробнее в разделе о тестировании ниже). После обновления на вопрос «выглядит и ведёт себя так же?» можно ответить, только если вы заранее зафиксировали, что значит «так же».

Процедура обновления

  1. Откройте копию из ветки новым редактором. Ветку для обновления, а не main. Новый редактор предложит конвертацию/реимпорт — соглашайтесь.
  2. Дайте ему выполнить реимпорт. Папка .godot генерируется заново с нуля. Первый импорт на больших проектах может занять время, а предупреждения, которые он выводит во время этого первого прохода, обычно безобидны.
  3. Проверьте панели Output и Debugger на предмет новых ошибок. Сравните с ошибками, которые были и до обновления (вы же их записали, верно?). Новые ошибки — это список задач миграции.
  4. Пройдите критические пути игры. Начните новую игру, загрузите сохранение, прогоните основной игровой цикл, откройте главные меню. Ошибки в редакторе — это лёгкая часть; регрессии прячутся в поведении во время выполнения.
  5. Запустите свои тестовые сценарии (те, что подготовили перед обновлением) и сравните с базовым срезом.
  6. Перед коммитом просмотрите diff рабочего дерева в git. Во время миграции редактор переписывает файлы: в project.godot появляются новые значения настроек, файлы .tscn пересохраняются, могут появиться новые файлы .uid. Просмотрите diff, чтобы точно знать, что изменилось, — и закоммитьте всё одним понятно подписанным миграционным коммитом.

Известные критические точки между версиями 4.x

Минорные версии Godot 4 в основном совместимы, но слово «в основном» здесь несёт большую нагрузку. Вот изменения, которые чаще всего кусаются, по официальным заметкам и отчётам сообщества.

4.2 → 4.3: TileMap объявлен устаревшим в пользу TileMapLayer

В Godot 4.3 нода TileMap объявлена устаревшей в пользу TileMapLayer — одна нода на слой вместо слоёв внутри одной ноды. Существующие TileMap продолжают работать, но новый код и новые проекты должны использовать TileMapLayer. В редакторе есть инструмент извлечения: выберите свой TileMap, откройте нижнюю панель TileMap, нажмите на значок с инструментами в правом верхнем углу и выберите «Extract TileMap layers as individual TileMapLayer nodes».

Подводный камень по отчётам сообщества: есть сообщения о том, что после миграции на TileMapLayer биты коллизий физического слоя TileSet сбрасываются к значениям по умолчанию. Это случается не у всех, но проявляется мерзко (объекты перестают сталкиваться — молча). После конвертации явно проверьте коллизии тайлов.

4.3 → 4.4: файлы .uid и дополнения GDScript

  • В Godot 4.4 появились сопутствующие файлы .uid рядом со скриптами и шейдерами. Коммитьте их в систему контроля версий — их удаление может сломать ссылки uid:// везде, где они используются (официальные заметки об обновлении до 4.4 описывают связанные изменения, например превращение путей @export_file в uid://). Они выглядят как мусор — но это не мусор.
  • Типизированные Dictionary и другие дополнения GDScript обратно совместимы — ваш старый код продолжает работать. Но аддоны, которые переходят на новые возможности, перестают работать на старых версиях, так что при перескоке поведение аддонов может измениться.

Общее: тонкие изменения между любыми минорными версиями

Правки рендеринга между минорными версиями могут едва заметно изменить внешний вид игры — освещение, сглаживание, 2D-привязку. В обсуждениях сообщества встречаются и регрессии, привязанные к конкретным сценам, которые не воспроизводятся в свежих проектах: после обновления сцена ведёт себя неправильно, но та же сцена, собранная в чистом проекте, работает нормально. Если что-то ломается необъяснимо, попробуйте такую последовательность изоляции: закройте редактор, удалите папку .godot, откройте проект заново и дайте всему реимпортироваться; если проблема сохраняется, воспроизведите сцену в чистом проекте, чтобы определить, виновато ли накопленное состояние вашего проекта или реальное изменение в движке.

3.x → 4.x — это совсем другой зверь

Всё сказанное выше касается переходов между версиями 4.x. Миграция с Godot 3 на Godot 4 — совершенно иная категория: изменился синтаксис GDScript, многие ноды переименованы, а TileMap, физика и рендеринг переработаны с нуля — и большинству аддонов нужны отдельные версии для 4.x. Для крупных проектов на 3.x стоимость миграции может приблизиться к стоимости переписывания с нуля, и вопрос «стоит ли оно того» решается строго индивидуально для каждого проекта. Эта миграция заслуживает (и имеет) собственную документацию; данная статья не будет притворяться, что покрывает её.

Тестирование после обновления — настоящее узкое место

А теперь честно: главная причина, по которой разработчики избегают обновлений, — не сама миграция, а то, что проверять «ничего не сломалось» вручную дорого. Полный ручной регрессионный прогон для игры среднего размера может съесть целые выходные. А баг во время выполнения, который игроки найдут после релиза, куда хуже любой ошибки в редакторе, потому что это уже проблема репутации, а не пункт в списке дел.

Минимальный ручной smoke-тест

  • Начать новую игру с титульного экрана
  • Загрузить существующее сохранение
  • Поиграть несколько минут в основной игровой цикл
  • Проверить UI на каждом поддерживаемом разрешении и режиме окна

Автоматизируйте сравнение «до/после»

Ручной прогон не масштабируется и не скажет вам, что спрайт сместился на два пикселя. Именно для этого создан Godot QA — бесплатный тест-раннер для Godot с открытым исходным кодом под лицензией MIT. Его рабочий процесс идеально подходит для обновления версий:

  1. Перед обновлением напишите (или запишите) JSON-файлы сценариев, покрывающие критические пути, и снимите базовые скриншоты на старой версии.
  2. После обновления запустите на новой версии в точности те же сценарии плюс попиксельное сравнение с базовыми снимками.
  3. Провалы точно указывают на регрессии за минуты вместо выходных, потраченных на ручное переигрывание.

Сценарий — это просто JSON-список шагов: ввод, ожидания, проверки, скриншоты:

{
  "name": "core_loop_smoke",
  "steps": [
    {"type": "wait", "seconds": 1.0},
    {"type": "input", "action": "ui_accept", "pressed": true},
    {"type": "wait", "seconds": 0.5},
    {"type": "assert", "node_path": "/root/Main/Player",
     "property": "health", "expected": 100, "operator": "eq"},
    {"type": "input", "action": "move_right", "pressed": true},
    {"type": "wait", "seconds": 2.0},
    {"type": "input", "action": "move_right", "pressed": false},
    {"type": "assert", "node_path": "/root/Main/Player",
     "property": "position:x", "expected": 100.0, "operator": "gt"},
    {"type": "screenshot", "name": "after_move"}
  ]
}

Тот же формат сценариев использует инструмент run_test_scenario из Godot MCP Pro, так что ИИ-ассистент, подключённый к вашему редактору, может писать эти сценарии за вас.

Если что-то сломалось

  1. Делайте бинарный поиск по версиям. Если вы перескочили сразу через несколько минорных версий, повторите обновление по одной минорной версии за раз, чтобы найти, где именно всё сломалось. Это сужает поиск с «всего подряд» до одного changelog.
  2. Удалите папку .godot и дайте проекту реимпортироваться. Устаревшие кэши импорта — причина удивительно большой доли странностей после обновления.
  3. Поищите точный текст своей ошибки в GitHub issues движка. Если это настоящая регрессия, её часто уже кто-то зарепортил — иногда вместе с обходным решением.
  4. Проверьте, не виноват ли аддон. Отключите аддоны в настройках проекта и протестируйте снова. Если проблема исчезла — виноват аддон; прежде чем винить движок, проверьте, не вышло ли его обновление.
  5. Признайте, что остаться на старой версии — тоже валидный исход. Если цена исправления превышает выгоду от обновления, откатите ветку, оставайтесь на месте и поставьте напоминание попробовать снова с выходом следующего релиза. Это не провал — это сработавшее управление рисками.

Когда остаться на месте — правильное решение

Некоторым проектам просто не следует обновляться, и это стоит сказать прямо: выпущенные или почти выпущенные игры, C#-проекты, которым нужен веб-экспорт, игры для старого железа и проекты на сильно модифицированных кастомных сборках движка. Во всех этих случаях версия, на которой вы сидите, делает свою работу. Обновление — это инструмент, а не добродетель; цель — законченная игра, а не свежий движок.

Часто задаваемые вопросы

Можно ли откатиться после обновления?

Надёжно — нет. Как только новый редактор пересохранит ваши сцены и ресурсы, они теряют обратную совместимость со старыми редакторами. Единственный безопасный путь назад — восстановление из системы контроля версий, и именно для этого существует ветка для обновления.

Стоит ли перескакивать сразу через несколько версий?

Маленькие шаги безопаснее. Официальные заметки об обновлении написаны для каждой версии отдельно, поэтому у каждого шага есть известный чек-лист — прыжок через несколько версий наваливает их все сразу и мешает понять, какое изменение что сломало.

Минорные версии действительно что-то ломают?

Редко, но да. Большинство проектов переходят между минорными версиями без проблем, но задокументированные сообществом крайние случаи существуют — сброс битов коллизий, регрессии рендеринга в отдельных сценах. Именно поэтому важны базовые тесты до обновления: они превращают «что-то сломалось?» из ощущения в измерение.

Применим ли этот чек-лист к переходу 3.x → 4.x?

Сам чек-лист — да: ветка, сохранение старого бинарника, фиксация базовых срезов, тестирование после. Список критических точек — нет: миграция с 3 на 4 гораздо масштабнее (синтаксис GDScript, переименованные ноды, переработанные системы) и имеет собственную официальную документацию.