Godot 4: Coloque Regras de Sinais no Seu Prompt para o MCP Conectar a Barra de Vida
Antes de pedir ao Godot MCP no Cursor, defina um contrato de sinal health_changed para o HUD conectar sem caminhos get_node profundos—modelos de prompt, exemplos GDScript, anti-padrões e aceitação no Play.
- Godot MCP
- Godot 4
- signals
- HUD
- GDScript
- Cursor
- AI game development
- tutorial
A falha mais comum de “IA quebrou minha cena” no Godot não é um erro de sintaxe—é um script de barra de vida que codifica:
$"/root/Game/Player/HitPoints".hp # ou get_node("../../Player/...")
Reorganize a árvore ou instancie Player como uma cena filha, e esse caminho morre. Godot MCP segue seu prompt fielmente—se você não proibir caminhos fixos, o modelo continuará inventando-os.
Este post faz um trabalho: no Cursor (ou Claude Code), declare um contrato de sinal primeiro, depois deixe o MCP conectar a vida do jogador à barra do HUD. Sem tutorial de instalação, sem construção completa de plataforma.
| Passo | O que você faz |
|---|---|
| 1 | Nomeie o sinal, argumentos, emissor / receptor |
| 2 | Peça ao MCP com restrições para editar scripts e conexões |
| 3 | Aceite no Play; corrija o prompt usando anti-padrões |
Relacionados:
Contexto: Organização de cenas — cenas filhas devem expor sinais / exports, não caminhos profundos.
Por que regras de sinal pertencem ao prompt
| Abordagem | Curto prazo | Após reorganização |
|---|---|---|
get_node("../Player/Health") | Rápido | Frequentemente quebra |
@onready var bar = %HealthBar (nome único) | Ok em uma cena | Ainda frágil entre cenas |
signal health_changed(current, max) + connect | Duas linhas extras | Árvores do HUD e Player podem mudar independentemente |
MCP não tem “memória de arquitetura” duradoura a menos que você repita restrições. Um bloco de contrato copiável é mais barato do que limpar caminhos fixos de cada diff.
Esqueleto mínimo de nós
Você não precisa de uma UI completa. A v1 só precisa de:
Game (Node2D / Node)
├── Player (CharacterBody2D) ← player_health.gd
│ └── ...
└── HUD (CanvasLayer)
└── HealthBar (ProgressBar ou TextureProgressBar) ← hud_health.gd
Nomenclatura:
| Nó | Nome sugerido | Notas |
|---|---|---|
| Raiz do Player | Player | Possui o script de vida |
| Camada HUD | HUD | CanvasLayer |
| Barra | HealthBar | ProgressBar; HP absoluto ou max_value = 1 proporção |
Se o HUD veio do AI Studio, renomeie para IDs estáveis em inglês antes de conectar.
Contrato de sinal (cole no topo de cada prompt)
Trate isso como lei do projeto:
[Contrato de sinal — vida]
1. Apenas o script de vida no Player emite:
signal health_changed(current: float, max_health: float)
Nome no passado / concluído; argumentos sempre (current, max_health).
2. O script da barra do HUD apenas conecta esse sinal e atualiza a ProgressBar; sem get_node para Player a partir do HUD.
3. Proibido: NodePaths profundos entre cenas, Autoload como barramento de vida (não necessário aqui), polling por Player no _process.
4. Prefira conexões de sinal no editor, ou @export Node / NodePath no HUD e depois .connect — nunca codifique "/root/...".
5. Dano e cura apenas mudam valores no Player e emitem; a UI nunca muta HP.
Esse bloco é o ponto deste artigo: contrato antes da implementação.
Passo 1: Teste de fumaça somente leitura
Liste os nomes dos filhos sob a raiz da cena atualmente editada. Não modifique nenhum arquivo ou nó.
Só escreva quando vir Player e HUD (ou seus equivalentes).
Passo 2: Player emite apenas
Anexe após o contrato:
[Contrato de sinal — vida] (cole o bloco completo)
Em res://scripts/player_health.gd (crie se não existir) e anexe ao Player:
- @export var max_health: float = 100.0
- var current: float
- signal health_changed(current: float, max_health: float)
- Em _ready: current = max_health; emita health_changed uma vez
- take_damage(amount), heal(amount); limite 0..max_health; emita após cada mudança
- Não referencie HUD; não use get_node para UI
Salve e reporte os tipos dos argumentos do sinal.
Implementação de referência:
extends Node
class_name PlayerHealth
signal health_changed(current: float, max_health: float)
@export var max_health: float = 100.0
var current: float
func _ready() -> void:
current = max_health
health_changed.emit(current, max_health)
func take_damage(amount: float) -> void:
if amount <= 0.0 or current <= 0.0:
return
current = maxf(0.0, current - amount)
health_changed.emit(current, max_health)
func heal(amount: float) -> void:
if amount <= 0.0 or current <= 0.0:
return
current = minf(max_health, current + amount)
health_changed.emit(current, max_health)
Tecla de dano temporária (apague depois):
Adicione debug_damage.gd temporário no Player: pressionar H chama PlayerHealth.take_damage(10) no mesmo nó (ou pai). Apenas para aceitação da conexão. Não toque no HUD.
Se o script estiver na raiz do Player, mude extends Node para corresponder (ex.: CharacterBody2D), ou faça PlayerHealth um filho Health—escolha um no prompt para o MCP não adivinhar o ponto de montagem.
Passo 3: HUD assina via referência exportada
[Contrato de sinal — vida] (cole o bloco completo)
Crie res://scripts/hud_health.gd no HUD ou HealthBar:
- @export var player_health: PlayerHealth
- @onready var bar: ProgressBar = $HealthBar # apenas se o script estiver no HUD; caminho permanece dentro da subárvore do HUD
- _ready: assert player_health != null; player_health.health_changed.connect(_on_health_changed)
- _on_health_changed(current, max_health): bar.max_value = max_health; bar.value = current
(ou proporção: max_value = 1; value = current / max_health)
- Proibido: get_node para Player; proibido: caminhos absolutos /root
Depois atribua o player_health exportado ao PlayerHealth do Player (ou filho Health) no editor. Salve a cena.
Referência:
extends CanvasLayer
@export var player_health: PlayerHealth
@onready var bar: ProgressBar = $HealthBar
func _ready() -> void:
assert(player_health != null, "Atribua PlayerHealth no inspetor")
player_health.health_changed.connect(_on_health_changed)
func _on_health_changed(current: float, max_health: float) -> void:
bar.max_value = max_health
bar.value = current
$HealthBar dentro do HUD é ok—mesma subárvore. Proibido é um caminho profundo através para Player.
Conexão via editor “Nó → Conectar um Sinal” via MCP também é ok:
Conecte via editor: Player (PlayerHealth) health_changed → script do HUD _on_health_changed. Não escreva strings NodePath manualmente.
Passo 4: Checklist de aceitação no Play
- Ao entrar: barra cheia (ou proporção correta)
- Pressione H:
bar.valuecai - Até 0: barra vazia; UI não deve escrever
current - Após
heal: barra sobe - Reorganize
Playersob ex.:Entitiese jogue novamente: a barra ainda atualiza se a referência exportada permanecer—essa é a vitória vs caminhos fixos
Se quebrar após reorganizar, corrija o export vazio—não peça ao MCP por “outro get_node”.
Prompt de aceitação:
Diagnostique a partir dos erros do Play: se o sinal nunca dispara, verifique a conexão; se player_health for nulo, apenas corrija o export. Não "corrija" com caminhos get_node absolutos. Diagnostique primeiro; aguarde meu OK antes de editar.
Anti-padrões: mude o prompt, não faça merge
| Anti-padrão | Por que prejudica | Adicione ao prompt |
|---|---|---|
get_node("/root/Game/Player") | Mudança de caminho raiz | ”Sem /root ou NodePath absoluto” |
get_parent().get_node("Player") | Acoplamento entre irmãos | ”HUD não deve assumir layout de irmão do Player” |
Autoload GlobalHealth.hp | Gaveta global de lixo | ”Sem novo Autoload para esta tarefa” |
HUD _process procurando Player | Lento e frágil | ”Sem polling; apenas sinais” |
Sinal nomeado update / set_hp | Vago, propenso a colisão | ”Sinal deve ser health_changed” |
Escrever manualmente ainda vence para movimento de alto desempenho e matemática de combate complexa; conexão de barra de vida é boilerplate onde um prompt MCP contratado é geralmente mais barato. Veja Godot MCP vs script manual.
Esqueleto reutilizável “contrato + tarefa”
Troque nomes para barras de mana / chefe:
[Contrato de sinal]
- Emissor: <nó/script>
- signal <nome>(...)
- Receptor: <método do HUD>
- Proibido: NodePath absoluto, barramento Autoload, polling _process
[Tarefa]
1. …
2. …
3. Salve a cena; liste novos sinais e como eles conectam (editor / .connect)
Resumo
- Caminhos fixos são um buraco no prompt, não “MCP não sabe Godot”
- Cole
health_changed(current, max_health)antes de pedir edições - Player apenas emite; HUD apenas conecta e atualiza
ProgressBar - Links entre objetos usam
@exportou conexão de sinal no editor—não/root/... - Aceite reorganizando Player e observando a barra—não por “script gerado OK”
Agora você tem um conjunto de regras de prompt Godot MCP copiável; inventário, registro de missões e contadores de abates podem reutilizar o mesmo padrão.
Continuar lendo
Mais guias que podem interessar
Solução de Problemas de Conexão do Cocos MCP: Cursor Não Mostra cocos-creator
Correções baseadas em sintomas para o MCP do VberAI Cocos Creator 2.x / 3.x: extensão ausente, falha de ativação, servidor não rodando, conflitos de porta, MCP do Cursor não escrito ou precisa recarregar—mais uma lista de verificação e verificação de localhost.
- cocos
- cocos-creator
- mcp
- cursor
Como Construímos um Servidor MCP em Tempo Real para Godot
Dentro da arquitetura Godot MCP da VberAI: como um servidor MCP em tempo real conecta o editor Godot a clientes de IA sem congelar a árvore de cenas.
- vberai
- godot
- mcp
- architecture
UI de Jogos com IA: Não Edite o YAML do Prefab—Use o Canvas para Exportar Unity / Godot / Cocos
Por que LLMs não devem ler nem escrever YAML de Prefab ao montar UI de jogos com IA. Fluxo de camada intermediária, exportação determinística e o caminho do canvas do VberAI Studio de Figma / PSD para Prefabs Unity, Godot e Cocos.
- game-ui-design
- game-dev-ai
- ui-to-engine
- figma-to-unity