xiaohongshu
xiaohongshu
godot-modernize-gdscript
Modernizes GDScript 1.0 (Godot 3.x) code to GDScript 2.0 (Godot 4.x) syntax. Converts yield to await, onready to @onready, export to @export, setget to property syntax, and adds optional static typing. Essential for Godot 3.x to 4.x migration projects.
Full skill instructions
Converts GDScript 1.0 (Godot 3.x) patterns to GDScript 2.0 (Godot 4.x) syntax.
This skill performs five key modernizations:
| GDScript 1.0 | GDScript 2.0 | Pattern |
|---|---|---|
yield(object, "signal") | await object.signal | Async operations |
onready var | @onready var | Node references |
export var | @export var | Inspector variables |
var x setget set_x, get_x | Property syntax | Getters/setters |
var health = 100 | var health: int = 100 | Static typing |
When this skill is invoked, IMMEDIATELY execute:
ls project.godot 2>/dev/null && echo "✓ Godot project detected" || echo "✗ Not a Godot project"
If NOT a Godot project:
If IS a Godot project:
# Check for Godot 3.x patterns
echo "=== Detecting GDScript 1.0 Patterns ==="
echo "yield statements:"
grep -rn "yield(" --include="*.gd" . | wc -l
echo "onready declarations:"
grep -rn "^onready var" --include="*.gd" . | wc -l
echo "export declarations:"
grep -rn "^export var\|^export(int)\|^export(float)" --include="*.gd" . | wc -l
echo "setget properties:"
grep -rn "setget" --include="*.gd" . | wc -l
echo "untyped variables:"
grep -rn "^var [a-z]" --include="*.gd" . | grep -v ":" | wc -l
Show the user:
=== GDScript 2.0 Modernization Analysis ===
Project: [project name]
Current: GDScript 1.0 (Godot 3.x style)
Patterns to modernize:
- yield statements: X
- onready variables: X
- export variables: X
- setget properties: X
- untyped variables: X
Total: X modernizations needed
Modernization includes:
✓ yield → await conversion
✓ onready → @onready
✓ export → @export
✓ setget → property syntax
✓ Optional static typing
✓ Git commit per file
✓ Backup before changes
Would you like me to:
1. Modernize all files (recommended)
2. Show detailed breakdown first
3. Select specific conversions
4. Cancel
# Find all .gd files
find . -name "*.gd" -type f | sort > /tmp/gdscript_files.txt
wc -l /tmp/gdscript_files.txt
echo "files found"
For each .gd file, detect patterns:
# Analyze patterns per file
for file in $(cat /tmp/gdscript_files.txt); do
echo "=== $file ==="
grep -c "yield(" "$file" 2>/dev/null || echo 0
grep -c "^onready var" "$file" 2>/dev/null || echo 0
grep -c "^export" "$file" 2>/dev/null || echo 0
grep -c "setget" "$file" 2>/dev/null || echo 0
done
Modernization Plan:
===================
1. yield → await conversions (X files)
2. onready → @onready (X files)
3. export → @export (X files)
4. setget → properties (X files)
5. Static typing (X files)
Total files to modify: X
Estimated time: Auto (user doesn't wait)
Backup created: YES (git tag)
Rollback available: YES
Detection:
grep -rn "yield(" --include="*.gd" .
Common Patterns:
| Old Pattern | New Pattern |
|---|---|
yield(get_tree().create_timer(1.0), "timeout") | await get_tree().create_timer(1.0).timeout |
yield(timer, "timeout") | await timer.timeout |
yield(animation_player, "animation_finished") | await animation_player.animation_finished |
yield(get_tree(), "idle_frame") | await get_tree().process_frame |
Transformation Process:
Extract yield statement
# Before
yield(get_tree().create_timer(2.0), "timeout")
Convert to await
# After
await get_tree().create_timer(2.0).timeout
Handle variable assignment
# Before
var result = yield(async_function(), "completed")
# After
var result = await async_function()
Implementation:
# Pseudo-code for replacement
def convert_yield_to_await(line):
# Pattern: yield(object, "signal_name")
# Convert to: await object.signal_name
import re
pattern = r'yield\(([^,]+),\s*"([^"]+)"\)'
replacement = r'await \1.\2'
return re.sub(pattern, replacement, line)
Detection:
grep -rn "^onready var" --include="*.gd" .
Transformation:
# Before
onready var player = $Player
onready var health_bar = $UI/HealthBar
# After
@onready var player: Node = $Player
@onready var health_bar: ProgressBar = $UI/HealthBar
Process:
onready with @onreadyType Inference (Optional):
# If $Player is CharacterBody2D in scene
@onready var player: CharacterBody2D = $Player
# If $Timer is Timer node
@onready var _timer: Timer = $Timer
Detection:
grep -rn "^export" --include="*.gd" .
Transformation:
# Before
export var speed = 200
export(int) var max_health = 100
export(float) var jump_force = 500.0
export(String) var character_name = "Player"
export(NodePath) var target_path
# After
@export var speed: float = 200.0
@export var max_health: int = 100
@export var jump_force: float = 500.0
@export var character_name: String = "Player"
@export var target_path: NodePath
Export Types Mapping:
| Old Export | New Export | Type |
|---|---|---|
export(int) | @export var x: int | Integer |
export(float) | @export var x: float | Float |
export(String) | @export var x: String | String |
export(bool) | @export var x: bool | Boolean |
export(Color) | @export var x: Color | Color |
export(Vector2) | @export var x: Vector2 | Vector2 |
export(Vector3) | @export var x: Vector3 | Vector3 |
export(NodePath) | @export var x: NodePath | NodePath |
export var | @export var x: Type | Inferred |
Detection:
grep -rn "setget" --include="*.gd" .
Transformation:
# Before (GDScript 1.0)
var health = 100 setget set_health, get_health
func set_health(value):
health = clamp(value, 0, max_health)
health_changed.emit(health)
func get_health():
return health
# After (GDScript 2.0)
var health: int = 100:
set(value):
health = clamp(value, 0, max_health)
health_changed.emit(health)
get:
return health
Process:
setget from variable declarationset(value): and get: syntaxComplex Example:
# Before
var score = 0 setget set_score
func set_score(value):
score = max(0, value)
update_ui()
# After
var score: int = 0:
set(value):
score = max(0, value)
update_ui()
Detection:
grep -rn "^var [a-z_]* = " --include="*.gd" . | grep -v ":"
Type Inference:
| Value | Inferred Type |
|---|---|
= 100 | int |
= 3.14 | float |
= "text" | String |
= true | bool |
= Vector2(x, y) | Vector2 |
= $Node | Node type from scene |
Transformation:
# Before
var health = 100
var speed = 200.5
var name = "Player"
var active = true
var position = Vector2.ZERO
# After
var health: int = 100
var speed: float = 200.5
var name: String = "Player"
var active: bool = true
var position: Vector2 = Vector2.ZERO
# Create backup tag
git tag gdscript1-baseline-$(date +%Y%m%d-%H%M%S)
# Stage any current changes
git add .
git commit -m "Baseline: Pre-GDScript 2.0 modernization" || echo "No changes to commit"
For each .gd file:
# Process file
python3 << 'EOF'
import re
def modernize_gdscript(content):
# Conversion 1: yield → await
content = re.sub(
r'yield\(([^,]+),\s*"([^"]+)"\)',
r'await \1.\2',
content
)
# Conversion 2: onready → @onready
content = re.sub(
r'^onready var',
'@onready var',
content,
flags=re.MULTILINE
)
# Conversion 3: export → @export (simple)
content = re.sub(
r'^export var',
'@export var',
content,
flags=re.MULTILINE
)
return content
# Read, process, write
with open("script.gd", "r") as f:
content = f.read()
new_content = modernize_gdscript(content)
with open("script.gd", "w") as f:
f.write(new_content)
EOF
# After each file modification
git add "$file"
git commit -m "Modernize: $file to GDScript 2.0
- Converted yield to await
- Updated onready to @onready
- Migrated export to @export
- Applied static typing"
# Validate syntax
godot --headless --quit-after 2 project.godot 2>&1 | grep -i "error" && {
echo "Syntax error detected in $file"
git reset --hard HEAD~1
echo "Reverted changes to $file"
}
# Check all modified files for syntax errors
for file in $(git diff --name-only HEAD~10..HEAD | grep "\.gd$"); do
echo "Checking $file..."
# Basic syntax check
gdscript_tool --check "$file" 2>/dev/null || echo "Manual review needed: $file"
done
# Verify no old patterns remain
echo "Checking for remaining GDScript 1.0 patterns..."
echo "yield statements remaining:"
grep -rn "yield(" --include="*.gd" . | wc -l
echo "onready remaining:"
grep -rn "^onready var" --include="*.gd" . | wc -l
echo "export remaining:"
grep -rn "^export var\|^export(" --include="*.gd" . | wc -l
# Open project in Godot to verify
godot --editor project.godot &
sleep 5
# Check for errors
# (User should visually verify no red errors in Output panel)
Before (GDScript 1.0):
extends CharacterBody2D
export var speed = 200
export(int) var health = 100
onready var sprite = $Sprite
onready var animation = $AnimationPlayer
var damage = 10 setget set_damage
func set_damage(value):
damage = clamp(value, 0, 100)
func _ready():
yield(get_tree().create_timer(1.0), "timeout")
start_game()
func take_damage(amount):
health -= amount
if health <= 0:
yield(play_death_animation(), "completed")
queue_free()
func play_death_animation():
animation.play("death")
yield(animation, "animation_finished")
After (GDScript 2.0):
extends CharacterBody2D
@export var speed: float = 200.0
@export var health: int = 100
@onready var sprite: Sprite2D = $Sprite
@onready var animation: AnimationPlayer = $AnimationPlayer
var damage: int = 10:
set(value):
damage = clamp(value, 0, 100)
func _ready():
await get_tree().create_timer(1.0).timeout
start_game()
func take_damage(amount: int) -> void:
health -= amount
if health <= 0:
await play_death_animation()
queue_free()
func play_death_animation() -> void:
animation.play("death")
await animation.animation_finished
Before:
func _ready():
button.connect("pressed", self, "_on_button_pressed")
timer.connect("timeout", self, "_on_timeout")
func _on_button_pressed():
pass
func _on_timeout():
pass
After:
func _ready():
button.pressed.connect(_on_button_pressed)
timer.timeout.connect(_on_timeout)
func _on_button_pressed() -> void:
pass
func _on_timeout() -> void:
pass
Modernization complete when:
yield( statements remain (converted to await)onready var remain (converted to @onready)export var remain (converted to @export)setget remain (converted to property syntax)Problem:
var result = yield(load_data(), "completed")
Solution:
var result = await load_data()
Problem:
func process():
yield(do_step_1(), "completed")
yield(do_step_2(), "completed")
Solution:
func process() -> void:
await do_step_1()
await do_step_2()
Problem:
var score = 0 setget , get_score # Only getter
Solution:
var score: int = 0:
get:
return score
If modernization causes issues:
# Find baseline tag
git tag | grep "gdscript1-baseline"
# Reset to pre-modernization state
git reset --hard <baseline-tag>
# Or revert specific commits
git revert <modernization-commit-hash>
Use before:
godot-refactor - Modernize syntax first, then refactor architecturegodot-migrate-tilemap - Update code before TileMap migrationUse after:
godot-organize-project - Organize files firstThis skill automates the tedious parts of GDScript 1.0 → 2.0 migration while preserving exact functionality.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience