Quick answer: RichTextLabel → bbcode_enabled = true. Set text with the tags. [lb] and [rb] escape literal brackets when you don’t want them parsed. Setting bbcode_enabled after assigning text doesn’t retroactively re-parse — set the flag first.
Game text uses [b]Damage:[/b] 50 for emphasis. RichTextLabel renders it literally with the brackets visible. The bbcode flag is off; turn it on and rewrite text after.
The Symptom
RichTextLabel renders BBCode tags as plain characters. [b]bold[/b] shows as [b]bold[/b] instead of bold. Color, size, and other tags equally inert.
The Fix
Step 1: Enable BBCode. Inspector → RichTextLabel → bbcode_enabled. Tick on. The text re-parses.
Step 2: Set text with tags.
extends RichTextLabel
func _ready() -> void:
bbcode_enabled = true
text = "[b]Damage:[/b] [color=red]50[/color]"
Order matters: set bbcode_enabled before text. Setting after means the parser sees the property change but doesn’t re-tokenize until the next text assignment.
Step 3: Escape stray brackets. User-supplied text containing brackets breaks parsing.
func set_safe_text(user_input: String) -> void:
var safe = user_input.replace("[", "[lb]").replace("]", "[rb]")
text = "[b]" + safe + "[/b]"
This prevents an attacker (or a user typing brackets into a chat) from injecting their own tags — including ones that load images.
append_text vs text
For incremental updates (a typewriter effect, an event log), use append_text:
append_text("[color=yellow]Quest started[/color]\n")
append_text("Find the [b]ancient key[/b].\n")
append_text appends without re-parsing earlier content. Faster for streaming logs than rebuilding the full text each line.
Custom Effects
Godot supports custom BBCode effects via RichTextEffect resources. Common pre-built effects: shake, wave, tornado. Add to install_effect array on the label, then use:
text = "[shake rate=20.0 level=5][rainbow]CRITICAL HIT[/rainbow][/shake]"
Verifying
Run the scene. Bold text should be bold. Colored text colored. If still raw, the flag is off; if mostly working but stray brackets break the layout, escape user input.
“Flag on, then text. Escape user input. append_text for streams.”
Related Issues
For Label autosizing, see Control anchors. For UI font issues, see font size theme.
Enable, set, escape. The text comes alive.