Migrar Projeto do Godot 3 para o Godot 4: Guia Prático de Conversão

Guia prático para migrar Godot 3 para 4: conversor automático, renomeações de nodes, GDScript 2.0 e os breaking changes que o conversor não resolve.
Migrar Projeto do Godot 3 para o Godot 4: Guia Prático de Conversão
Migrar Godot 3 para 4 não é apertar um botão e torcer. O Godot 4 mudou renderer, reorganizou a árvore de nodes, renomeou centenas de classes e reescreveu o GDScript. O conversor automático que vem na engine resolve a parte chata (as renomeações em massa), mas deixa pra você tudo que envolve lógica: sinais, corrotinas, física de personagem, shaders.
A boa notícia: o processo tem um caminho conhecido. Esse guia segue a ordem que funciona na prática: decidir se vale migrar, preparar o projeto, rodar o conversor, e então atacar os breaking changes que sobram, um por um, com o antes e depois em código.
Vale a pena migrar?
Resposta honesta: depende de onde o projeto está.
Migre se: o projeto está no começo ou no meio do desenvolvimento, você vai dar suporte a ele por anos, ou precisa de algo que só existe no 4 (o renderer Forward+ com Vulkan, o GDScript 2.0 com tipagem melhor, a física Jolt no 3D).
Não migre se: o jogo está a semanas do lançamento. Migração de engine na reta final é receita pra atrasar tudo e introduzir bug em sistema que já estava estável. Termine no 3.x, lance, e migre na sequência (ou no próximo projeto).
Pondere se: o projeto depende pesado de plugins de terceiros. Addon do Godot 3 não roda no 4, e nem todo autor portou o dele. Antes de qualquer coisa, abra a pasta addons/ e confira plugin por plugin se existe versão pro Godot 4. Se um plugin central do seu jogo não tem porte, esse é o seu custo real de migração, não o resto.
Sobre o tamanho do trabalho: projeto pequeno e organizado migra em horas. Projeto grande, com muito script acoplado e shader customizado, leva dias. A variável que mais pesa é quanto código GDScript você tem, porque é nele que o conversor menos ajuda.
Preparação: antes de rodar qualquer conversor
Três passos antes de encostar no Godot 4:
- Atualize pro último 3.x. O conversor foi pensado pra projetos vindos da série 3.x recente. Se o projeto está no 3.2 ou 3.3, suba primeiro pro 3.5/3.6 dentro da própria série 3, resolva o que quebrar aí (vai ser pouco), e só então parta pro 4.
- Commit limpo no Git. O conversor reescreve arquivos no lugar, sem desfazer. Você quer um
git statuslimpo antes, pra poder comparar cada mudança no diff e voltar atrás se precisar. Se o projeto não está em versionamento, esse é o momento de corrigir isso (ou no mínimo duplicar a pasta inteira). - Liste seus pontos críticos. Anote onde o projeto usa
yield,setget, Tween,File/Directorye shaders customizados. São exatamente os pontos onde o conversor vai te deixar na mão, e ter a lista pronta transforma a migração de caça ao tesouro em checklist.
Como migrar Godot 3 para 4 com o conversor automático
O Godot 4 traz um conversor de projetos embutido. Ele varre cenas (.tscn), recursos (.tres), scripts (.gd) e configurações, aplicando as renomeações de classes, métodos, propriedades e sinais da versão nova.
Dois jeitos de rodar:
Pelo Project Manager: abra o Godot 4, importe o project.godot do projeto antigo, e o editor oferece a conversão completa antes de abrir. É o caminho mais simples.
Pela linha de comando, que eu prefiro porque permite validar antes de alterar. Na pasta do projeto, com o executável do Godot 4:
# Primeiro: simula a conversão e lista o que seria alterado, sem tocar em nada
godot --validate-conversion-3to4
# Depois de revisar a saída: converte de verdade
godot --convert-3to4
Leia a saída do --validate-conversion-3to4 com atenção. Ela mostra arquivo por arquivo o que vai mudar, e é onde você descobre surpresas antes delas acontecerem. Detalhe que pega gente: por segurança, o conversor pula arquivos muito grandes e linhas muito longas por padrão. Se você tem um .tscn gigante ou um script com linhas quilométricas, confira no log se algo foi pulado e ajuste os limites passando os argumentos max_file_kb e max_line_size na chamada.
O que o conversor cobre bem
A força dele é renomeação em massa. Os casos mais comuns que ele resolve sozinho:
| Godot 3 | Godot 4 |
|---|---|
Spatial | Node3D |
KinematicBody2D | CharacterBody2D |
KinematicBody | CharacterBody3D |
Area | Area3D |
RayCast | RayCast3D |
Position2D | Marker2D |
instance() | instantiate() |
OS.get_ticks_msec() | Time.get_ticks_msec() |
deg2rad() / rad2deg() | deg_to_rad() / rad_to_deg() |
rand_range() | randf_range() |
stepify() | snapped() |
export var | @export var |
onready var | @onready var |
O padrão geral das classes 3D: tudo que não tinha sufixo ganhou 3D (porque Spatial virou Node3D e a família inteira seguiu). Já as keywords do GDScript viraram annotations com @: export, onready, tool viraram @export, @onready, @tool.
Depois de rodar, abra o diff no Git e passe o olho. O conversor é conservador e às vezes deixa um comentário ou um trecho marcado em vez de converter. Cada um desses merece revisão manual.
Os breaking changes que sobram pra você
Aqui começa o trabalho de verdade. O conversor renomeia, mas não reescreve lógica. Esses são os pontos que você vai corrigir na mão, em ordem de frequência.
Sinais: conexão e await
A sintaxe de sinal mudou por completo. No Godot 3, tudo era string. No 4, sinal é objeto de primeira classe e a conexão recebe um Callable:
# Godot 3
button.connect("pressed", self, "_on_button_pressed")
emit_signal("game_over")
# Godot 4
button.pressed.connect(_on_button_pressed)
game_over.emit()
A versão nova é melhor em tudo: o editor autocompleta, e erro de digitação no nome do sinal vira erro de parse em vez de bug silencioso em runtime.
yield virou await
O yield não existe mais. Esperar um sinal agora é await direto no sinal:
# Godot 3
yield(get_tree().create_timer(1.0), "timeout")
yield(tween, "finished")
# Godot 4
await get_tree().create_timer(1.0).timeout
await tween.finished
O conversor tenta ajudar nos casos simples, mas qualquer uso de yield como corrotina manual (retomar função com resume, por exemplo) precisa ser repensado, porque o modelo de corrotina mudou. Procure todos os yield do projeto antes de rodar o conversor e marque os que fazem algo além de "esperar sinal".
move_and_slide e a velocity embutida
Quem tem jogo de plataforma sente essa primeiro. No Godot 3, você mantinha sua própria variável de velocidade e passava pro move_and_slide(), que devolvia a velocidade ajustada. No 4, velocity é propriedade do próprio CharacterBody e o método não recebe nem retorna nada:
# Godot 3 (KinematicBody2D)
var velocity = Vector2.ZERO
func _physics_process(delta):
velocity.y += gravity * delta
velocity = move_and_slide(velocity, Vector2.UP)
# Godot 4 (CharacterBody2D)
func _physics_process(delta):
velocity.y += gravity * delta
move_and_slide()
A direção "pra cima" que era o segundo argumento virou a propriedade up_direction, que no 2D já vem com o padrão certo. Se o seu script declarava var velocity, delete a declaração: ela agora conflita com a propriedade nativa.
setget virou set/get inline
A keyword setget sumiu. Setter e getter agora moram junto da declaração da variável:
# Godot 3
var health = 100 setget set_health
func set_health(value):
health = clamp(value, 0, 100)
# Godot 4
var health = 100:
set(value):
health = clamp(value, 0, 100)
Diferença de comportamento que importa: no Godot 3, atribuição dentro do próprio script não passava pelo setter (só acesso externo passava). No 4, o setter roda sempre, inclusive em atribuição interna. Se algum setter seu tem efeito colateral pesado, revise quem atribui nessa variável.
Tween virou objeto, não node
O node Tween que você adicionava na cena não existe mais. Tween agora é criado por código, na hora de usar:
# Godot 3 (node Tween na cena)
$Tween.interpolate_property(self, "position", position, target, 0.5,
Tween.TRANS_QUAD, Tween.EASE_OUT)
$Tween.start()
# Godot 4
var tween = create_tween()
tween.tween_property(self, "position", target, 0.5).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
Além de mais curto, o tween novo se libera sozinho quando termina. O conversor não faz essa migração: ele não tem como saber a intenção da animação. É reescrita manual, mas das gostosas, porque o código sempre encolhe.
File e Directory viraram FileAccess e DirAccess
Acesso a arquivo mudou de "instancia e abre" pra método estático que já devolve o handle aberto:
# Godot 3
var file = File.new()
file.open("user://save.dat", File.READ)
var data = file.get_as_text()
file.close()
# Godot 4
var file = FileAccess.open("user://save.dat", FileAccess.READ)
var data = file.get_as_text()
# fecha sozinho quando a referência sai de escopo
Mesmo padrão pro Directory, que virou DirAccess. Todo sistema de save/load passa por aqui, então teste salvar e carregar logo depois de migrar essa parte.
Shaders e renderer
O conversor não toca em shader, e a linguagem mudou em pontos importantes: hint_albedo virou source_color, vários nomes de matriz e de funções built-in mudaram. Shader simples se corrige rápido lendo o erro que o editor cospe; shader complexo merece uma sessão dedicada.
No renderer, a escolha GLES2/GLES3 deixou de existir. O Godot 4 oferece Forward+ (desktop, o mais completo), Mobile (otimizado pra celular) e Compatibility (OpenGL, roda em hardware antigo e web). A conversão não escolhe por você: pense no seu alvo. Jogo 2D pra web e mobile costuma ficar bem no Compatibility; 3D de desktop pede Forward+. E aceite desde já que luz e pós-processamento vão ficar diferentes do que estavam no 3: reserve um tempo pra reajustar iluminação e environment olhando o jogo, não os números antigos.
Checklist pós-conversão
Depois do conversor e das correções manuais, rode essa sequência antes de considerar a migração fechada:
- Abra cena por cena no editor. Cena que quebrou aparece com erro de dependência na hora. Resolva antes de rodar o jogo.
- Procure os avisos do conversor. Busque no projeto por comentários e trechos que ele marcou em vez de converter.
- Rode o jogo e jogue de verdade. Movimento, colisão, UI, save/load, áudio. Os bugs de migração adoram se esconder em fluxo que você não testa há meses.
- Revise os exports. As configurações de export mudaram entre as versões; reconfigure os presets de cada plataforma e gere uma build de teste em todas.
- Confira a iluminação. Principalmente em 3D, compare lado a lado com a versão antiga e reajuste o que mudou de cara.
Fechando
Migrar Godot 3 para 4 é um projeto curto, não um clique. O caminho que funciona: decidir com calma se é a hora, garantir backup e a lista de pontos críticos, deixar o conversor fazer a renomeação em massa, e então resolver na mão sinais, await, move_and_slide, setget, Tween, arquivos e shaders, testando a cada bloco.
O esforço se paga. O GDScript 2.0 é mais rápido e mais seguro de escrever, o editor é melhor, e é no 4 que a engine evolui daqui pra frente. Se o seu projeto tem futuro, ele merece estar onde o futuro da engine está.


