v1.8
Demo
Two Nodes:
RicherTextLabel
: Reduce effort needed to display state data and stylize it.RichTextAnimation
: For dialogue and cinematics, animates text in and out.https://github.com/user-attachments/assets/724558ad-f98e-40bb-8f30-dc413705c166
https://github.com/user-attachments/assets/caf703ad-44d3-43b0-b4f9-56f513ac572f
[deep_sky_blue;b]Bold blue[] and [orange;i]Italic orange[].
[32]Big text[] and [0.5]half text.[]
I'm :smile: with results. You get a :+1:.
We on the [sin]sinewave[] vibe.
Only $coins coins, $player.name? Travel to $location.get_name("west") for more coins.
1234 -> 1,234
to_rich_string()
if it can._italic_ -> [i]%s[] -> [i]italic[]
*cough* -> [i]*%s*[] -> [i]*cough*[]
."My [%s]colored string[] is easy." % [Color.DEEP_SKY_BLUE]
RichTextAnimation
for fading in and out.
[hold] [h]
Tag to pause animation until user. Wait...[h] Did you hear...[h] *Bang*!
[wait] [w]
Tag to wait in seconds. (Defaults to 1) Let me thing.[w] Hmm...[w]...[w]...
[pace] [p]
Set pace of animations. A slow talker [p=.1]talks like this...[p] While fast talkers [p=3]talk like this...
[!NOTE] If fonts aren't showing up in the font drop down, clear
font_cache
. The entire project is scanned for fonts to display in the dropdown.
Tag | Description | Example |
---|---|---|
! meta |
Executes an expression on the context node when pressed. If it starts with https:// it will load a browser. |
[!print("Hey!")] |
^ hint |
Expression that becomes a hint popup. | [^sword.get_hover_text()] |
dim |
Dims color by 33%. | |
lit |
Lightens color by 33%. | |
hue |
Shifts hue. 0 or 1 = no change. 0.5 = opposite end of spectrum. | [hue 0.25] |
beat |
Pulses in size and color. | |
curspull |
Pulls towards cursor. | [curspull pull=-1] |
cuss |
Animation to replace vowels with symbols. | What the [cuss]heck[]. |
heart |
Animated love bounce. Demonstrates changing font and using emojis. | |
jit |
||
jit2 |
Jittering nervous animation. | |
jump |
||
jump2 |
||
l33t |
Animation to replace letters with numbers. | |
off |
Ignore. Offsets. | |
rain |
Simulates rain. What for? I don't know. | |
secret |
Hidden unless mouse cursor is nearbye. | |
sin |
Might not work as sin is now built in? | |
sparkle |
Animation to sparkle character colors. Meant to be used with color tags. | |
sway |
Just skews back and forth. | |
uwu |
Converts all R's and L's to W's. | |
wack |
Randomly animates rotation and scale for a wacky look. | |
woo |
Animates between upper and lower case, creating a sarcastic tone. | |
pulse |
Built in | |
wave |
Built in | |
tornado |
Built in | |
shake |
Built in | |
fade |
Built in | |
rainbow |
Built in |
This node is meant for dialogue systems and cinematics.
Tag | Description | Arguments | Example | Self Closing |
---|---|---|---|---|
wait or w |
Waits a second. | Number of seconds. | Wait...[w=2] Did you hear...[w] *bang* |
✅ |
hold or h |
Holds until advance() is called. |
[h] |
✅ | |
pace or p |
Sets animation speed. | Scale. | [p=2.0]Fast talker.[p=0.2]Slow talker.[p]Normal speed. |
✅ |
skip |
Skips animation across selected items. | They call it [skip]The Neverending Forest[]. |
❌ | |
$ |
Runs an expression at this spot in the animation. | Expression. | Did you hear something...[$play_sound("gurgle")] |
✅ |
# |
Calls on_bookmark.emit() with the id when reached. |
Bookmark id. | He told me [#quote]the haunted forest[#endquote] wasn't so haunted.[#end] |
✅ |
Tag | Description | Arguments |
---|---|---|
back |
Characters bounce back in. | |
console |
(Broken) Simulates a computer console. | |
fader |
Characters alpha fades in. | |
fallin |
Characters are scaled down from a large size. | |
focus |
Characters slide in from all random directions. | |
fromcursor |
Characters slide in from cursor position. | |
growin |
Characters scale up from tiny. | |
offin |
Characters slide in from a slight offset to the left. | |
prickle |
Character alpha fades in but with a random offset. Requires a low fade_in_speed to look right. |
|
redact |
(Broken) Simulates redacted text being exposed. | |
wfc |
Characters start out as random 0's and 1's and eventually "collapse". |
If shortcut_expression = true
you can use the <code expression>
pattern instead of the [!code expression]
pattern.
Did you hear something...[wait][$play_sound("gurgle")] Uh oh![$player.fear = 100.0] Ahh...
Did you hear something...[wait]<play_sound("gurgle")> Uh oh!<player.fear = 100.0> Ahh...
If shortcut_bookmark = true
you can use the #bookmark
pattern instead of the [#bookmark]
pattern.
He told me#quote the haunted forest#endquote wasn't so haunted.#end
He told me[#quote] the haunted forest[#endquote] wasn't so haunted.[#end]
If a font has "emoji" (any case) in it's name, it will be used for emojis instead of the default font.
Emojis sometimes lag on some computers, which I get around by creating a custom FontVariant that uses the emoji font as a base and ThemeDB.fallback_font
as a fallback font. This seems to prevent lag spikes.
If an emoji tag is used :smile:
or [:smile:]
an emoji_font
metadata key will be created with the font.
Pipes |
post process strings.
There are two ways to use them.
{$score+2|pipe}
[|pipe]Text to be passed.[]
# These are all doing the same thing.
"We'll visit {location|capitalize} tomorrow."
"We'll visit {location.capitalize()} tomorrow."
"We'll visit [|capitalize]$location[] tomorrow."
# Arguments can also be passed as a space seperated list:
# These are all the same.
"Day of week: {time.day_of_week|substr 0 3}"
"Day of week: {time.day_of_week.substr(0, 3)}"
"Day of week: [|substr 0 3]$time.day_of_week[]"
The real power is in adding your own. Pipes try to use a method inside the context node.
func cap(x):
return x.capitalize()
func oooify(x):
if cow_mode == CowMode.ACTIVATED:
return x.replace("o", "[sin]ooo[/sin]").replace("O", "[sin]OOO[/sin]")
else:
return x
# Pipes can be chained.
# Location name gets capitalized, and all it's O's stretched out.
"We'll visit {location|cap|ooify}."
# Or we may want to change entire the dialogue based on state data.
[|ooify]Wow those cows were mooing.[]
Or maybe you want to stylize content based on the characters mood.
# If returning BBCode, it has to be old fashioned style.
func mood(s: String, npc_id: String):
match npcs[npc_id].emotion:
Emotion.HAPPY: return "[color=yellow]%s[/color]" % s
Emotion.SAD: return "[color=aqua]%s[/color]" % s
Emotion.ANGRY: return "[color=red]%s[/color]" % s
_: return s
"Mary: [i;|mood mary]What I'm saying will be colored based on my mood.[]"
"John: [i;|mood john]What I'm saying will be colored based on my mood.[]"
[!NOTE] The BBCode
[|pipe]
tag function must return old fashioned BBCode. It doesn't support the labels features like Markdown replacement. Eventually I'll fix that.
pulse
wave
tornado
shake
fade
rainbow
PROPERTY_HINT_DICTIONARY_TYPE
FontHelper
erroring on built projects.set_bbcode
to queue for the end of the frame.STACK_STATE
object.font_cache
and font functions to FontHelper
._random
and set as meta property since it's rarely used.color
property not being settable from script.horizontal_alignment
property.outline_color
to set the default outline color.CUSTOM
to apply default outline_color
to all text.CUSTOM_DARKEN
to apply outline_color
to non colored text, but darken outlines otherwise.CUSTOM_LIGHTEN
to apply outline_color
to non colored text, but lighten outlines otherwise.OutlineStyle
to OutlineMode
to match property outline_mode
.OutlineMode.OFF
not turning off outlines.[!]
meta tag which calls an expression when pressed.[^]
hint tag which calls an expression to display in a popup when hovered.hint
tags which now use the RicherTextLabel
.meta_auto_https
which opens urls in a browser.fit_width
which will set custom_minimum_size.x = get_content_width()
.\n
better now.alignment
since original RichTextLabel
now has horizontal_alignment
.RichTextEffects
not working on built projects.@export
to _get_property_list
.context_nice_*
properties to context_rich_*
.RicherTextLabel
from RichTextLabel2
to prevent future problems.to_rich_string()
instead of to_string_nice()
.advance()
only skips to next [wait]
[hold]
or `[$expression] instead of all triggers.advance()
returns true if still playing.fit_content
not working. Now override_fitContent
really forces custom_minimum_size
.set_bbcode
being called many times in a row.|
. See README.autostyle_numbers_pad_decimals
Enable?autostyle_numbers_decimals
Number of decimals.[curspull]
shows how to animate based on cursor position.[wack]
randomly scales and rotates characters.[beat]
pulses it's scale and color every second.[secret]
hides characters unless cursor is nearbye.[fromcursor]
which transitions letters to and from cursor position.[growin]
scales characters in, overshooting, then scaling to proper size.[offin]
moves characters in from an left offset.[cuss]
[heart]
[rain]
[sway]
[uwu]
.[] {} or <>
.context_state: Dictionary
for passing additional arguments available in expressions.{}
pattern for including complex expressions. Example: {lerp(score, 2, 0.2) * PI}
.autostyle_emojis
to disable emoji detection.[[]
pattern instead of \[]
pattern.emoji_font
not loading.emoji_scale
not affecting emojis.ctc_offset
.ctc_on_wait
to control whether ctc is visible while waiting for timer.ctc_on_finish
to control whether ctc is visible when animation finishes.default_wait_time
for the [wait]
and [w]
tags.signal_quotes
and signals for when a "quote" starts and stops.signal_stars
and signals for when stars start and stop. [wait][w][hold][h][pace][p][skip]
.