Godot 4: Metti le regole dei segnali nel prompt così MCP collega la barra della salute
Prima di chiedere a Godot MCP in Cursor, definisci un contratto di segnale health_changed così l'HUD si connette senza percorsi get_node profondi—modelli di prompt, esempi GDScript, anti-pattern e accettazione in Play.
- Godot MCP
- Godot 4
- signals
- HUD
- GDScript
- Cursor
- AI game development
- tutorial
Introduzione
L’errore più comune “l’IA ha rotto la mia scena” in Godot non è un errore di sintassi—è uno script della barra della salute che hard-coda:
$"/root/Game/Player/HitPoints".hp # o get_node("../../Player/...")
Riparenti l’albero o istanzia Player come scena figlia, e quel percorso muore. Godot MCP segue fedelmente il tuo prompt—se non proibisci i percorsi hard-coded, il modello continuerà a inventarli.
Questo post fa un solo lavoro: in Cursor (o Claude Code), dichiara prima un contratto di segnale, poi lascia che MCP colleghi la salute del giocatore alla barra HUD. Nessun tutorial di installazione, nessuna costruzione completa di platformer.
| Passo | Cosa fai |
|---|---|
| 1 | Nomina il segnale, gli argomenti, emettitore / ricevitore |
| 2 | Prompt a MCP con vincoli per modificare script e connessioni |
| 3 | Accetta in Play; correggi il prompt usando anti-pattern |
Correlati:
Contesto: Organizzazione delle scene — le scene figlie dovrebbero esporre segnali / export, non percorsi profondi.
Perché le regole dei segnali appartengono al prompt
| Approccio | Breve termine | Dopo la riorganizzazione |
|---|---|---|
get_node("../Player/Health") | Veloce | Spesso si rompe |
@onready var bar = %HealthBar (nome univoco) | Ok in una scena | Ancora fragile tra scene |
signal health_changed(current, max) + connect | Due righe in più | Gli alberi HUD e Player possono cambiare indipendentemente |
MCP non ha una “memoria architetturale” duratura a meno che tu non ripeta i vincoli. Un blocco di contratto incollabile è più economico che ripulire i percorsi hard-coded da ogni diff.
Scheletro minimo dei nodi
Non serve una UI completa. v1 ha bisogno solo di:
Game (Node2D / Node)
├── Player (CharacterBody2D) ← player_health.gd
│ └── ...
└── HUD (CanvasLayer)
└── HealthBar (ProgressBar o TextureProgressBar) ← hud_health.gd
Nomi:
| Nodo | Nome suggerito | Note |
|---|---|---|
| Radice Player | Player | Possiede lo script della salute |
| Layer HUD | HUD | CanvasLayer |
| Barra | HealthBar | ProgressBar; HP assoluti o max_value = 1 rapporto |
Se l’HUD proviene da AI Studio, rinomina con ID inglesi stabili prima del collegamento.
Contratto di segnale (incolla all’inizio di ogni prompt)
Trattalo come legge di progetto:
[Contratto di segnale — salute]
1. Solo lo script della salute su Player emette:
signal health_changed(current: float, max_health: float)
Nome al passato / completato; argomenti sempre (current, max_health).
2. Lo script della barra HUD si connette solo a quel segnale e aggiorna ProgressBar; nessun get_node verso Player dall'HUD.
3. Vietati: NodePath profondi tra scene, Autoload come bus della salute (non necessario qui), polling per Player in _process.
4. Preferisci connessioni di segnale dall'editor, o @export Node / NodePath sull'HUD e poi .connect — mai hard-codare "/root/...".
5. Danno e cura cambiano solo i valori su Player ed emettono; la UI non muta mai gli HP.
Quel blocco è il punto di questo articolo: contratto prima dell’implementazione.
Passo 1: Test di sola lettura
Elenca i nomi dei figli sotto la radice della scena attualmente modificata. Non modificare file o nodi.
Scrivi solo quando vedi Player e HUD (o i tuoi equivalenti).
Passo 2: Player emette solo
Aggiungi dopo il contratto:
[Contratto di segnale — salute] (incolla il blocco completo)
In res://scripts/player_health.gd (crea se manca) e allegalo a Player:
- @export var max_health: float = 100.0
- var current: float
- signal health_changed(current: float, max_health: float)
- In _ready: current = max_health; emetti health_changed una volta
- take_damage(amount), heal(amount); clamp 0..max_health; emetti dopo ogni modifica
- Non fare riferimento all'HUD; non usare get_node verso la UI
Salva e riporta i tipi degli argomenti del segnale.
Implementazione di riferimento:
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)
Tasto danno temporaneo (elimina dopo):
Aggiungi debug_damage.gd temporaneo su Player: premendo H chiama PlayerHealth.take_damage(10) sullo stesso nodo (o genitore). Solo per accettazione del collegamento. Non toccare l'HUD.
Se lo script sta sulla radice Player, cambia extends Node per corrispondere (es. CharacterBody2D), oppure rendi PlayerHealth un figlio Health—scegli uno nel prompt così MCP non indovina il punto di montaggio.
Passo 3: L’HUD si sottoscrive tramite riferimento esportato
[Contratto di segnale — salute] (incolla il blocco completo)
Crea res://scripts/hud_health.gd su HUD o HealthBar:
- @export var player_health: PlayerHealth
- @onready var bar: ProgressBar = $HealthBar # solo se lo script è su HUD; il percorso resta nel sottoalbero 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
(o rapporto: max_value = 1; value = current / max_health)
- Vietato: get_node verso Player; vietati percorsi assoluti /root
Poi assegna l'export player_health al PlayerHealth di Player (o figlio Health) nell'editor. Salva la scena.
Riferimento:
extends CanvasLayer
@export var player_health: PlayerHealth
@onready var bar: ProgressBar = $HealthBar
func _ready() -> void:
assert(player_health != null, "Assegna PlayerHealth nell'ispettore")
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 l’HUD è ok—stesso sottoalbero. Vietato è un percorso profondo attraverso verso Player.
Anche l’editor “Node → Connect a Signal” tramite MCP è ok:
Connetti tramite l'editor: Player (PlayerHealth) health_changed → script HUD _on_health_changed. Non scrivere a mano stringhe NodePath.
Passo 4: Checklist di accettazione in Play
- All’ingresso: barra piena (o rapporto corretto)
- Premi H:
bar.valuescende - A 0: barra vuota; la UI non deve scrivere
current - Dopo
heal: la barra sale - Riparenta
Playersotto es.Entitiese gioca di nuovo: la barra si aggiorna ancora se il riferimento export rimane—questo è il vantaggio rispetto ai percorsi hard-coded
Se si rompe dopo il riparenting, correggi l’export vuoto—non chiedere a MCP “un altro get_node”.
Prompt di accettazione:
Diagnostica dagli errori di Play: se il segnale non scatta mai, controlla la connessione; se player_health è null, correggi solo l'export. Non "correggere" con percorsi get_node assoluti. Diagnostica prima; attendi il mio OK prima di modificare.
Anti-pattern: cambia il prompt, non unire
| Anti-pattern | Perché fa male | Aggiungi al prompt |
|---|---|---|
get_node("/root/Game/Player") | Instabilità del percorso radice | ”Niente /root o NodePath assoluti” |
get_parent().get_node("Player") | Accoppiamento tra fratelli | ”L’HUD non deve assumere il layout dei fratelli di Player” |
Autoload GlobalHealth.hp | Cassetto globale disordinato | ”Nessun nuovo Autoload per questo compito” |
HUD _process che cerca Player | Lento e fragile | ”Niente polling; solo segnali” |
Segnale chiamato update / set_hp | Vago, soggetto a collisioni | ”Il segnale deve chiamarsi health_changed” |
Scrivere a mano vince ancora per movimento hot-path e matematica di combattimento complessa; il collegamento della barra della salute è boilerplate dove un prompt MCP contrattuale è di solito più economico. Vedi Godot MCP vs scripting manuale.
Scheletro riutilizzabile “contratto + compito”
Scambia i nomi per barre del mana / boss:
[Contratto di segnale]
- Emettitore: <nodo/script>
- signal <nome>(...)
- Ricevitore: <metodo HUD>
- Vietati: NodePath assoluti, bus Autoload, polling _process
[Compito]
1. …
2. …
3. Salva la scena; elenca i nuovi segnali e come si connettono (editor / .connect)
Riepilogo
- I percorsi hard-coded sono un buco nel prompt, non “MCP non sa Godot”
- Incolla
health_changed(current, max_health)prima di chiedere modifiche - Player emette solo; HUD si connette solo e aggiorna
ProgressBar - I collegamenti tra oggetti usano
@exporto connessione segnale dall’editor—non/root/... - Accetta riparentando Player e guardando la barra—non con “script generato OK”
Ora hai un set di regole di prompt Godot MCP incollabile; inventario, registro missioni e contatori di uccisioni possono riutilizzare lo stesso schema.
Continua a leggere
Altre guide che potrebbero interessarti
VberAI End-to-End: AI Studio + Engine MCP per un Mini-Gioco Giocabile
Genera o importa UI in AI Studio, poi guida logica e debug tramite Cursor con Godot, Unity o Cocos MCP. Include una registrazione chibi match-3: dall'export di Studio a una demo giocabile senza codice scritto a mano.
- VberAI
- AI Studio
- Unity MCP
- Godot MCP
Produttività AI per lo Sviluppo di Giochi nel 2026: Combinazioni di Codifica che Funzionano Davvero
Produttività AI pratica per lo sviluppo di giochi: quali combinazioni di Cursor, Claude Code e Copilot funzionano; dove si inseriscono MCP per motori e AI Studio; flussi di lavoro per team Unity, Godot e Cocos.
- game-dev-ai
- ai-coding-combo
- cursor
- claude-code
Cos'è VberAI? Plugin MCP, AI Studio e AI Super Matting
Dove si collocano Engine MCP (Unity / Godot / Cocos), AI Studio (design-to-engine UI) e AI Super Matting in una pipeline di produzione di giochi.
- vberai
- mcp
- ai-studio
- ai-super-matting