Overview
In game development, situations frequently arise where you need to handle specific "coordinates" - enemy spawn points, bullet firing positions, effect display locations. Hardcoding these coordinates directly in scripts as Vector2(150, 300) means modifying code every time you need to fine-tune positions, which is very inefficient.
The Marker2D node solves this problem, making coordinate management dramatically easier.
This article explains the basic usage of Marker2D and how it improves development efficiency, with concrete examples.
What is Marker2D?
Marker2D is a very simple node that functions as just a "marker" in 2D space. It's almost identical to Node2D, but the key difference is that it's always displayed as a green cross icon in the editor.

This "visibility" is Marker2D's greatest strength. Instead of values in scripts, you can intuitively place and adjust coordinates with the same drag-and-drop feel as positioning objects in the editor.
Use Case 1: Managing Enemy Spawn Points
When you want to spawn enemies from various locations around a stage, Marker2D is perfect.
1. Place Marker2D Nodes
Add multiple Marker2D nodes to your main scene and position each where you want enemies to spawn. Name them clearly like "SpawnPoint1," "SpawnPoint2."
2. Group Them Together
Adding all placed Marker2D nodes to a group like "enemies_spawn_points" makes batch management convenient.
3. Get Coordinates from Script
Get the Marker2D coordinates from your script and instantiate enemies.
@export var enemy_scene: PackedScene
func _ready():
# Get all spawn points from the group
var spawn_points = get_tree().get_nodes_in_group('enemies_spawn_points')
if spawn_points.is_empty():
return
# Select a random spawn point
var random_spawn_point = spawn_points.pick_random()
# Instantiate enemy and place at Marker2D position
var enemy = enemy_scene.instantiate()
enemy.global_position = random_spawn_point.global_position
add_child(enemy)
Now, if you want to change enemy spawn positions, just move the cross icons in the editor - no code changes needed.
Use Case 2: Gun Muzzles and Effect Origins for Characters
When a player character shoots bullets, where should those bullets come from? The center of the character would look unnatural. This is where Marker2D shines.
1. Make Marker2D a Child Node
Open your player character scene (Player.tscn etc.) and add a Marker2D as a child of Sprite2D. Name it "Muzzle."
2. Adjust Position
Drag the "Muzzle" node in the editor to precisely position it at the gun muzzle on the character sprite.
3. Use from Script
Use the "Muzzle" global position when firing bullets.
# Player.gd
@onready var muzzle = $Sprite2D/Muzzle
@export var bullet_scene: PackedScene
func _process(delta):
if Input.is_action_just_pressed('shoot'):
var bullet = bullet_scene.instantiate()
# Use Muzzle's global position as firing point
bullet.global_position = muzzle.global_position
get_parent().add_child(bullet) # Add bullet to main scene
Even if the character rotates or moves, the Marker2D always maintains its position relative to the character's gun muzzle, so bullets always fire from the correct location. This applies to sword trail effects, dust effects at feet, or any coordinates that should follow a character.
Summary
Marker2D is a very powerful node precisely because of its simplicity. Separating coordinates from code and managing them "visibly" brings many benefits:
- Intuitive Position Adjustment: Artists and designers can adjust positions without touching code
- Improved Maintainability: No need to modify code for position changes
- Simplified Complex Hierarchies: Easy to get coordinates of specific character parts
If there are places in your project where coordinates are hardcoded, consider replacing them with Marker2D. Your development experience will become much more comfortable.