Learn GDScript in 30 Minutes: The Only Tutorial You Need

A fast, practical guide to GDScript for complete beginners. No fluff, just the essentials to start making games in Godot immediately. Includes real examples.

GDScript code editor with colorful syntax highlighting

Forget everything you've heard about needing to learn programming for months before making games. GDScript is designed to get you making games TODAY. This guide covers everything you need to start—no filler, no theory for theory's sake. Just practical knowledge you'll use immediately.

Part 1: The Absolute Basics (5 minutes)

Variables: Storing Stuff

Variables are boxes that hold values. That's it. Here's how you make them:

gdscript
# Basic variables
var health = 100
var player_name = "Hero"
var speed = 5.5
var is_alive = true

# With type hints (recommended)
var health: int = 100
var player_name: String = "Hero"
var speed: float = 5.5
var is_alive: bool = true

The colon syntax (: int) is optional but helpful—it tells Godot what type of value to expect, which catches errors early.

Constants: Values That Never Change

gdscript
# Constants use UPPER_CASE by convention
const MAX_HEALTH = 100
const GRAVITY = 980.0
const GAME_TITLE = "My Awesome Game"

Basic Math

gdscript
var damage = 25
var defense = 10
var actual_damage = damage - defense  # 15

var base_speed = 100
var boost = 1.5
var boosted_speed = base_speed * boost  # 150.0

# Useful shortcuts
health -= 20  # Same as: health = health - 20
score += 100  # Same as: score = score + 100

Part 2: Making Decisions (5 minutes)

If Statements

gdscript
if health <= 0:
    print("Game Over!")
elif health < 30:
    print("Low health warning!")
else:
    print("Health is fine")

# You can combine conditions
if is_alive and health > 0:
    print("Player is active")

if has_key or is_admin:
    print("Door opens")

Comparison Operators

gdscript
# These all return true or false
health == 100    # Equals
health != 0      # Not equals
health > 50      # Greater than
health < 30      # Less than
health >= 100    # Greater or equal
health <= 0      # Less or equal

Part 3: Loops (5 minutes)

For Loops: Do Something X Times

gdscript
# Count from 0 to 4
for i in range(5):
    print(i)  # Prints: 0, 1, 2, 3, 4

# Loop through a list
var fruits = ["apple", "banana", "orange"]
for fruit in fruits:
    print(fruit)

# Spawn 10 enemies
for i in range(10):
    spawn_enemy()

While Loops: Do Something Until...

gdscript
var countdown = 10
while countdown > 0:
    print(countdown)
    countdown -= 1
print("Blast off!")

Part 4: Functions (5 minutes)

Functions are reusable chunks of code. They're how you organize your game logic.

gdscript
# Basic function
func say_hello():
    print("Hello!")

# Function with parameters
func greet(name):
    print("Hello, " + name + "!")

# Function that returns a value
func add(a, b):
    return a + b

# Function with typed parameters (recommended)
func take_damage(amount: int) -> void:
    health -= amount
    if health <= 0:
        die()

# Using functions
say_hello()           # Prints: Hello!
greet("Player")       # Prints: Hello, Player!
var sum = add(5, 3)   # sum is now 8

Part 5: Godot-Specific Stuff (10 minutes)

This is where GDScript gets fun. These are the features you'll use in every game.

Every Script Starts Like This

gdscript
extends CharacterBody2D  # What type of node this script is for

# Variables go here
var health: int = 100
var speed: float = 200.0

# Called when the node enters the scene
func _ready():
    print("I'm alive!")

# Called every frame (~60 times per second)
func _process(delta):
    # delta is time since last frame
    # Use it for smooth movement
    pass

# Called at fixed intervals (for physics)
func _physics_process(delta):
    # Use this for movement and collisions
    pass

Getting Player Input

gdscript
func _process(delta):
    # Check if a key is held down
    if Input.is_action_pressed("move_right"):
        position.x += speed * delta

    # Check if a key was just pressed (once)
    if Input.is_action_just_pressed("jump"):
        jump()

    # Get axis input (-1, 0, or 1)
    var direction = Input.get_axis("move_left", "move_right")
    position.x += direction * speed * delta

@export: Tweak Values in the Editor

gdscript
# These appear in the Godot Inspector!
@export var speed: float = 200.0
@export var jump_force: float = 400.0
@export var max_health: int = 100

# You can add categories
@export_category("Movement")
@export var acceleration: float = 50.0
@export var friction: float = 30.0

@export_category("Combat")
@export var damage: int = 10
@export var attack_cooldown: float = 0.5

@onready: Get Node References

gdscript
# Get references to child nodes
@onready var sprite = $Sprite2D
@onready var animation_player = $AnimationPlayer
@onready var collision = $CollisionShape2D

# Use them in your code
func die():
    animation_player.play("death")
    collision.disabled = true

Signals: Events Between Nodes

gdscript
# Define your own signal
signal health_changed(new_health)
signal died

# Emit signals when things happen
func take_damage(amount: int):
    health -= amount
    health_changed.emit(health)  # Tell everyone health changed

    if health <= 0:
        died.emit()  # Tell everyone we died

# Connect to signals (in another script)
func _ready():
    player.health_changed.connect(_on_health_changed)
    player.died.connect(_on_player_died)

func _on_health_changed(new_health):
    health_bar.value = new_health

func _on_player_died():
    show_game_over_screen()

Part 6: Common Patterns You'll Use Daily

Basic 2D Player Movement

gdscript
extends CharacterBody2D

@export var speed: float = 200.0
@export var jump_force: float = -400.0
@export var gravity: float = 980.0

func _physics_process(delta):
    # Apply gravity
    if not is_on_floor():
        velocity.y += gravity * delta

    # Jump
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_force

    # Horizontal movement
    var direction = Input.get_axis("move_left", "move_right")
    velocity.x = direction * speed

    # Apply movement
    move_and_slide()

Spawning Objects

gdscript
# Load the scene you want to spawn
@export var bullet_scene: PackedScene

func shoot():
    # Create an instance
    var bullet = bullet_scene.instantiate()

    # Set its position
    bullet.position = position
    bullet.rotation = rotation

    # Add it to the game
    get_parent().add_child(bullet)

Timer / Cooldown

gdscript
var can_shoot: bool = true

func _process(delta):
    if Input.is_action_just_pressed("shoot") and can_shoot:
        shoot()
        can_shoot = false

        # Wait 0.5 seconds, then allow shooting again
        await get_tree().create_timer(0.5).timeout
        can_shoot = true

Cheat Sheet: Quick Reference

gdscript
# Variables
var x = 10                    # Dynamic type
var x: int = 10               # Typed
const X = 10                  # Constant
@export var x: int = 10       # Editable in Inspector
@onready var x = $Node        # Get node reference

# Functions
func name():                  # Basic function
func name(arg: int):          # With parameter
func name() -> int:           # Returns a value

# Lifecycle
func _ready():                # Called once when ready
func _process(delta):         # Called every frame
func _physics_process(delta): # Called for physics

# Input
Input.is_action_pressed("x")      # Is held down?
Input.is_action_just_pressed("x") # Just pressed?
Input.get_axis("left", "right")   # Returns -1, 0, or 1

# Signals
signal my_signal               # Define
my_signal.emit()              # Send
obj.my_signal.connect(func)   # Listen

# Common operations
position.x += 10              # Move right
rotation_degrees += 45        # Rotate
scale *= 2                    # Double size
queue_free()                  # Delete this node

What's Next?

You now know enough GDScript to start making games. Seriously. Open Godot, create a new 2D scene, add a CharacterBody2D, attach a script, and start experimenting.

  • Build something small: A character that moves and jumps
  • Add interaction: Coins to collect, enemies to avoid
  • Learn as you go: Google specific problems when you hit them
  • Check our Learning Hub: Interactive tutorials for nodes, signals, and more

The best way to learn is by building. Pick a simple game idea and start. You'll be surprised how far you can get with just what you've learned here.

👤
Godot Learning Team Helping developers transition to Godot with practical tutorials and comparisons.