GDScript Interview Questions with Answers
Most Asked GDScript Interview Questions for Game Developers
Introduction
This page provides a complete collection of GDScript Interview Questions and Answers designed for game developers, Godot Engine users, and software engineers preparing for technical interviews. GDScript is a high‑level, dynamically typed programming language built specifically for the Godot Engine. It is designed to be easy to learn, efficient, and tightly integrated with Godot's scene system, making it the primary language for game development in Godot. This interview guide covers beginner, intermediate, and advanced GDScript concepts including syntax, data types, nodes, signals, physics, animations, UI, networking, shaders, design patterns, and real‑world game development scenarios.
Why GDScript?
- Optimized for game development – built with games in mind
- Tight integration with Godot Engine – nodes, scenes, signals, and more
- Python‑like syntax – easy to learn and write
- Lightweight and fast – minimal overhead, fast execution
- Extensive built‑in types – Vector2, Color, Rect2, and more
- Vibrant community and ecosystem – plenty of resources and libraries
Most Asked GDScript Interview Questions
GDScript is a high-level, dynamically typed programming language built specifically for the Godot Engine. It is designed to be easy to learn and efficient for game development.
- Python-like Syntax: Easy to learn and read
- Built-in Types: Vector2, Color, Rect2, etc.
- Node-based: Tightly integrated with Godot's scene system
- Lightweight: Optimized for game development
- Signal Support: Built-in event system
# Hello World in GDScript
extends Node
func _ready():
print("Hello, World!")GDScript provides a rich set of data types including integers, floats, strings, booleans, arrays, dictionaries, and built-in Godot types like Vector2 and Color.
- int: Integer numbers
- float: Floating-point numbers
- String: Text strings
- bool: true/false
- Array: Ordered collections
- Dictionary: Key-value pairs
- Vector2: 2D vectors
- Color: RGBA colors
# Data Types in GDScript
extends Node
func _ready():
var age = 25
var salary = 50000.50
var pi = 3.14159265358979
var grade = 'A'
var is_active = true
var name = "Alice"
var price = 99.99
print("Age: ", age)
print("Salary: ", salary)
print("Pi: ", pi)
print("Grade: ", grade)
print("Active: ", is_active)
print("Name: ", name)
print("Price: ", price)GDScript uses var for variables and const for constants. Variables are dynamically typed by default but support static typing with type hints.
- var: Dynamic variable declaration
- const: Compile-time constants
- Type Hints:
var health: int = 100 - Export:
@export var speed: float = 200 - Scope: Variables are local to functions by default
# Variables and Constants in GDScript
extends Node
const PI = 3.14159
const MAX_VALUE = 100
func _ready():
var x = 10
var val = 3.14
var str = "Hello"
var counter = 0
print("x = ", x)
print("PI = ", PI)
print("val = ", val)
print("str = ", str)
print("counter = ", counter)Arrays are ordered collections of elements. GDScript arrays are dynamic and can hold mixed data types.
- Declaration:
var arr = [1, 2, 3] - Access:
arr[0] - Methods:
append(),remove_at(),size() - 2D Arrays:
[[1, 2], [3, 4]] - Iteration:
for item in arr
# Arrays in GDScript
extends Node
func _ready():
var arr = [1, 2, 3, 4, 5]
# Access elements
print("arr[0] = ", arr[0])
print("arr[2] = ", arr[2])
# Array operations
arr.append(6)
arr.append(7)
print("After append: ", arr)
arr.remove_at(2)
print("After remove: ", arr)
# Iteration
for i in range(arr.size()):
print("arr[", i, "] = ", arr[i])
# 2D Array
var matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print("matrix[1][1] = ", matrix[1][1])Functions are reusable blocks of code. GDScript supports function overloading, default parameters, and type hints.
- Declaration:
func function_name(): - Return:
return value - Type Hints:
func add(a: int, b: int) -> int: - Default Parameters:
func greet(name: String = "Guest"): - Variadic:
func sum(...args):
# Functions in GDScript
extends Node
# Function with return value
func add(a, b):
return a + b
# Function with type hints
func subtract(a: int, b: int) -> int:
return a - b
# Function with default parameters
func greet(name: String = "Guest"):
print("Hello, ", name)
# Function with multiple returns
func get_min_max(arr):
var min_val = arr[0]
var max_val = arr[0]
for value in arr:
if value < min_val:
min_val = value
if value > max_val:
max_val = value
return [min_val, max_val]
func _ready():
print("Add: ", add(10, 20))
print("Subtract: ", subtract(20, 10))
greet("Alice")
greet()
var result = get_min_max([5, 2, 8, 1, 9])
print("Min: ", result[0], " Max: ", result[1])Recursion is a technique where a function calls itself. GDScript supports recursive functions with proper base cases.
- Base Case: Stopping condition
- Recursive Case: Self-call with smaller input
- Stack Depth: Be mindful of recursion depth
- Tail Recursion: Can be optimized
- Use Cases: Tree traversal, factorial, Fibonacci
# Recursion in GDScript
extends Node
# Factorial
func factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
# Fibonacci
func fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# Sum of array
func sum_array(arr, index = 0):
if index >= arr.size():
return 0
return arr[index] + sum_array(arr, index + 1)
func _ready():
print("Factorial 5: ", factorial(5))
print("Fibonacci 8: ", fibonacci(8))
print("Sum [1,2,3,4,5]: ", sum_array([1, 2, 3, 4, 5]))Dictionaries are key-value pairs that provide fast lookups. Keys can be any type, and values can be mixed types.
- Declaration:
var dict = {"key": "value"} - Access:
dict["key"]ordict.key - Add:
dict["new_key"] = value - Remove:
dict.erase("key") - Iteration:
for key in dict:
# Dictionaries in GDScript
extends Node
func _ready():
# Dictionary declaration
var scores = {
"Alice": 95,
"Bob": 87,
"Carol": 92
}
# Access values
print("Alice: ", scores["Alice"])
print("Bob: ", scores.get("Bob", 0))
# Add new key-value
scores["Dave"] = 88
# Iterate
for key in scores:
print(key, ": ", scores[key])
# Dictionary with mixed types
var person = {
"name": "Alice",
"age": 25,
"is_active": true,
"hobbies": ["reading", "coding"]
}
print("Person: ", person["name"], ", Age: ", person["age"])Classes are blueprints for creating objects. GDScript supports object-oriented programming with inheritance and polymorphism.
- Class Definition:
class_name MyClass - Constructor:
func _init(): - Properties: Variables in the class
- Methods: Functions in the class
- Inheritance:
extends ParentClass
# Classes and Objects in GDScript
# player.gd
extends Node
class_name Player
var name: String
var health: int
var position: Vector2
func _init(p_name: String, p_health: int = 100):
name = p_name
health = p_health
position = Vector2.ZERO
func take_damage(amount: int):
health -= amount
if health <= 0:
health = 0
print(name, " has died!")
else:
print(name, " took ", amount, " damage. Health: ", health)
func move(delta: Vector2):
position += delta
print(name, " moved to ", position)
func get_health():
return health
# main.gd
extends Node
func _ready():
var player1 = Player.new("Alice", 100)
var player2 = Player.new("Bob", 150)
player1.move(Vector2(10, 5))
player2.move(Vector2(-5, 3))
player1.take_damage(30)
player2.take_damage(50)
print("Player1 health: ", player1.get_health())
print("Player2 health: ", player2.get_health())Inheritance allows classes to reuse and extend behavior from parent classes. GDScript uses extends for inheritance.
- extends: Inherits from a parent class
- super: Calls parent methods
- Override: Redefine parent methods
- Polymorphism: Child classes can be used as parent type
- Multiple Inheritance: Supported via composition
# Inheritance in GDScript
# enemy.gd
extends Node
class_name Enemy
var health: int
var damage: int
func _init(p_health: int = 50, p_damage: int = 10):
health = p_health
damage = p_damage
func attack():
print("Enemy attacks for ", damage, " damage!")
func take_damage(amount: int):
health -= amount
if health <= 0:
print("Enemy defeated!")
else:
print("Enemy health: ", health)
# goblin.gd
extends Enemy
class_name Goblin
var speed: float
func _init(p_health: int = 30, p_damage: int = 5, p_speed: float = 2.0):
super(p_health, p_damage)
speed = p_speed
func attack():
print("Goblin slashes for ", damage, " damage!")
func run_away():
print("Goblin runs away at speed ", speed)
# main.gd
extends Node
func _ready():
var enemy = Enemy.new()
var goblin = Goblin.new()
enemy.attack()
goblin.attack()
goblin.run_away()
enemy.take_damage(20)
goblin.take_damage(15)Signals are GDScript's built-in event system. They allow objects to communicate without direct references.
- Definition:
signal my_signal - Connect:
signal.connect(target, method) - Emit:
emit_signal("my_signal") - Parameters:
signal my_signal(value: int) - Disconnect:
signal.disconnect(target, method)
# Signals in GDScript
extends Node
# Define signal
signal health_changed(new_health, max_health)
signal player_died
var health = 100
var max_health = 100
func take_damage(amount: int):
health -= amount
if health <= 0:
health = 0
emit_signal("player_died")
emit_signal("health_changed", health, max_health)
print("Health: ", health, "/", max_health)
func heal(amount: int):
health = min(health + amount, max_health)
emit_signal("health_changed", health, max_health)
print("Health: ", health, "/", max_health)
func _ready():
# Connect signals
connect("health_changed", self, "_on_health_changed")
connect("player_died", self, "_on_player_died")
# Test
take_damage(30)
heal(20)
take_damage(100)
func _on_health_changed(new_health, new_max):
print("Health updated: ", new_health, "/", new_max)
func _on_player_died():
print("Player has died! Game Over!")Timer is a node that executes code after a delay or at regular intervals. It's essential for time-based operations.
- Creation:
Timer.new() - Wait Time:
timer.wait_time = 1.0 - One Shot:
timer.one_shot = true - Start:
timer.start() - Signal:
timer.connect("timeout", self, "_on_timeout")
# Timer in GDScript
extends Node
var timer: Timer
var count = 0
func _ready():
# Create and configure timer
timer = Timer.new()
timer.wait_time = 1.0
timer.one_shot = false
timer.connect("timeout", self, "_on_timer_timeout")
add_child(timer)
timer.start()
print("Timer started")
func _on_timer_timeout():
count += 1
print("Timer tick: ", count)
if count >= 5:
timer.stop()
print("Timer stopped")Tween (Tweening) animates properties over time with various easing functions. It's used for smooth transitions.
- Creation:
Tween.new() - Interpolate:
tween.interpolate_property() - Start:
tween.start() - Easing:
Tween.TRANS_BOUNCE,Tween.EASE_OUT - Signal:
tween.connect("tween_completed", self, "_on_completed")
# Tween Animation in GDScript
extends Node2D
var tween: Tween
func _ready():
# Create tween
tween = Tween.new()
add_child(tween)
# Animate position
tween.interpolate_property(self, "position",
Vector2(0, 0), Vector2(200, 200), 2.0,
Tween.TRANS_BOUNCE, Tween.EASE_OUT
)
tween.start()
print("Animation started")
func _process(delta):
if tween.is_active():
print("Animating...")Input Handling allows games to respond to player input through keyboard, mouse, and gamepad events.
- Input Events:
_input(event)method - Input Actions:
Input.is_action_pressed("action") - Keyboard:
event is InputEventKey - Mouse:
event is InputEventMouseButton - Joypad:
event is InputEventJoypadButton
# Input Handling in GDScript
extends Node
func _ready():
print("Input system ready")
func _input(event):
if event is InputEventKey:
if event.pressed:
print("Key pressed: ", event.keycode)
if event.keycode == KEY_ESCAPE:
get_tree().quit()
if event is InputEventMouseButton:
if event.pressed:
print("Mouse clicked at: ", event.position)
func _process(delta):
# Input actions
if Input.is_action_just_pressed("ui_accept"):
print("Space pressed")
if Input.is_action_pressed("ui_right"):
print("Moving right")
if Input.is_action_pressed("ui_left"):
print("Moving left")Godot has many Node Types for different purposes including UI, 2D, 3D, and audio nodes. Each node has specific properties and methods.
- Node: Base class for all nodes
- Node2D: 2D game objects
- Node3D: 3D game objects
- Control: UI elements
- AudioStreamPlayer: Audio playback
# Node Types in GDScript
extends Node
func _ready():
# Node creation
var label = Label.new()
label.text = "Hello World"
label.position = Vector2(100, 100)
add_child(label)
# Button
var button = Button.new()
button.text = "Click Me"
button.position = Vector2(200, 200)
button.connect("pressed", self, "_on_button_pressed")
add_child(button)
# Timer
var timer = Timer.new()
timer.wait_time = 2.0
timer.one_shot = true
timer.connect("timeout", self, "_on_timer_timeout")
add_child(timer)
timer.start()
func _on_button_pressed():
print("Button clicked!")
func _on_timer_timeout():
print("Timer timeout!")Signals enable event-driven communication. Groups allow organizing and managing multiple nodes together.
- Groups:
add_to_group("enemies") - Call Group:
get_tree().call_group("enemies", "die") - Signal Connect:
node.connect("signal", target, "method") - Signal Emit:
emit_signal("signal", args) - Group Methods:
get_tree().get_nodes_in_group("group")
# Signals and Groups in GDScript
extends Node
func _ready():
# Create group
add_to_group("enemies")
add_to_group("movable")
# Add child to groups
get_child(0).add_to_group("enemies")
get_child(1).add_to_group("enemies")
# Signal connection
var button = Button.new()
button.text = "Kill All Enemies"
button.connect("pressed", self, "_on_kill_all")
add_child(button)
func _on_kill_all():
# Call group method
get_tree().call_group("enemies", "die")
print("All enemies killed!")
func die():
print("Enemy died!")
queue_free()Physics in GDScript uses physics bodies like RigidBody2D, CharacterBody2D, and StaticBody2D for realistic movement and collision.
- RigidBody2D: Physics simulation
- CharacterBody2D: Character movement
- StaticBody2D: Static colliders
- _physics_process: Physics update loop
- move_and_slide: Smooth movement
# Physics in GDScript
extends RigidBody2D
var speed = 200
var jump_force = 400
func _ready():
print("Physics body ready")
func _physics_process(delta):
# Movement
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
velocity.x = speed
if Input.is_action_pressed("ui_left"):
velocity.x = -speed
# Jump
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = -jump_force
# Apply velocity
set_linear_velocity(velocity)
# Apply gravity
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var gravity_vec = Vector2(0, gravity)
add_central_force(gravity_vec * mass)Area2D detects overlapping bodies and areas, enabling trigger zones, hitboxes, and pickup detection.
- body_entered: Body enters area
- body_exited: Body exits area
- area_entered: Area enters area
- area_exited: Area exits area
- get_overlapping_bodies: Get overlapping bodies
# Area2D Detection in GDScript
extends Area2D
func _ready():
# Connect signals
connect("body_entered", self, "_on_body_entered")
connect("body_exited", self, "_on_body_exited")
connect("area_entered", self, "_on_area_entered")
connect("area_exited", self, "_on_area_exited")
func _on_body_entered(body):
print("Body entered: ", body.name)
func _on_body_exited(body):
print("Body exited: ", body.name)
func _on_area_entered(area):
print("Area entered: ", area.name)
func _on_area_exited(area):
print("Area exited: ", area.name)
func _process(delta):
# Check overlapping bodies
var overlapping_bodies = get_overlapping_bodies()
for body in overlapping_bodies:
print("Overlapping: ", body.name)AnimationPlayer is a node for creating and playing animations. It can animate any property of any node.
- Add Animation:
add_animation("name", animation) - Play:
play("name") - Stop:
stop() - Seek:
seek(position) - Signal:
connect("animation_finished", self, "_on_finished")
# AnimationPlayer in GDScript
extends Node2D
var anim_player: AnimationPlayer
func _ready():
# Create animation player
anim_player = AnimationPlayer.new()
add_child(anim_player)
# Create animation
var animation = Animation.new()
animation.length = 2.0
animation.track_insert_key(0, 0.0, Vector2(0, 0))
animation.track_insert_key(0, 2.0, Vector2(200, 200))
# Add track
animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(0, "self:position")
# Add animation
anim_player.add_animation("move", animation)
# Play animation
anim_player.play("move")
print("Animation playing")
func _process(delta):
if anim_player.is_playing():
print("Animation progress: ", anim_player.current_animation_position)Particle Systems create effects like fire, smoke, and sparks using particles that are emitted and animated.
- Particles2D: GPU-based particles
- CPUParticles2D: CPU-based particles
- Amount: Number of particles
- Lifetime: Particle lifetime
- Material:
ParticlesMaterialfor behavior
# Particle System in GDScript
extends Particles2D
func _ready():
# Configure particles
amount = 100
lifetime = 2.0
speed_scale = 1.0
emitting = true
# Set material
var material = ParticlesMaterial.new()
material.gravity = Vector2(0, 50)
material.initial_velocity = 100
material.initial_velocity_random = 50
set_process_material(material)
print("Particle system ready")
func _process(delta):
if emitting:
print("Emitting particles: ", amount)Path2D defines a path that nodes can follow. PathFollow2D moves along the path at a specified speed.
- Path2D: Defines the path
- PathFollow2D: Follows the path
- Curve2D: Defines path points
- Progress: Position along the path
- Loop:
loop = truefor repeating
# Path2D and PathFollow2D in GDScript
extends Node2D
var path: Path2D
var path_follow: PathFollow2D
func _ready():
# Create path
path = Path2D.new()
add_child(path)
# Create curve
var curve = Curve2D.new()
curve.add_point(Vector2(0, 0))
curve.add_point(Vector2(200, 100))
curve.add_point(Vector2(400, 0))
curve.add_point(Vector2(600, 100))
path.curve = curve
# Create path follow
path_follow = PathFollow2D.new()
path_follow.loop = true
path.add_child(path_follow)
# Add sprite to follow path
var sprite = Sprite2D.new()
sprite.texture = load("res://icon.png")
path_follow.add_child(sprite)
print("Path created")
func _process(delta):
if path_follow:
path_follow.progress += 50 * delta
print("Progress: ", path_follow.progress)TileMap is a node for creating 2D tile-based levels. It uses a TileSet to define tile properties.
- TileSet: Defines tile properties
- set_cell: Places tiles
- get_cell: Gets tile at position
- world_to_map: Converts world to tile coordinates
- map_to_world: Converts tile to world coordinates
# TileMap in GDScript
extends TileMap
func _ready():
# Define tile size
tile_set = TileSet.new()
# Set tile size
tile_set.tile_size = Vector2(16, 16)
# Create tile
var tile_id = tile_set.get_tiles_ids().size()
tile_set.create_tile(tile_id)
# Set tile texture
var texture = load("res://tile.png")
tile_set.tile_set_texture(tile_id, texture)
# Set tile region
tile_set.tile_set_region(tile_id, Rect2(0, 0, 16, 16))
# Set tile
set_cell(0, 0, tile_id)
set_cell(1, 0, tile_id)
set_cell(0, 1, tile_id)
print("TileMap created")
func _process(delta):
# Update tile
var mouse_pos = get_global_mouse_position()
var tile_pos = world_to_map(mouse_pos)
print("Mouse tile: ", tile_pos)Camera2D controls the viewport in 2D games. It can follow targets, apply smoothing, and set limits.
- Follow Target:
camera.position = target.position - Limits:
limit_left,limit_right, etc. - Smoothing:
smoothing_enabled = true - Zoom:
zoom = Vector2(2, 2) - Rotation:
rotation = angle
# Camera2D in GDScript
extends Camera2D
var target: Node2D
var smoothing = 5.0
func _ready():
# Set camera limits
limit_left = -100
limit_right = 1000
limit_top = -100
limit_bottom = 1000
# Set target
target = get_node("../Player")
print("Camera ready")
func _process(delta):
if target:
# Smooth following
position = position.linear_interpolate(target.position, smoothing * delta)
print("Camera position: ", position)ParallaxBackground creates scrolling backgrounds with layers that move at different speeds for depth effect.
- ParallaxLayer: Individual layer
- motion_scale: Layer speed multiplier
- motion_offset: Layer offset
- Scroll:
scroll_offset += velocity * delta - Mirroring:
mirroring = Vector2(1024, 0)
# ParallaxBackground in GDScript
extends ParallaxBackground
func _ready():
# Create layers
var layer1 = ParallaxLayer.new()
layer1.motion_scale = Vector2(0.2, 0.2)
add_child(layer1)
var layer2 = ParallaxLayer.new()
layer2.motion_scale = Vector2(0.5, 0.5)
add_child(layer2)
var layer3 = ParallaxLayer.new()
layer3.motion_scale = Vector2(1.0, 1.0)
add_child(layer3)
# Add sprites to layers
var sprite1 = Sprite2D.new()
sprite1.texture = load("res://bg1.png")
layer1.add_child(sprite1)
print("Parallax background created")AnimationTree enables advanced animation blending and state machines for complex character animations.
- Blend Tree: Blend multiple animations
- State Machine: Animation state management
- Parameters: Control animation blending
- Blend Position:
set("parameter", value) - Active:
active = true
# AnimationTree in GDScript
extends AnimationTree
func _ready():
# Set animation tree
active = true
# Get parameters
var parameters = get_parameters_list()
for param in parameters:
print("Parameter: ", param)
# Set blend position
set("parameters/Idle/blend_position", Vector2(0, 0))
set("parameters/Walk/blend_position", Vector2(1, 0))
print("AnimationTree ready")
func _process(delta):
# Update parameters based on input
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
velocity.x = 1
if Input.is_action_pressed("ui_left"):
velocity.x = -1
if Input.is_action_pressed("ui_down"):
velocity.y = 1
if Input.is_action_pressed("ui_up"):
velocity.y = -1
# Update blend position
set("parameters/Idle/blend_position", velocity)
set("parameters/Walk/blend_position", velocity)Shaders are programs that run on the GPU for visual effects. GDScript can create and control shader materials.
- Shader: GPU program
- ShaderMaterial: Material with shader
- Uniform: Shader parameters
- set_shader_param: Update uniform values
- CanvasItem: 2D shader type
# Shader in GDScript
extends Node2D
var shader_material: ShaderMaterial
func _ready():
# Create shader
var shader = Shader.new()
shader.code = """
shader_type canvas_item;
uniform vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
void fragment() {
COLOR = color;
}
"""
# Create material
shader_material = ShaderMaterial.new()
shader_material.shader = shader
material = shader_material
# Set uniform
shader_material.set_shader_param("color", Color(0, 1, 0, 1))
print("Shader applied")
func _process(delta):
# Update uniform
var time = OS.get_ticks_msec() / 1000.0
var color = Color(sin(time), cos(time), 0, 1)
shader_material.set_shader_param("color", color)Multiplayer in GDScript uses ENet for networking. It supports hosting and joining games with remote procedure calls.
- NetworkedMultiplayerENet: ENet implementation
- Host:
create_server(port, max_players) - Join:
create_client(ip, port) - RPC:
rpc("function_name", args) - Peer Connected:
peer_connectedsignal
# Multiplayer in GDScript
extends Node
var network = NetworkedMultiplayerENet.new()
var port = 8080
var max_players = 4
func host_game():
network.create_server(port, max_players)
get_tree().network_peer = network
network.connect("peer_connected", self, "_on_peer_connected")
network.connect("peer_disconnected", self, "_on_peer_disconnected")
print("Hosting game on port ", port)
func join_game(ip: String):
network.create_client(ip, port)
get_tree().network_peer = network
print("Joining game at ", ip)
func _on_peer_connected(id):
print("Peer connected: ", id)
rpc("register_player", id)
remote func register_player(id):
print("Player registered: ", id)
func _on_peer_disconnected(id):
print("Peer disconnected: ", id)
func _ready():
# Check command line arguments
if OS.get_cmdline_args().has("--host"):
host_game()
else:
join_game("127.0.0.1")WebSockets enable real-time bidirectional communication between games and servers.
- WebSocketClient: Client-side WebSocket
- connect_to_url: Connect to WebSocket server
- send_text: Send text message
- data_received: Signal for received data
- connection_established: Connection success
# WebSocket in GDScript
extends Node
var websocket: WebSocketClient
func _ready():
websocket = WebSocketClient.new()
websocket.connect("connection_established", self, "_on_connected")
websocket.connect("connection_closed", self, "_on_closed")
websocket.connect("data_received", self, "_on_data_received")
websocket.connect("connection_error", self, "_on_error")
var url = "wss://echo.websocket.org"
var err = websocket.connect_to_url(url)
if err == OK:
print("Connecting to ", url)
else:
print("Failed to connect")
func _on_connected():
print("WebSocket connected")
websocket.send_text('{"message": "Hello Server!"}')
func _on_closed(was_clean):
print("WebSocket closed")
func _on_data_received():
var data = websocket.get_peer(1).get_packet()
print("Data received: ", data.get_string_from_utf8())
func _on_error():
print("WebSocket error")HTTP Requests allow games to communicate with web APIs for data fetching and submission.
- HTTPRequest: Node for HTTP requests
- request: Send HTTP request
- request_completed: Signal for response
- JSON.parse: Parse JSON responses
- GET/POST: Different request methods
# HTTP Request in GDScript
extends Node
var http: HTTPRequest
func _ready():
http = HTTPRequest.new()
add_child(http)
http.connect("request_completed", self, "_on_request_completed")
# GET request
http.request("https://api.example.com/data")
print("Request sent")
func _on_request_completed(result, response_code, headers, body):
if result == HTTPRequest.RESULT_SUCCESS:
print("Success: ", response_code)
var data = body.get_string_from_utf8()
print("Data: ", data)
# Parse JSON
var json = JSON.parse(data)
if json.error == OK:
print("Parsed data: ", json.result)
else:
print("Error: ", result)
func _process(delta):
# Handle multiple requests
if Input.is_action_just_pressed("ui_accept"):
http.request("https://api.example.com/update")File Operations read and write files for saving data, loading resources, and managing game state.
- File: File handling object
- open: Open file with mode
- store_string: Write string to file
- get_as_text: Read entire file
- get_line: Read line by line
# File Operations in GDScript
extends Node
func _ready():
# Write to file
var file = File.new()
file.open("user://data.txt", File.WRITE)
file.store_string("Hello, World!
")
file.store_string("Line 2
")
file.store_line("Line 3")
file.close()
# Read from file
file.open("user://data.txt", File.READ)
var content = file.get_as_text()
print("Content: ", content)
file.close()
# Read line by line
file.open("user://data.txt", File.READ)
while not file.eof_reached():
var line = file.get_line()
print("Line: ", line)
file.close()
# Check if file exists
var exists = file.file_exists("user://data.txt")
print("File exists: ", exists)
# Save JSON
var data = {"name": "Alice", "age": 25}
var json = JSON.print(data)
file.open("user://data.json", File.WRITE)
file.store_string(json)
file.close()
print("File operations complete")Resource Management handles loading, saving, and managing game resources like textures, sounds, and scenes.
- Resource: Base resource class
- load: Load resource from disk
- ResourceSaver: Save resources
- ResourceLoader: Load resources
- duplicate: Create resource copy
# Resource Management in GDScript
extends Node
var resource: Resource
func _ready():
# Load resource
resource = load("res://player.tres")
print("Resource loaded: ", resource)
# Create resource
var new_resource = Resource.new()
new_resource.set_meta("name", "Custom Resource")
print("Resource created: ", new_resource)
# Save resource
var error = ResourceSaver.save("res://custom.tres", new_resource)
if error == OK:
print("Resource saved")
else:
print("Failed to save resource")
# Duplicate resource
var duplicate = resource.duplicate()
print("Resource duplicated")
# Set resource properties
if resource.has_method("set_health"):
resource.call("set_health", 100)
print("Resource management complete")Threading enables concurrent execution for performance-intensive tasks like loading and processing.
- Thread: Thread object
- start: Start thread
- wait_to_finish: Wait for thread completion
- Mutex: Thread synchronization
- Semaphore: Thread signaling
# Threading in GDScript
extends Node
var thread: Thread
var mutex: Mutex
var semaphore: Semaphore
func _ready():
mutex = Mutex.new()
semaphore = Semaphore.new()
thread = Thread.new()
# Start thread
thread.start(self, "_thread_function")
print("Thread started")
func _thread_function(userdata):
print("Thread running")
for i in range(10):
# Lock mutex
mutex.lock()
print("Thread: ", i)
mutex.unlock()
# Sleep
OS.delay_msec(100)
# Signal completion
semaphore.post()
print("Thread finished")
func _process(delta):
# Check if thread is still running
if thread.is_alive():
print("Thread is running")
else:
print("Thread stopped")
# Wait for completion
if semaphore.try_wait():
print("Thread completed")
thread.wait_to_finish()Audio in GDScript uses AudioStreamPlayer nodes for playing sound effects and music.
- AudioStreamPlayer: Audio playback
- play: Play audio
- stop: Stop audio
- volume_db: Volume control
- get_playback_position: Current position
# Audio in GDScript
extends Node2D
var audio_player: AudioStreamPlayer
func _ready():
# Create audio player
audio_player = AudioStreamPlayer.new()
add_child(audio_player)
# Load audio
var stream = load("res://sound.wav")
audio_player.stream = stream
# Set volume
audio_player.volume_db = -10
print("Audio system ready")
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_SPACE:
# Play audio
audio_player.play()
print("Playing audio")
if event.keycode == KEY_S:
# Stop audio
audio_player.stop()
print("Audio stopped")
func _process(delta):
# Update audio position
if audio_player.playing:
print("Audio position: ", audio_player.get_playback_position())Video Player plays video files using the VideoStreamPlayer node for cutscenes and intros.
- VideoStreamPlayer: Video playback
- play: Play video
- pause: Pause video
- size: Video size
- stream: Video file
# Video Player in GDScript
extends Node2D
var video_player: VideoStreamPlayer
func _ready():
# Create video player
video_player = VideoStreamPlayer.new()
add_child(video_player)
# Load video
var stream = load("res://video.ogv")
video_player.stream = stream
# Set size
video_player.size = Vector2(640, 480)
video_player.position = Vector2(100, 100)
# Play video
video_player.play()
print("Video playing")
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_P:
# Pause video
if video_player.playing:
video_player.pause()
print("Video paused")
else:
video_player.play()
print("Video resumed")RichTextLabel displays formatted text with colors, fonts, and styles using BBCode.
- bbcode_text: Formatted text
- BBCode: [color], [b], [i], [u]
- add_color_override: Custom colors
- get_meta_at_position: Link handling
- Meta Tags: [url] for links
# Rich Text Label in GDScript
extends RichTextLabel
func _ready():
# Set text with formatting
bbcode_text = """
[center]Hello, [color=red]World![/color][/center]
[b]Bold[/b] [i]Italic[/i] [u]Underlined[/u]
[color=blue]Blue Text[/color]
[font_size=20]Large Text[/font_size]
"""
# Set custom color
add_color_override("default_color", Color(0, 1, 0, 1))
print("RichTextLabel ready")
func _input(event):
if event is InputEventMouseButton and event.pressed:
# Handle click on link
var meta = get_meta_at_position(event.position)
if meta:
print("Link clicked: ", meta)Tree Control displays hierarchical data with expandable items, similar to file explorers.
- TreeItem: Individual item
- create_item: Create item
- set_text: Set item text
- item_activated: Signal for activation
- item_selected: Signal for selection
# Tree Control in GDScript
extends Tree
func _ready():
# Clear tree
clear()
# Create root
var root = create_item()
root.set_text(0, "Root")
# Add child
var child1 = create_item(root)
child1.set_text(0, "Child 1")
child1.set_text(1, "Value 1")
var child2 = create_item(root)
child2.set_text(0, "Child 2")
child2.set_text(1, "Value 2")
# Add sub-child
var subchild = create_item(child1)
subchild.set_text(0, "Subchild")
subchild.set_text(1, "Sub Value")
# Connect signals
connect("item_activated", self, "_on_item_activated")
connect("item_selected", self, "_on_item_selected")
print("Tree ready")
func _on_item_activated():
print("Item activated")
func _on_item_selected():
var selected = get_selected()
if selected:
print("Selected: ", selected.get_text(0))GraphEdit is a node for creating visual node graphs, useful for editors and visual scripting.
- GraphNode: Node in the graph
- connection_request: Signal for connections
- disconnection_request: Signal for disconnections
- add_slot: Add connection slot
- position: Node position
# GraphEdit in GDScript
extends GraphEdit
func _ready():
# Connect signals
connect("connection_request", self, "_on_connection_request")
connect("disconnection_request", self, "_on_disconnection_request")
# Create nodes
var node1 = GraphNode.new()
node1.title = "Node 1"
node1.position = Vector2(100, 100)
add_child(node1)
var node2 = GraphNode.new()
node2.title = "Node 2"
node2.position = Vector2(400, 200)
add_child(node2)
# Add slots
node1.add_slot("Output")
node2.add_slot("Input")
print("GraphEdit ready")
func _on_connection_request(from, from_slot, to, to_slot):
print("Connection from: ", from, " to: ", to)
func _on_disconnection_request(from, from_slot, to, to_slot):
print("Disconnection from: ", from, " to: ", to)LineEdit is a single-line text input field for user input in UI forms and dialogs.
- text: Input text
- placeholder_text: Placeholder text
- text_entered: Signal for enter press
- text_changed: Signal for text change
- secret: Password mode
# LineEdit in GDScript
extends LineEdit
func _ready():
# Set placeholder
placeholder_text = "Enter text..."
placeholder_alpha = 0.5
# Connect signals
connect("text_entered", self, "_on_text_entered")
connect("text_changed", self, "_on_text_changed")
print("LineEdit ready")
func _on_text_entered(new_text):
print("Text entered: ", new_text)
func _on_text_changed(new_text):
print("Text changed: ", new_text)OptionButton is a dropdown selection control for choosing from a list of options.
- add_item: Add option
- select: Select option
- get_item_text: Get option text
- item_selected: Signal for selection
- clear: Clear all items
# OptionButton in GDScript
extends OptionButton
func _ready():
# Add items
add_item("Option 1")
add_item("Option 2")
add_item("Option 3")
# Set selected
select(1)
# Connect signal
connect("item_selected", self, "_on_item_selected")
print("OptionButton ready")
func _on_item_selected(index):
var text = get_item_text(index)
var id = get_item_id(index)
print("Selected: ", text, " (ID: ", id, ")")SpinBox is a numeric input with increment/decrement buttons for entering numerical values.
- min_value: Minimum value
- max_value: Maximum value
- step: Increment step
- value: Current value
- value_changed: Signal for value change
# SpinBox in GDScript
extends SpinBox
func _ready():
# Set range
min_value = 0
max_value = 100
step = 1
value = 50
# Connect signal
connect("value_changed", self, "_on_value_changed")
print("SpinBox ready")
func _on_value_changed(new_value):
print("Value changed: ", new_value)ProgressBar displays progress visually, useful for health bars, loading screens, and experience bars.
- min_value: Minimum value
- max_value: Maximum value
- value: Current value
- modulate: Color
- percent_visible: Show percentage
# ProgressBar in GDScript
extends ProgressBar
func _ready():
# Set range
min_value = 0
max_value = 100
value = 50
# Set color
modulate = Color(0, 1, 0, 1)
print("ProgressBar ready")
func _process(delta):
# Update value
value += 10 * delta
if value > max_value:
value = min_value
print("Progress: ", value, "%")ColorPicker is a UI control for selecting colors with RGB, HSV, and preset support.
- color: Selected color
- color_changed: Signal for color change
- preset_added: Signal for preset addition
- presets: Preset colors
- edit_alpha: Alpha channel editing
# ColorPicker in GDScript
extends ColorPicker
func _ready():
# Connect signals
connect("color_changed", self, "_on_color_changed")
connect("preset_added", self, "_on_preset_added")
# Set initial color
color = Color(1, 0, 0, 1)
print("ColorPicker ready")
func _on_color_changed(new_color):
print("Color changed: ", new_color)
func _on_preset_added(color):
print("Preset added: ", color)FileDialog is a system dialog for opening and saving files, supporting filters and multiple selection.
- mode: Open or save mode
- access: Resource or file system
- filters: File extensions
- file_selected: Signal for file selection
- dir_selected: Signal for directory selection
# FileDialog in GDScript
extends FileDialog
func _ready():
# Configure dialog
mode = FileDialog.MODE_OPEN_FILE
access = FileDialog.ACCESS_RESOURCES
filters = ["*.txt", "*.json"]
# Connect signals
connect("file_selected", self, "_on_file_selected")
connect("files_selected", self, "_on_files_selected")
connect("dir_selected", self, "_on_dir_selected")
print("FileDialog ready")
func _on_file_selected(path):
print("File selected: ", path)
func _on_files_selected(paths):
for path in paths:
print("File selected: ", path)
func _on_dir_selected(path):
print("Directory selected: ", path)TabContainer organizes content into multiple tabs, useful for settings panels and tool windows.
- add_child: Add tab content
- set_tab_title: Set tab title
- tab_changed: Signal for tab change
- current_tab: Current tab index
- get_tab_title: Get tab title
# TabContainer in GDScript
extends TabContainer
func _ready():
# Add tabs
var tab1 = Label.new()
tab1.text = "Tab 1 Content"
add_child(tab1)
set_tab_title(0, "Tab 1")
var tab2 = Label.new()
tab2.text = "Tab 2 Content"
add_child(tab2)
set_tab_title(1, "Tab 2")
var tab3 = Label.new()
tab3.text = "Tab 3 Content"
add_child(tab3)
set_tab_title(2, "Tab 3")
# Connect signal
connect("tab_changed", self, "_on_tab_changed")
print("TabContainer ready")
func _on_tab_changed(tab):
print("Tab changed: ", tab, " - ", get_tab_title(tab))ScrollContainer provides scrollable area for content that exceeds the visible area.
- scroll_horizontal: Horizontal scrolling
- scroll_vertical: Vertical scrolling
- get_h_scroll: Horizontal scroll position
- get_v_scroll: Vertical scroll position
- auto: Auto scroll mode
# ScrollContainer in GDScript
extends ScrollContainer
func _ready():
# Set scroll properties
scroll_horizontal = ScrollContainer.SCROLL_MODE_AUTO
scroll_vertical = ScrollContainer.SCROLL_MODE_AUTO
# Add content
var content = Control.new()
content.size = Vector2(1000, 1000)
add_child(content)
print("ScrollContainer ready")
func _process(delta):
# Get scroll position
var h_scroll = get_h_scroll()
var v_scroll = get_v_scroll()
print("Scroll: ", h_scroll, ", ", v_scroll)ItemList displays a list of selectable items, useful for menus and selection lists.
- add_item: Add list item
- get_item_text: Get item text
- item_selected: Signal for selection
- item_double_clicked: Signal for double click
- clear: Clear all items
# ItemList in GDScript
extends ItemList
func _ready():
# Add items
add_item("Item 1")
add_item("Item 2")
add_item("Item 3")
# Set properties
allow_rmb_select = true
allow_reselect = true
# Connect signals
connect("item_selected", self, "_on_item_selected")
connect("item_double_clicked", self, "_on_item_double_clicked")
print("ItemList ready")
func _on_item_selected(index):
var text = get_item_text(index)
print("Selected: ", text)
func _on_item_double_clicked(index):
var text = get_item_text(index)
print("Double clicked: ", text)LinkButton is a button that acts like a hyperlink, opening URLs or triggering actions.
- uri: URL to open
- text: Button text
- pressed: Signal for press
- underline: Underline style
- OS.shell_open: Open URL
# LinkButton in GDScript
extends LinkButton
func _ready():
# Set text
text = "Visit Website"
# Set link
uri = "https://godotengine.org"
# Connect signal
connect("pressed", self, "_on_pressed")
print("LinkButton ready")
func _on_pressed():
# Open link
OS.shell_open(uri)
print("Link opened: ", uri)CheckButton is a toggleable button that indicates on/off state, similar to a checkbox.
- pressed: Toggle state
- toggled: Signal for state change
- text: Button text
- icon: Button icon
- disabled: Disable button
# CheckButton in GDScript
extends CheckButton
func _ready():
# Set state
pressed = true
# Connect signal
connect("toggled", self, "_on_toggled")
print("CheckButton ready")
func _on_toggled(button_pressed):
print("Button toggled: ", button_pressed)ColorRect is a rectangular node that displays a solid color, useful for backgrounds and UI elements.
- color: Rect color
- size: Rect size
- position: Rect position
- modulate: Color modulation
- material: Shader material
# ColorRect in GDScript
extends ColorRect
func _ready():
# Set color
color = Color(1, 0, 0, 1)
# Set size
size = Vector2(100, 100)
# Set position
position = Vector2(100, 100)
print("ColorRect ready")
func _input(event):
if event is InputEventMouseButton and event.pressed:
# Change color
var new_color = Color(randf(), randf(), randf(), 1)
color = new_color
print("Color changed: ", new_color)NinePatchRect scales a texture using a 9-slice layout, preserving corner integrity for UI elements.
- texture: Patch texture
- patch_margin_left: Left margin
- patch_margin_right: Right margin
- patch_margin_top: Top margin
- patch_margin_bottom: Bottom margin
# NinePatchRect in GDScript
extends NinePatchRect
func _ready():
# Load texture
texture = load("res://panel.png")
# Set patch margins
patch_margin_left = 8
patch_margin_right = 8
patch_margin_top = 8
patch_margin_bottom = 8
# Set size
size = Vector2(200, 100)
print("NinePatchRect ready")TextureRect displays a texture with various stretch modes for UI backgrounds and images.
- texture: Displayed texture
- stretch_mode: Stretch behavior
- size: Rect size
- flip_h: Horizontal flip
- flip_v: Vertical flip
# TextureRect in GDScript
extends TextureRect
func _ready():
# Load texture
texture = load("res://icon.png")
# Set stretch mode
stretch_mode = TextureRect.STRETCH_KEEP_CENTERED
# Set size
size = Vector2(64, 64)
print("TextureRect ready")Sprite2D displays a 2D texture in the game world, the most common node for 2D objects.
- texture: Sprite texture
- scale: Sprite scale
- rotation: Sprite rotation
- modulate: Color modulation
- centered: Center sprite
# Sprite2D in GDScript
extends Sprite2D
func _ready():
# Load texture
texture = load("res://player.png")
# Set properties
scale = Vector2(2, 2)
rotation = 0.5
modulate = Color(1, 0, 0, 1)
print("Sprite2D ready")
func _process(delta):
# Rotate sprite
rotation += delta
print("Rotation: ", rotation)AnimatedSprite2D displays frame-based animations using SpriteFrames for 2D animation.
- frames: SpriteFrames resource
- play: Play animation
- stop: Stop animation
- animation: Current animation name
- frame: Current frame
# AnimatedSprite2D in GDScript
extends AnimatedSprite2D
func _ready():
# Load sprite sheet
var sprite_frames = SpriteFrames.new()
# Add animation
sprite_frames.add_animation("idle")
sprite_frames.add_animation("walk")
# Add frames
for i in range(4):
var texture = load("res://player_idle_" + str(i) + ".png")
sprite_frames.add_frame("idle", texture)
for i in range(6):
var texture = load("res://player_walk_" + str(i) + ".png")
sprite_frames.add_frame("walk", texture)
# Set frames
frames = sprite_frames
# Play animation
play("idle")
print("AnimatedSprite2D ready")
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_W:
play("walk")
print("Walking")
if event.keycode == KEY_S:
play("idle")
print("Idle")CollisionShape2D defines the collision shape for physics bodies, enabling collision detection.
- shape: Collision shape
- position: Shape position
- RectangleShape2D: Rectangle shape
- CircleShape2D: Circle shape
- ConvexPolygonShape2D: Polygon shape
# CollisionShape2D in GDScript
extends CollisionShape2D
func _ready():
# Set shape
shape = RectangleShape2D.new()
shape.size = Vector2(32, 32)
# Set position
position = Vector2(16, 16)
print("CollisionShape2D ready")
func _process(delta):
# Get shape properties
if shape is RectangleShape2D:
print("Shape size: ", shape.size)CollisionPolygon2D defines custom polygon collision shapes for complex collision boundaries.
- polygon: Vertex points
- build_mode: Build mode
- position: Polygon position
- SOLIDS: Solid collision
- SEGMENTS: Segment collision
# CollisionPolygon2D in GDScript
extends CollisionPolygon2D
func _ready():
# Set polygon
polygon = [
Vector2(-16, -16),
Vector2(16, -16),
Vector2(16, 16),
Vector2(-16, 16)
]
# Set build mode
build_mode = CollisionPolygon2D.BUILD_SOLIDS
print("CollisionPolygon2D ready")
func _process(delta):
# Update polygon
var new_polygon = []
for point in polygon:
new_polygon.append(point + Vector2(delta * 10, 0))
polygon = new_polygonRigidBody2D is a physics body that simulates realistic physics with mass, velocity, and forces.
- mass: Body mass
- gravity_scale: Gravity multiplier
- apply_central_force: Apply force
- apply_central_impulse: Apply impulse
- linear_velocity: Current velocity
# RigidBody2D in GDScript
extends RigidBody2D
func _ready():
# Set physics properties
mass = 1.0
gravity_scale = 1.0
friction = 0.5
bounce = 0.2
# Set mode
mode = RigidBody2D.MODE_RIGID
print("RigidBody2D ready")
func _physics_process(delta):
# Apply force
if Input.is_action_pressed("ui_right"):
apply_central_force(Vector2(1000, 0))
if Input.is_action_pressed("ui_left"):
apply_central_force(Vector2(-1000, 0))
# Apply impulse
if Input.is_action_just_pressed("ui_accept"):
apply_central_impulse(Vector2(0, -500))
print("Velocity: ", linear_velocity)CharacterBody2D is a physics body for character movement with collision detection and sliding.
- velocity: Movement velocity
- move_and_slide: Move with sliding
- is_on_floor: Check floor contact
- is_on_wall: Check wall contact
- gravity: Custom gravity
# CharacterBody2D in GDScript
extends CharacterBody2D
var speed = 200
var jump_force = -400
var gravity = 980
func _ready():
print("CharacterBody2D ready")
func _physics_process(delta):
# Apply gravity
velocity.y += gravity * delta
# Horizontal movement
var direction = 0
if Input.is_action_pressed("ui_right"):
direction = 1
if Input.is_action_pressed("ui_left"):
direction = -1
velocity.x = direction * speed
# Jump
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = jump_force
# Move and slide
move_and_slide()
print("Velocity: ", velocity)StaticBody2D is a physics body for static objects like walls, floors, and platforms.
- CollisionShape2D: Collision shape
- friction: Surface friction
- bounce: Surface bounce
- constant_linear_velocity: Constant velocity
- constant_angular_velocity: Constant angular velocity
# StaticBody2D in GDScript
extends StaticBody2D
func _ready():
# Add collision shape
var shape = CollisionShape2D.new()
shape.shape = RectangleShape2D.new()
shape.shape.size = Vector2(32, 32)
add_child(shape)
print("StaticBody2D ready")AnimationPlayer is a node for creating and playing animations. It can animate any property of any node.
- add_animation: Add animation
- play: Play animation
- stop: Stop animation
- seek: Seek to position
- animation_finished: Signal for completion
# AnimationPlayer in GDScript
extends AnimationPlayer
func _ready():
# Create animation
var animation = Animation.new()
animation.length = 2.0
# Add track
var track_idx = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(track_idx, "self:position")
# Add keys
animation.track_insert_key(track_idx, 0.0, Vector2(0, 0))
animation.track_insert_key(track_idx, 1.0, Vector2(200, 0))
animation.track_insert_key(track_idx, 2.0, Vector2(0, 0))
# Add animation
add_animation("move", animation)
# Play animation
play("move")
print("AnimationPlayer ready")
func _process(delta):
if is_playing():
print("Animation progress: ", current_animation_position)AnimationTree enables advanced animation blending and state machines for complex character animations.
- Blend Tree: Blend multiple animations
- State Machine: Animation state management
- Parameters: Control animation blending
- Blend Position: Set parameter values
- Active: Enable animation tree
# AnimationTree in GDScript
extends AnimationTree
func _ready():
# Set animation player
var anim_player = get_parent().get_node("AnimationPlayer")
set_animation_player(anim_player)
# Set parameters
set("parameters/Idle/blend_position", Vector2(0, 0))
set("parameters/Walk/blend_position", Vector2(1, 0))
# Set active
active = true
print("AnimationTree ready")
func _process(delta):
# Get input
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
velocity.x = 1
if Input.is_action_pressed("ui_left"):
velocity.x = -1
# Update blend position
set("parameters/Idle/blend_position", velocity)
set("parameters/Walk/blend_position", velocity)Skeleton2D is a node for skeletal animation, enabling bone-based character animation.
- Bone2D: Bone node
- length: Bone length
- rotation: Bone rotation
- rest: Rest pose
- set_bone_rest: Set rest pose
# Skeleton2D in GDScript
extends Skeleton2D
func _ready():
# Create bones
var bone1 = Bone2D.new()
bone1.name = "Bone1"
bone1.length = 50
add_child(bone1)
var bone2 = Bone2D.new()
bone2.name = "Bone2"
bone2.length = 50
bone1.add_child(bone2)
# Set rest pose
set_bone_rest(0, Transform2D.IDENTITY)
set_bone_rest(1, Transform2D.IDENTITY)
print("Skeleton2D ready")
func _process(delta):
# Rotate bones
var bone1 = get_node("Bone1")
bone1.rotation += delta
print("Bone1 rotation: ", bone1.rotation)Joint2D connects two physics bodies, enabling constraints like pins, springs, and hinges.
- node_a: First body
- node_b: Second body
- softness: Joint softness
- bias: Joint bias
- Position: Joint position
# Joint2D in GDScript
extends Joint2D
func _ready():
# Set nodes
node_a = get_node("../Body1")
node_b = get_node("../Body2")
# Set properties
softness = 0.5
bias = 0.5
print("Joint2D ready")PinJoint2D pins two bodies together at a point, like a hinge or pivot point.
- node_a: First body
- node_b: Second body
- position: Pin position
- angular: Angular locking
- Motor: Joint motor
# PinJoint2D in GDScript
extends PinJoint2D
func _ready():
# Set nodes
node_a = get_node("../Body1")
node_b = get_node("../Body2")
# Set anchor
position = Vector2(0, 0)
print("PinJoint2D ready")DampedSpringJoint2D connects two bodies with a spring-like constraint with damping.
- length: Spring rest length
- stiffness: Spring stiffness
- damping: Spring damping
- node_a: First body
- node_b: Second body
# DampedSpringJoint2D in GDScript
extends DampedSpringJoint2D
func _ready():
# Set nodes
node_a = get_node("../Body1")
node_b = get_node("../Body2")
# Set properties
length = 100
stiffness = 10
damping = 5
print("DampedSpringJoint2D ready")Light2D is a node that adds lighting effects to 2D scenes, creating dynamic illumination.
- color: Light color
- energy: Light intensity
- mode: Light blend mode
- texture: Light texture
- range: Light range
# Light2D in GDScript
extends Light2D
func _ready():
# Set color
color = Color(1, 1, 0, 1)
# Set energy
energy = 1.0
# Set mode
mode = Light2D.MODE_ADD
print("Light2D ready")
func _process(delta):
# Animate light
energy = 1.0 + sin(OS.get_ticks_msec() / 1000.0) * 0.5
print("Energy: ", energy)PointLight2D is a light that emits from a single point, creating radial illumination.
- texture: Light texture
- texture_scale: Light size
- range: Light range
- color: Light color
- energy: Light intensity
# PointLight2D in GDScript
extends PointLight2D
func _ready():
# Set texture
texture = load("res://light.png")
# Set size
texture_scale = 2.0
# Set range
range = 100
print("PointLight2D ready")DirectionalLight2D simulates parallel light rays, like sunlight, creating shadows in a direction.
- direction: Light direction
- energy: Light intensity
- color: Light color
- shadow: Shadow settings
- blend_mode: Blend mode
# DirectionalLight2D in GDScript
extends DirectionalLight2D
func _ready():
# Set direction
direction = Vector2(1, 1).normalized()
# Set energy
energy = 0.5
print("DirectionalLight2D ready")Shadows in GDScript are created by lights casting shadows on occluders, adding depth to scenes.
- Shadow2D: Shadow node
- color: Shadow color
- smooth: Shadow smoothness
- occluder: Shadow occluder
- cast_shadow: Enable shadow casting
# Shadow in GDScript
extends Node2D
var shadow: Shadow2D
func _ready():
# Create shadow
shadow = Shadow2D.new()
shadow.color = Color(0, 0, 0, 0.5)
shadow.smooth = 10.0
add_child(shadow)
print("Shadow ready")VisibilityNotifier2D detects when a node becomes visible or invisible in the viewport.
- screen_entered: Signal for screen enter
- screen_exited: Signal for screen exit
- viewport_entered: Signal for viewport enter
- rect: Visibility rect
- enable: Enable notifier
# VisibilityNotifier2D in GDScript
extends VisibilityNotifier2D
func _ready():
# Connect signals
connect("screen_entered", self, "_on_screen_entered")
connect("screen_exited", self, "_on_screen_exited")
connect("viewport_entered", self, "_on_viewport_entered")
print("VisibilityNotifier2D ready")
func _on_screen_entered():
print("Entered screen")
func _on_screen_exited():
print("Exited screen")
func _on_viewport_entered(viewport):
print("Entered viewport: ", viewport.name)Viewport is a node that renders a separate view of the scene, useful for split-screen and rendering to textures.
- size: Viewport size
- clear_color: Background color
- update_mode: Update frequency
- render_target: Render target
- world: Viewport world
# Viewport in GDScript
extends Viewport
func _ready():
# Set size
size = Vector2(200, 200)
# Set clear color
set_clear_color(Color(0, 0, 0, 1))
# Set update mode
update_mode = Viewport.UPDATE_ALWAYS
print("Viewport ready")WorldEnvironment controls the environment settings for the scene including background, sky, and ambient light.
- environment: Environment resource
- background_mode: Background mode
- background_color: Background color
- ambient_light: Ambient lighting
- sky: Sky resource
# WorldEnvironment in GDScript
extends WorldEnvironment
func _ready():
# Set environment
var env = Environment.new()
# Background
env.background_mode = Environment.BG_COLOR
env.background_color = Color(0.2, 0.2, 0.5, 1)
# Ambient light
env.ambient_light_color = Color(1, 1, 1, 1)
env.ambient_light_energy = 0.5
# Sky
var sky = Sky.new()
sky.texture = load("res://sky.png")
env.sky = sky
# Set environment
environment = env
print("WorldEnvironment ready")MeshInstance2D displays a 2D mesh in the scene, useful for complex shapes and effects.
- mesh: Mesh resource
- material: Mesh material
- rotation: Mesh rotation
- scale: Mesh scale
- position: Mesh position
# MeshInstance2D in GDScript
extends MeshInstance2D
func _ready():
# Create mesh
var mesh = RectangleShape2D.new()
mesh.size = Vector2(100, 100)
# Set mesh
shape = mesh
print("MeshInstance2D ready")
func _process(delta):
# Rotate mesh
rotation += delta
print("Rotation: ", rotation)Polygon2D draws a filled polygon with customizable vertices, colors, and textures.
- polygon: Vertex points
- color: Fill color
- texture: Polygon texture
- texture_offset: Texture offset
- antialiased: Anti-aliasing
# Polygon2D in GDScript
extends Polygon2D
func _ready():
# Set polygon
polygon = [
Vector2(0, 0),
Vector2(100, 0),
Vector2(50, 100)
]
# Set color
color = Color(1, 0, 0, 1)
print("Polygon2D ready")
func _process(delta):
# Update polygon
var new_polygon = []
var time = OS.get_ticks_msec() / 1000.0
for point in polygon:
new_polygon.append(point + Vector2(sin(time) * 10, 0))
polygon = new_polygonLine2D draws lines with customizable width, color, and points, useful for paths and trails.
- points: Line points
- width: Line width
- default_color: Line color
- antialiased: Anti-aliasing
- begin: Start drawing
# Line2D in GDScript
extends Line2D
func _ready():
# Set points
points = [
Vector2(0, 0),
Vector2(100, 100),
Vector2(200, 0)
]
# Set properties
width = 2.0
default_color = Color(1, 0, 0, 1)
antialiased = true
print("Line2D ready")
func _process(delta):
# Update points
var time = OS.get_ticks_msec() / 1000.0
var new_points = []
for i in range(points.size()):
var point = points[i]
new_points.append(point + Vector2(sin(time + i) * 10, 0))
points = new_pointsParticles2D is a GPU-based particle system for creating effects like fire, smoke, and sparks.
- amount: Particle count
- lifetime: Particle lifetime
- speed_scale: Speed multiplier
- emitting: Emit particles
- process_material: Material settings
# Particles2D in GDScript
extends Particles2D
func _ready():
# Configure particles
amount = 100
lifetime = 2.0
speed_scale = 1.0
emitting = true
# Set material
var material = ParticlesMaterial.new()
material.gravity = Vector2(0, 50)
material.initial_velocity = 100
material.initial_velocity_random = 50
set_process_material(material)
print("Particles2D ready")
func _process(delta):
if emitting:
print("Emitting particles: ", amount)CPUParticles2D is a CPU-based particle system, more flexible but less performant than GPU particles.
- amount: Particle count
- lifetime: Particle lifetime
- gravity: Particle gravity
- initial_velocity: Starting velocity
- emission_shape: Emission shape
# CPUParticles2D in GDScript
extends CPUParticles2D
func _ready():
# Configure particles
amount = 100
lifetime = 2.0
# Set material
gravity = Vector2(0, 50)
initial_velocity = 100
initial_velocity_random = 50
# Set emission
emission_shape = CPUParticles2D.EMISSION_SHAPE_CIRCLE
emission_radius = 50
# Start emitting
emitting = true
print("CPUParticles2D ready")Trail2D creates a trail effect that follows a node, useful for motion trails and effects.
- trail_length: Length of trail
- modulate: Trail color
- add_point: Add trail point
- get_points: Get trail points
- clear: Clear trail
# Trail2D in GDScript
extends Trail2D
func _ready():
# Set length
trail_length = 20
# Set color
modulate = Color(1, 0, 0, 0.5)
print("Trail2D ready")
func _process(delta):
# Add point
var position = get_global_mouse_position()
add_point(position)
print("Trail length: ", get_points().size())Debugging in GDScript uses print statements, breakpoints, and the debugger to find and fix issues.
- print: Print debug messages
- assert: Assert conditions
- breakpoint: Pause execution
- get_stack: Get call stack
- OS.get_ticks_usec: Timing
# Debug in GDScript
extends Node
func _ready():
# Print debug messages
print("Debug message")
print("Debug: ", 42)
# Print warning
print("Warning: Something might be wrong")
# Print error
print("Error: Something went wrong")
# Assert
assert(1 + 1 == 2, "Math is broken!")
# Breakpoint
breakpoint
# Debug with stack trace
var stack = get_stack()
for frame in stack:
print(frame["source"], ":", frame["line"])
print("Debug ready")Profiling measures performance to identify bottlenecks and optimize code execution.
- OS.get_ticks_usec: High-precision timing
- Performance Monitor: Godot's built-in profiler
- Frame Time: Measure frame duration
- Function Timing: Measure function execution
- Memory Profiling: Track memory usage
# Profiling in GDScript
extends Node
func _ready():
# Start profiling
var start_time = OS.get_ticks_usec()
# Do work
for i in range(10000):
var x = i * i
# End profiling
var end_time = OS.get_ticks_usec()
var elapsed = (end_time - start_time) / 1000.0
print("Time taken: ", elapsed, " ms")
print("Profiling complete")Best Practices in GDScript include using type hints, constants, proper naming, and code organization for maintainable code.
- Type Hints: Use static typing
- Constants: Use const for constants
- Naming: Descriptive variable names
- Export: Use export for inspector variables
- Groups: Organize nodes with groups
# GDScript Best Practices
extends Node
# Use type hints
var health: int = 100
var name: String = "Player"
# Use const for constants
const MAX_HEALTH = 100
const SPEED = 200
# Use _ready for initialization
func _ready():
# Use connect for signals
get_tree().connect("node_added", self, "_on_node_added")
# Use groups for organization
add_to_group("players")
print("Best practices applied")
func _on_node_added(node):
print("Node added: ", node.name)
# Use _process for per-frame updates
func _process(delta):
pass
# Use _physics_process for physics updates
func _physics_process(delta):
pass
# Use _input for input handling
func _input(event):
pass
# Use comments for documentation
# This is a comment
# Use descriptive variable names
var player_position = Vector2.ZERO
var enemy_count = 0
# Use static typing
func get_health() -> int:
return health
# Use export variables
@export var speed: int = 200
@export var jump_force: int = 400Performance Optimization improves game performance through efficient code, memory management, and optimization techniques.
- Local Variables: Use local variable references
- Preallocated Arrays: Preallocate arrays
- Pool Arrays: Use PoolVector arrays
- yield: Use yield for background processing
- Profiling: Profile to find bottlenecks
# Performance Optimization in GDScript
extends Node
func _ready():
# Use local variables
var local_var = 0
for i in range(1000):
local_var += i
# Use preallocated arrays
var arr = []
arr.resize(1000)
for i in range(1000):
arr[i] = i
# Use PoolVector arrays for performance
var pool = PoolIntArray()
pool.resize(1000)
for i in range(1000):
pool[i] = i
# Use yield for background processing
yield(get_tree(), "idle_frame")
print("Performance optimization complete")Export Variables expose variables in the inspector for easy configuration in the editor.
- @export: Basic export
- @export_range: Range export
- @export_file: File path export
- @export_dir: Directory export
- @export_color_no_alpha: Color export
# Export Variables in GDScript
extends Node
# Basic export
@export var health: int = 100
@export var speed: float = 200.0
@export var name: String = "Player"
# Range export
@export_range(0, 100) var damage: int = 50
# File export
@export_file("*.png", "*.jpg") var texture_path: String
# Directory export
@export_dir var resource_path: String
# Color export
@export_color_no_alpha var color: Color = Color(1, 1, 1)
# Multi-line export
@export_multiline var description: String = ""
# Group export
@export_group("Physics")
@export var gravity: float = 980.0
@export var friction: float = 0.5
func _ready():
print("Export variables ready")Tool Scripts are scripts that run in the editor, enabling custom tools and editor extensions.
- tool: Tool script keyword
- Engine.is_editor_hint: Check editor mode
- _get_property_list: Custom properties
- _get: Get custom property
- _set: Set custom property
# Tool Scripts in GDScript
tool
extends Node
func _ready():
# Check if in editor
if Engine.is_editor_hint():
print("Running in editor")
else:
print("Running in game")
func _process(delta):
# Update in editor
if Engine.is_editor_hint():
print("Editor update")
func _get_property_list():
# Custom property list
var properties = []
properties.append({
"name": "custom_property",
"type": TYPE_INT,
"hint": PROPERTY_HINT_RANGE,
"hint_string": "0,100,1"
})
return properties
func _get(property):
if property == "custom_property":
return 42
return null
func _set(property, value):
if property == "custom_property":
print("Property set to: ", value)
return true
return false
func _get_configuration_warning():
# Return warning message
if not has_node("Child"):
return "Missing child node"
return ""Plugins extend Godot's editor functionality with custom tools, nodes, and inspector plugins.
- EditorPlugin: Base plugin class
- add_custom_type: Add custom node
- add_tool_menu_item: Add menu item
- add_inspector_plugin: Add inspector plugin
- _enter_tree: Plugin initialization
# Plugins in GDScript
tool
extends EditorPlugin
func _enter_tree():
# Add custom node
add_custom_type("MyNode", "Node", preload("my_node.gd"), preload("icon.png"))
# Add custom menu item
add_tool_menu_item("My Tool", self, "_on_tool_menu_pressed")
# Add custom inspector plugin
var plugin = preload("inspector_plugin.gd").new()
add_inspector_plugin(plugin)
print("Plugin initialized")
func _exit_tree():
# Cleanup
remove_custom_type("MyNode")
remove_tool_menu_item("My Tool")
print("Plugin cleaned up")
func _on_tool_menu_pressed():
print("Tool menu pressed")
func _has_main_screen():
return true
func _get_plugin_name():
return "My Plugin"
func _get_plugin_icon():
return preload("icon.png")Autoload is a singleton pattern in Godot where scripts are loaded automatically and globally accessible.
- Global: Accessed from anywhere
- Singleton: Single instance
- Auto: Automatically loaded
- Shared Data: Game state, settings
- Persistent: Exists throughout the game
# Autoload in GDScript
# Global.gd
extends Node
var player_score = 0
var player_name = "Player"
func add_score(points):
player_score += points
print("Score: ", player_score)
func set_name(name):
player_name = name
print("Name: ", player_name)
# main.gd
extends Node
func _ready():
# Access autoload
Global.add_score(10)
Global.set_name("Alice")
print("Autoload ready")Singleton Pattern ensures a class has only one instance, providing global access to that instance.
- static var: Single instance
- get_instance: Access instance
- _init: Initialize singleton
- Global State: Shared game data
- Persistent: Across scenes
# Singleton Pattern in GDScript
# GameManager.gd
extends Node
class_name GameManager
static var instance: GameManager
func _init():
if instance == null:
instance = self
else:
queue_free()
func _ready():
print("GameManager initialized")
static func get_instance():
return instance
var current_scene: String = "main"
var game_state = {
"score": 0,
"level": 1,
"lives": 3
}
func save_state():
print("Saving game state")
func load_state():
print("Loading game state")
func reset_state():
game_state["score"] = 0
game_state["level"] = 1
game_state["lives"] = 3
print("Game state reset")
# main.gd
extends Node
func _ready():
var gm = GameManager.get_instance()
gm.save_state()
gm.reset_state()
print("Singleton pattern implemented")Factory Pattern creates objects without specifying the concrete class, providing flexibility in object creation.
- Factory Class: Creates objects
- Static Method: Create method
- Type Parameter: Specify type
- Polymorphism: Create different types
- Decoupling: Separate creation from usage
# Factory Pattern in GDScript
# EnemyFactory.gd
extends Node
class_name EnemyFactory
static func create_enemy(type: String):
match type:
"goblin":
return load("res://Goblin.tscn").instance()
"orc":
return load("res://Orc.tscn").instance()
"dragon":
return load("res://Dragon.tscn").instance()
_:
return null
# main.gd
extends Node
func _ready():
var goblin = EnemyFactory.create_enemy("goblin")
if goblin:
add_child(goblin)
print("Goblin created")
var orc = EnemyFactory.create_enemy("orc")
if orc:
add_child(orc)
print("Orc created")
print("Factory pattern implemented")Observer Pattern enables event-driven communication where observers react to events from subjects.
- Subject: Emits events
- Observer: Listens for events
- Signals: Built-in event system
- Connect: Register observers
- Emit: Trigger events
# Observer Pattern in GDScript
# EventBus.gd
extends Node
signal player_hit(damage)
signal player_healed(amount)
signal enemy_died
signal game_over
static var instance: EventBus
func _init():
if instance == null:
instance = self
else:
queue_free()
func _ready():
print("EventBus initialized")
static func get_instance():
return instance
# Player.gd
extends Node
func _ready():
var bus = EventBus.get_instance()
bus.connect("player_hit", self, "_on_player_hit")
bus.connect("player_healed", self, "_on_player_healed")
func _on_player_hit(damage):
print("Player took ", damage, " damage")
func _on_player_healed(amount):
print("Player healed ", amount)
# Enemy.gd
extends Node
func _ready():
var bus = EventBus.get_instance()
bus.connect("enemy_died", self, "_on_enemy_died")
bus.connect("game_over", self, "_on_game_over")
func _on_enemy_died():
print("Enemy died")
func _on_game_over():
print("Game over!")
# main.gd
extends Node
func _ready():
var bus = EventBus.get_instance()
bus.emit_signal("player_hit", 30)
bus.emit_signal("player_healed", 20)
bus.emit_signal("enemy_died")
bus.emit_signal("game_over")
print("Observer pattern implemented")State Pattern allows an object to change its behavior when its internal state changes, implementing state machines.
- State: Base state class
- Enter/Exit: State lifecycle
- Update: State logic
- Transition: State switching
- Context: Object using states
# State Pattern in GDScript
# State.gd
extends Node
class_name State
func enter():
pass
func exit():
pass
func update(delta):
pass
func physics_update(delta):
pass
# IdleState.gd
extends State
func enter():
print("Entering idle state")
func update(delta):
if Input.is_action_pressed("ui_right"):
get_parent().change_state("walk")
if Input.is_action_just_pressed("ui_accept"):
get_parent().change_state("jump")
# WalkState.gd
extends State
func enter():
print("Entering walk state")
func update(delta):
if not Input.is_action_pressed("ui_right"):
get_parent().change_state("idle")
if Input.is_action_just_pressed("ui_accept"):
get_parent().change_state("jump")
# JumpState.gd
extends State
func enter():
print("Entering jump state")
func physics_update(delta):
var parent = get_parent()
if parent.is_on_floor():
parent.change_state("idle")
# Player.gd
extends CharacterBody2D
var current_state: State
var states = {}
func _ready():
# Initialize states
states["idle"] = IdleState.new()
states["walk"] = WalkState.new()
states["jump"] = JumpState.new()
for state in states.values():
add_child(state)
state.set_parent(self)
change_state("idle")
func change_state(new_state: String):
if current_state:
current_state.exit()
current_state = states[new_state]
current_state.enter()
func _process(delta):
if current_state:
current_state.update(delta)
func _physics_process(delta):
if current_state:
current_state.physics_update(delta)
print("State: ", current_state)Command Pattern encapsulates requests as objects, enabling queuing, undo/redo, and logging.
- Command: Encapsulates action
- Execute: Perform action
- Undo: Reverse action
- Redo: Reapply action
- History: Store commands
# Command Pattern in GDScript
# Command.gd
class_name Command
func execute():
pass
func undo():
pass
# MoveCommand.gd
extends Command
var target: Node2D
var start_pos: Vector2
var end_pos: Vector2
var duration: float = 1.0
var elapsed: float = 0.0
func _init(p_target: Node2D, p_end: Vector2):
target = p_target
start_pos = target.position
end_pos = p_end
func execute():
elapsed = 0.0
func update(delta):
if elapsed < duration:
elapsed += delta
var t = elapsed / duration
target.position = start_pos.linear_interpolate(end_pos, t)
return false
else:
target.position = end_pos
return true
# CommandManager.gd
extends Node
var commands = []
var current_index = -1
func execute(command: Command):
current_index += 1
commands.resize(current_index + 1)
commands[current_index] = command
command.execute()
func undo():
if current_index >= 0:
commands[current_index].undo()
current_index -= 1
func redo():
if current_index + 1 < commands.size():
current_index += 1
commands[current_index].execute()
# main.gd
extends Node2D
var command_manager: CommandManager
var target: Node2D
func _ready():
command_manager = CommandManager.new()
add_child(command_manager)
target = Node2D.new()
add_child(target)
print("Command pattern ready")
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_M:
var cmd = MoveCommand.new(target, Vector2(200, 200))
command_manager.execute(cmd)
if event.keycode == KEY_Z and Input.is_action_pressed("ui_ctrl"):
command_manager.undo()
if event.keycode == KEY_Y and Input.is_action_pressed("ui_ctrl"):
command_manager.redo()Strategy Pattern defines a family of algorithms and makes them interchangeable at runtime.
- Strategy: Algorithm interface
- Context: Uses strategy
- Set Strategy: Change algorithm
- Execute: Run algorithm
- Behavior: Dynamic behavior
# Strategy Pattern in GDScript
# WeaponStrategy.gd
class_name WeaponStrategy
func attack():
pass
# SwordStrategy.gd
extends WeaponStrategy
func attack():
print("Swinging sword!")
# BowStrategy.gd
extends WeaponStrategy
func attack():
print("Shooting arrow!")
# MagicStrategy.gd
extends WeaponStrategy
func attack():
print("Casting magic spell!")
# Player.gd
extends Node
var weapon: WeaponStrategy
func _ready():
set_weapon(SwordStrategy.new())
func set_weapon(new_weapon: WeaponStrategy):
weapon = new_weapon
print("Weapon equipped")
func attack():
if weapon:
weapon.attack()
else:
print("No weapon equipped")
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_1:
set_weapon(SwordStrategy.new())
if event.keycode == KEY_2:
set_weapon(BowStrategy.new())
if event.keycode == KEY_3:
set_weapon(MagicStrategy.new())
if event.keycode == KEY_SPACE:
attack()
func _ready():
print("Strategy pattern ready")Decorator Pattern adds behavior to objects dynamically without modifying their structure.
- Component: Base object
- Decorator: Adds behavior
- Wrapping: Wrap objects
- Composition: Multiple decorators
- Extension: Dynamic extension
# Decorator Pattern in GDScript
# Weapon.gd
class_name Weapon
func get_damage():
return 0
func get_description():
return ""
# BaseWeapon.gd
extends Weapon
var damage = 10
func get_damage():
return damage
func get_description():
return "Base Weapon"
# WeaponDecorator.gd
extends Weapon
var weapon: Weapon
func _init(w: Weapon):
weapon = w
func get_damage():
return weapon.get_damage()
func get_description():
return weapon.get_description()
# FireDecorator.gd
extends WeaponDecorator
func get_damage():
return weapon.get_damage() + 5
func get_description():
return weapon.get_description() + " with Fire"
# PoisonDecorator.gd
extends WeaponDecorator
func get_damage():
return weapon.get_damage() + 3
func get_description():
return weapon.get_description() + " with Poison"
# main.gd
extends Node
func _ready():
var base = BaseWeapon.new()
print("Base: ", base.get_description(), " Damage: ", base.get_damage())
var fire = FireDecorator.new(base)
print("Fire: ", fire.get_description(), " Damage: ", fire.get_damage())
var poison = PoisonDecorator.new(base)
print("Poison: ", poison.get_description(), " Damage: ", poison.get_damage())
var fire_poison = PoisonDecorator.new(FireDecorator.new(base))
print("Fire+Poison: ", fire_poison.get_description(), " Damage: ", fire_poison.get_damage())
print("Decorator pattern implemented")Adapter Pattern converts one interface to another, allowing incompatible interfaces to work together.
- Target: Expected interface
- Adaptee: Existing interface
- Adapter: Bridges interfaces
- Compatibility: Legacy integration
- Wrapping: Wrap adaptee
# Adapter Pattern in GDScript
# LegacySystem.gd
class_name LegacySystem
func old_method():
print("Legacy system old method")
# NewSystem.gd
class_name NewSystem
func new_method():
print("New system new method")
# Adapter.gd
extends NewSystem
var legacy: LegacySystem
func _init(l: LegacySystem):
legacy = l
func new_method():
legacy.old_method()
print("Adapted to new system")
# main.gd
extends Node
func _ready():
var legacy = LegacySystem.new()
var adapter = Adapter.new(legacy)
legacy.old_method()
adapter.new_method()
print("Adapter pattern implemented")Bridge Pattern decouples abstraction from implementation, allowing them to vary independently.
- Abstraction: High-level interface
- Implementation: Low-level operations
- Bridge: Connects abstraction and implementation
- Flexibility: Independent variation
- Composition: Uses implementation
# Bridge Pattern in GDScript
# Renderer.gd
class_name Renderer
func render():
pass
# OpenGLRenderer.gd
extends Renderer
func render():
print("Rendering with OpenGL")
# VulkanRenderer.gd
extends Renderer
func render():
print("Rendering with Vulkan")
# Shape.gd
class_name Shape
var renderer: Renderer
func _init(r: Renderer):
renderer = r
func draw():
pass
# Circle.gd
extends Shape
func draw():
renderer.render()
print("Drawing Circle")
# Rectangle.gd
extends Shape
func draw():
renderer.render()
print("Drawing Rectangle")
# main.gd
extends Node
func _ready():
var opengl = OpenGLRenderer.new()
var vulkan = VulkanRenderer.new()
var circle = Circle.new(opengl)
circle.draw()
var rect = Rectangle.new(vulkan)
rect.draw()
print("Bridge pattern implemented")Composite Pattern composes objects into tree structures to represent part-whole hierarchies.
- Component: Base interface
- Leaf: Individual object
- Composite: Container of objects
- Add/Remove: Manage children
- Operation: Recursive operation
# Composite Pattern in GDScript
# GameObject.gd
class_name GameObject
func operation():
pass
# Leaf.gd
extends GameObject
var name: String
func _init(n: String):
name = n
func operation():
print("Leaf: ", name)
# Composite.gd
extends GameObject
var children = []
func add(child: GameObject):
children.append(child)
func remove(child: GameObject):
children.erase(child)
func operation():
print("Composite:")
for child in children:
child.operation()
# main.gd
extends Node
func _ready():
var leaf1 = Leaf.new("Leaf 1")
var leaf2 = Leaf.new("Leaf 2")
var leaf3 = Leaf.new("Leaf 3")
var composite1 = Composite.new()
composite1.add(leaf1)
composite1.add(leaf2)
var composite2 = Composite.new()
composite2.add(leaf3)
composite2.add(composite1)
composite2.operation()
print("Composite pattern implemented")Flyweight Pattern minimizes memory usage by sharing data between similar objects.
- Flyweight: Shared object
- Factory: Creates flyweights
- Cache: Store shared objects
- Shared State: Common data
- Unique State: Instance-specific data
# Flyweight Pattern in GDScript
# Particle.gd
class_name Particle
var texture: String
var color: Color
var size: float
var position: Vector2
var velocity: Vector2
# ParticleFactory.gd
extends Node
var particle_cache = {}
func get_particle(texture: String, color: Color, size: float):
var key = texture + str(color) + str(size)
if particle_cache.has(key):
return particle_cache[key].duplicate()
else:
var particle = Particle.new()
particle.texture = texture
particle.color = color
particle.size = size
particle_cache[key] = particle
return particle
func _ready():
print("Flyweight pattern ready")
# main.gd
extends Node
var particle_factory: ParticleFactory
func _ready():
particle_factory = ParticleFactory.new()
add_child(particle_factory)
for i in range(10):
var p = particle_factory.get_particle("fire.png", Color(1, 0, 0, 1), 1.0)
p.position = Vector2(randf() * 100, randf() * 100)
p.velocity = Vector2(randf() * 10, randf() * 10)
print("Particle created at: ", p.position)
print("Flyweight pattern implemented")A Complete Game System in GDScript demonstrates game architecture with game managers, players, enemies, and scoring systems.
- GameManager: Manages game state
- Player: Player character
- Enemy: Enemy AI
- Score System: Tracking points
- Life System: Lives management
# Complete Game System in GDScript
# GameManager.gd
extends Node
class_name GameManager
static var instance: GameManager
var score: int = 0
var level: int = 1
var lives: int = 3
var game_state: String = "menu"
func _init():
if instance == null:
instance = self
else:
queue_free()
func _ready():
print("GameManager ready")
static func get_instance():
return instance
func start_game():
score = 0
level = 1
lives = 3
game_state = "playing"
print("Game started")
func game_over():
game_state = "game_over"
print("Game over! Score: ", score)
func add_score(points: int):
score += points
print("Score: ", score)
func lose_life():
lives -= 1
if lives <= 0:
game_over()
else:
print("Lives: ", lives)
# Player.gd
extends CharacterBody2D
var speed: int = 200
var jump_force: int = -400
func _ready():
print("Player ready")
func _physics_process(delta):
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
velocity.x = speed
if Input.is_action_pressed("ui_left"):
velocity.x = -speed
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = jump_force
velocity.y += 980 * delta
set_velocity(velocity)
move_and_slide()
var gm = GameManager.get_instance()
gm.add_score(1)
# Enemy.gd
extends CharacterBody2D
var health: int = 10
func _ready():
print("Enemy ready")
func take_damage(amount: int):
health -= amount
if health <= 0:
var gm = GameManager.get_instance()
gm.add_score(10)
queue_free()
print("Enemy destroyed")
# main.gd
extends Node
func _ready():
var gm = GameManager.get_instance()
gm.start_game()
var player = Player.new()
add_child(player)
var enemy = Enemy.new()
add_child(enemy)
print("Game system ready")
func _process(delta):
if Input.is_action_just_pressed("ui_escape"):
var gm = GameManager.get_instance()
gm.game_over()Quick Navigation
Related Topics
Ready for your next interview?
Take a real‑time mock interview and boost your confidence.
Start Mock Interview