Fouten zoeken
Je hebt net een script van nul opgebouwd. Grote kans dat er onderweg iets misging: een regel die niet insprong, een naam met een hoofdletter te veel, of een spel dat startte maar niets deed.
Dat hoort erbij. Wat je nu leert is niet hoe je fouten voorkomt, maar hoe je ze zelf terugvindt — want vanaf hier ga je dingen bouwen waarvan het antwoord niet in deze cursus staat.
Geschreven voor Godot 4.7.x — zie Godot-versies voor compatibiliteit.
Drie soorten fouten
Ze zien er anders uit en vragen een andere eerste stap. Bepaal daarom altijd eerst welke je voor je hebt.
| Wat je ziet | Wat het is | Waar je begint |
|---|---|---|
| Rode tekst in Uitvoer, spel start niet | Je code klopt niet als taal | De foutmelding lezen |
| Spel draait, maar er gebeurt niets | Je code draait niet, of doet niets zichtbaars | print() op drie plekken |
| Spel doet iets, maar iets anders dan je wilde | Je code klopt, je denkwerk niet | Halveren |
De derde is de lastigste, want er is niets kapot. Alleen jij weet dat het niet klopt.
Een foutmelding lezen
Een melding in Uitvoer ziet er zo uit:
res://scripts/speler.gd:15 - Invalid call. Nonexistent function 'plya' in base 'AnimatedSprite2D'.
Lees hem in drie stukken:
res://scripts/speler.gd— in welk bestand het misgaat.:15— op welke regel. Dubbelklik op de melding en Godot springt er meteen naartoe.- De rest — wat er mis is. Hier: de functie
plyabestaat niet. Dat is een typefout voorplay.
De laatste zin is vaak Engels en klinkt technischer dan hij is. Zoek de woorden die je herkent: een naam die je zelf hebt getypt, of een node-type uit je scène.
Krijg je meerdere meldingen tegelijk? Los alleen de bovenste op en start opnieuw. De rest is vaak gevolgschade en verdwijnt vanzelf.
Drie meldingen die je zult tegenkomen
Deze drie komen tijdens het spelen, niet bij het starten. Je spel draait dus al even en klapt er dan uit. Ze zeggen alle drie iets anders over waar je moet kijken.
Attempt to call function 'x' on a null instance
Je vraagt iets aan een node die er niet is. null betekent leeg: de variabele bestaat, maar er zit geen node in.
Invalid call. Nonexistent function 'play' in base 'Nil'.
Attempt to call function 'play' on a null instance.
Bijna altijd staat er een $Naam in je regel die niet klopt met de Scene Tree. Vergelijk letter voor letter: $AnimatedSprite2D vindt niets als je node $Sprite heet. Twijfel je over de schrijfwijze, sleep de node dan vanuit de Scene Tree je script in met Ctrl ingedrukt — Godot typt het pad dan zelf.
Invalid access to property or key 'x' on a base object of type 'y'
De node bestaat wél, maar die eigenschap heeft hij niet.
Invalid access to property or key 'text' on a base object of type 'Node2D'.
Lees het achterste stuk eerst: type 'Node2D'. Dat is wat Godot denkt dat je te pakken hebt. Een Node2D heeft geen text — een Label wel. Meestal wijs je dus naar de verkeerde node, of ligt de eigenschap één laag dieper: niet op je CanvasLayer maar op het Label daaronder.
Helemaal geen melding
Het derde geval is het vervelendst: je klikt, je springt, je raakt het muntje — en er gebeurt niets. Godot zegt niets, want er is niets kapot. Er is alleen nooit iets aangeroepen.
Bij een signal is dat bijna altijd de oorzaak: de functie staat in je script, maar het signal is niet verbonden. Controleer het zo:
- Selecteer de node, open het Node-paneel rechtsboven en kies Signals.
- Onder een verbonden signal staat de naam van de functie ingesprongen. Staat daar niets, dan is het nooit gekoppeld.
- Zet ter controle
print("hier")als eerste regel in de functie. Blijft Uitvoer leeg terwijl je het muntje raakt, dan weet je het zeker.
Print op drie plekken
Draait je spel zonder foutmelding, maar gebeurt er niets? Dan weet je nog niets — en dat is precies het probleem. print() maakt zichtbaar wat je code doet.
Werk van groot naar klein, in deze volgorde:
func _physics_process(delta: float) -> void:
print("de functie draait")
if not is_on_floor():
print("ik val")
velocity += get_gravity() * delta
print(velocity)
move_and_slide()
- Draait deze code überhaupt? Zet een
print("de functie draait")bovenaan. Zie je niets, dan ligt het niet aan de regels eronder maar aan het script zelf: hangt het wel aan de goede node? - Komt hij in dit blok? Zet een
print()binnen deif. Zie je die niet, dan is je voorwaarde nooit waar. - Wat zit er in? Print de waarde zelf, bijvoorbeeld
print(velocity). Nu zie je of het getal is wat je verwachtte.
Haal je prints daarna weg. Een print in _physics_process levert zestig regels per seconde op, en dan zie je de echte melding niet meer.
Halveer je probleem
Weet je niet welke regel de boosdoener is, zet dan de helft uit met een # ervoor en kijk of het probleem blijft.
# if Input.is_action_just_pressed("ui_accept") and is_on_floor():
# velocity.y = JUMP_VELOCITY
- Blijft de fout? Dan zit hij in het deel dat je hebt laten staan.
- Is de fout weg? Dan zit hij in wat je zojuist hebt uitgezet.
Herhaal dit met de helft die overblijft. Na een paar keer heb je nog twee of drie regels over, en daar zit hij.
Dit werkt ook buiten je code: zet een node tijdelijk op onzichtbaar, of haal een tegel weg. De vraag is steeds dezelfde — verandert het probleem als ik dit wegneem?
Vergelijk met iets dat wél werkt
In Godot zit een fout vaak niet in je code maar in de editor: een signal dat niet verbonden is, een Shape die leeg is, een node die net anders heet.
Heb je twee dingen die op elkaar lijken en werkt er één? Zet ze dan naast elkaar en schrijf de verschillen op. Klik beide nodes aan en vergelijk de Inspector regel voor regel. Meestal vind je hem binnen een minuut, en meestal is het iets kleins dat je nooit had bedacht.
De vier vragen
Als je echt vastzit, beantwoord deze vier op papier of hardop. Ze dwingen je van "het werkt niet" naar iets dat je kunt onderzoeken.
- Wat verwacht ik precies? Niet "hij moet springen", maar "als ik spatie druk moet
velocity.yop-400staan". - Wat gebeurt er precies? Niet "niets", maar "de print binnen de
ifverschijnt nooit". - Waar lopen die twee voor het eerst uit elkaar? Dat is de plek waar je moet zoeken.
- Wat is mijn eerstvolgende test? Eén concrete handeling, waarvan je van tevoren weet wat het betekent als hij lukt of mislukt.
Kom je er met een klasgenoot of docent niet uit, dan zijn dit ook precies de vier dingen die je moet kunnen vertellen.
Opdracht 5.8.a: het spel start niet
Dit script hoort te werken, maar Godot weigert het. Wat is er mis?
extends CharacterBody2D
const SPEED = 300.0
func _physics_process(delta: float) -> void
velocity.x = SPEED
move_and_slide()
Klik hier voor een tip.
Godot noemt in de melding een regelnummer. Kijk niet alleen naar díe regel, maar ook naar het einde van de regel erboven.
Klik hier voor de oplossing.
De dubbele punt aan het eind van de func-regel ontbreekt:
func _physics_process(delta: float) -> void:
Elke regel die een blok opent — func, if, else, for — eindigt op een dubbele punt.
Opdracht 5.8.b: het spel draait, maar er gebeurt niets
Geen foutmelding, en toch beweegt het karakter niet.
extends CharacterBody2D
const SPEED = 300.0
func _physics_process(delta: float) -> void:
var direction := Input.get_axis("ui_left", "ui_right")
if direction:
velocity.x = direction * SPEED
Klik hier voor een tip.
Gebruik de methode uit "Print op drie plekken". Zet print(velocity) als laatste regel. Als velocity wél verandert maar je karakter niet beweegt, wie moet die snelheid dan nog uitvoeren?
Klik hier voor de oplossing.
move_and_slide() ontbreekt. De snelheid wordt netjes uitgerekend, maar niemand verplaatst het karakter. Voeg toe als laatste regel binnen de functie:
move_and_slide()
Dit is een goed voorbeeld van de tweede soort fout: er is niets kapot, er ontbreekt iets.
Opdracht 5.8.c: het spel doet iets anders dan bedoeld
Dit karakter zou moeten springen bij een druk op de spatiebalk, maar hij blijft aan het plafond plakken zolang je de toets vasthoudt.
if Input.is_action_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
Klik hier voor een tip.
Er is geen foutmelding en er ontbreekt niets. Vraag jezelf af hoe vaak deze if waar is terwijl je de spatie vasthoudt.
Klik hier voor de oplossing.
is_action_pressed is waar zolang je de toets vasthoudt, dus elke frame krijgt je karakter opnieuw de volle sprongkracht. Gebruik is_action_just_pressed, dat alleen waar is op het frame dat je indrukt:
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
Zie Deel 7 — Springen voor het volledige verhaal.
Waar staan de veelgemaakte fouten?
Elke les in deze cursus eindigt met een blok Er gaat iets mis waarin de fouten staan die bij dat onderwerp horen. Zoek daar eerst, voordat je zelf gaat graven.
| Waar het misgaat | Kijk hier |
|---|---|
| Installatie en projectmap | Installatie, Je projectmap terugvinden |
| Editor, scènes en bestanden | De Godot-interface, Bestanden downloaden |
| Level en tegels | Level tekenen, Collision op je tegels |
| Beweging en springen | Deel 2 — Vallen, Deel 4 — Je eerste if, Deel 5 — Lopen, Deel 7 — Springen |
| Camera | Camera die de speler volgt |
| Animaties | Animaties maken, Animaties in code |
| Signals en score | Signals & een muntje, Score op het scherm |
| Levels, menu en spawnen | Een tweede level, Een startmenu, Spawnen, Timer |
Losse code-voorbeelden staan in de GDScript-tips, en alle node-instellingen in de Nodes cheatsheet.
← Deel 7 — Springen · Volgende: Camera die de speler volgt →