xiaohongshu
xiaohongshu
godot-modernize-ui
Modernize Godot 3.x UI to 4.x best practices with theme extraction, responsive layouts, hiDPI support, and RichTextLabel BBCode patterns
Full skill instructions
Modernizes Godot 3.x UI scenes and scripts to Godot 4.x best practices.
Before (Godot 3.x):
# Hardcoded in each Control node
$Button.modulate = Color.red
$Button.get("custom_styles/normal").bg_color = Color.blue
$Label.add_font_override("font", preload("res://fonts/big.tres"))
After (Godot 4.x):
# Centralized in Theme resource
# Create: res://ui/themes/main_theme.tres
# Assign to root Control or project settings
Theme.tres structure:
Theme
├── Button/styles/normal (StyleBoxFlat)
├── Button/colors/font_color = Color(1, 1, 1, 1)
├── Button/fonts/font = preload("res://fonts/button_font.tres")
├── Label/fonts/font = preload("res://fonts/label_font.tres")
└── Panel/styles/panel (StyleBoxFlat)
Before:
# Manual positioning
$Panel.position = Vector2(100, 100)
$Panel.size = Vector2(400, 300)
After:
Control (root)
├── Layout Mode: Anchors
├── Anchor Left: 0.5, Anchor Top: 0.5
├── Anchor Right: 0.5, Anchor Bottom: 0.5
├── Grow Horizontal: Center
├── Grow Vertical: Center
└── Custom Minimum Size: (400, 300)
Anchor Presets for Common Layouts:
| Layout | Anchors | Offsets | Grow |
|---|---|---|---|
| Fullscreen | 0,0 to 1,1 | 0 all sides | Both |
| Top Bar | 0,0 to 1,0 | Bottom: 60 | Horizontal |
| Bottom Bar | 0,1 to 1,1 | Top: 60 | Horizontal |
| Center Panel | 0.5,0.5 | Size defined | Both |
| Left Sidebar | 0,0 to 0,1 | Right: 250 | Vertical |
| Right Sidebar | 1,0 to 1,1 | Left: 250 | Vertical |
Project Settings:
Display > Window > Stretch
├── Mode: canvas_items (or viewport)
├── Aspect: expand
└── Scale: 1.0 (auto-detected)
Script for Dynamic Scaling:
func _ready():
# Handle hiDPI on different displays
var screen_dpi = DisplayServer.screen_get_dpi()
if screen_dpi > 150:
get_tree().root.content_scale_factor = 2.0
Responsive Sizing:
@export var base_width: float = 1920.0
@export var base_height: float = 1080.0
func _on_viewport_size_changed():
var viewport_size = get_viewport().get_visible_rect().size
var scale_x = viewport_size.x / base_width
var scale_y = viewport_size.y / base_height
scale = Vector2(min(scale_x, scale_y), min(scale_x, scale_y))
Deprecated Godot 3.x:
[color=red]Warning[/color]
[url=https://example.com]Link[/url]
[img]res://icon.png[/img]
Godot 4.x BBCode:
[color=ff0000]Warning[/color]
[color=#ff0000]Hex Color[/color]
[url=https://example.com]Link[/url]
[img=64x64]res://icon.png[/img]
[font=res://fonts/custom.tres]Custom font[/font]
[wave amp=50 freq=5]Animated text[/wave]
[tornado radius=5 freq=2]Spinning text[/tornado]
[shake rate=5 level=10]Shaking text[/shake]
[fgcolor=00ff00 bgcolor=000000]Background[/fgcolor]
[outline_color=ffffff]Outlined[/outline_color]
Script Integration:
@onready var rich_label: RichTextLabel = $RichTextLabel
func append_colored_text(text: String, color: Color):
rich_label.append_text("[color=%s]%s[/color]" % [color.to_html(), text])
func append_url(text: String, url: String):
rich_label.append_text("[url=%s]%s[/url]" % [url, text])
func _on_meta_clicked(meta):
OS.shell_open(str(meta))
Custom Button with Built-in Theme:
@tool
class_name ModernButton
extends Button
@export var button_style: ButtonStyle = ButtonStyle.PRIMARY:
set(value):
button_style = value
_update_style()
enum ButtonStyle { PRIMARY, SECONDARY, DANGER }
func _ready():
_update_style()
func _update_style():
match button_style:
ButtonStyle.PRIMARY:
add_theme_color_override("font_color", Color(1, 1, 1))
add_theme_stylebox_override("normal", preload("res://ui/styles/primary_normal.tres"))
ButtonStyle.SECONDARY:
add_theme_color_override("font_color", Color(0.2, 0.2, 0.2))
add_theme_stylebox_override("normal", preload("res://ui/styles/secondary_normal.tres"))
ButtonStyle.DANGER:
add_theme_color_override("font_color", Color(1, 1, 1))
add_theme_stylebox_override("normal", preload("res://ui/styles/danger_normal.tres"))
CanvasLayer (UI Layer)
└── Control (Full Rect anchor, Fullscreen preset)
├── MarginContainer (padding)
│ ├── VBoxContainer (vertical layout)
│ │ ├── HBoxContainer (top bar)
│ │ │ ├── Label (title)
│ │ │ └── Button (close)
│ │ └── ScrollContainer (scrollable content)
│ │ └── VBoxContainer
│ │ └── (dynamic content)
│ └── HBoxContainer (bottom bar)
│ └── Button (action)
└── Panel (overlay/popup)
func _ready():
# Apply safe area insets for notched devices
var safe_area = DisplayServer.get_display_safe_area()
var window_size = DisplayServer.window_get_size()
$MarginContainer.add_theme_constant_override("margin_left", safe_area.position.x)
$MarginContainer.add_theme_constant_override("margin_top", safe_area.position.y)
$MarginContainer.add_theme_constant_override("margin_right",
window_size.x - safe_area.end.x)
$MarginContainer.add_theme_constant_override("margin_bottom",
window_size.y - safe_area.end.y)
Using RectPosition/RectSize directly:
# ❌ Bad - breaks with different resolutions
$Control.rect_position = Vector2(100, 100)
$Control.rect_size = Vector2(200, 150)
# ✅ Good - use anchors and layout containers
# Set anchors in editor or use custom_minimum_size
$Control.custom_minimum_size = Vector2(200, 150)
Hardcoding pixel values without scaling:
# ❌ Bad - too small on hiDPI
var padding = 10
# ✅ Good - scale with content_scale_factor
var padding = 10 * get_tree().root.content_scale_factor
Manual font size calculations:
# ❌ Bad - inconsistent across displays
label.add_theme_font_size_override("font_size", 24)
# ✅ Good - use theme with dynamic fonts
# Set in Theme resource with multiple sizes
Forgetting to handle window resize:
# ✅ Good - subscribe to resize signal
func _ready():
get_viewport().size_changed.connect(_on_viewport_size_changed)
_on_viewport_size_changed()
func _on_viewport_size_changed():
# Recalculate responsive layout
pass
| Task | Godot 3.x | Godot 4.x |
|---|---|---|
| Theme override | add_stylebox_override() | add_theme_stylebox_override() |
| Font override | add_font_override() | add_theme_font_override() |
| Color override | add_color_override() | add_theme_color_override() |
| Constant override | add_constant_override() | add_theme_constant_override() |
| Size override | rect_min_size | custom_minimum_size |
| Position | rect_position | position |
| Size | rect_size | size |
| Global position | rect_global_position | global_position |
| BBCode color | [color=red] | [color=ff0000] or [color=#ff0000] |
| BBCode image | [img]path[/img] | [img=widthxheight]path[/img] |
| hiDPI setting | ProjectSettings.display/window/dpi/allow_hidpi | Display > Window > Stretch > Mode |
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