Description
Describe the project you are working on
Godot internals.
Describe the problem or limitation you are having in your project
GDScript does not have a convenient way to express 'single character' values.
Ideally, it would have a literal type for them.
Single characters are most useful for their performance benefits, because they do not allocate memory (as opposed to String
).
Some existing APIs already use single characters as arguments or return types (int
type). It is currently inconvenient to call them (a
is unicode 97
):
string.get_slicec(97, 0)
(ref)input.is_key_label_pressed(97)
(ref)string.unicode_at(0) == 97
(ref)- Adjust functions that should already take single characters but are currently taking string, e.g. lpad:
string.lpadc(97)
- Changing input behavior would be better, but would break compatibility (5.0+)
String.chr(97)
(ref)- Unlikely to be useful in this configuration as you can just use
"a"
, but may be used transitively (through functions).
- Unlikely to be useful in this configuration as you can just use
Describe the feature / enhancement and how it helps to overcome the problem or limitation
There should be a single-character literal for GDScript. Since GDScript uses int
to describe characters in existing APIs, it would evaluate to int
(UTF-32).
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
I propose the following syntax (analogous to others using String prefixes):
# Type is int
var char := c"a" # Yields 97
var char := c'a' # Yields 97
# Edge cases
var char := c"'" # Valid, yields ' (39)
var char := c'"' # Valid, yields " (34)
var char := c"\"" # Valid, yields " (34)
# Careful: Some characters are 1 char in UTF-32, but multiple chars in UTF-8 / UTF-16.
var char := c"Ä" # Valid, yields Ä (196)
# Unlikely to be useful, could use var char := 0x2122 instead
var char := c"\u2122" # Valid, yields ™ (8482 / 0x2122)
# Erroneous Use
var chars := c"aa" # Error: Expected one character in single-character literal, found string of size 2.
var chars := c"" # Error: Expected one character in single-character literal, found string of size 0.
# Emoji are often encoded using multiple characters.
var chars := c"👨🏻🦱" # Error: Expected one character in single-character literal, found string of size 7.
# Examples (each equal)
string.get_slicec(97, 0)
string.get_slicec(c"a", 0)
input.is_key_label_pressed(Key.KEY_A)
input.is_key_label_pressed(65)
input.is_key_label_pressed(c"A")
string.unicode_at(0) == 97
string.unicode_at(0) == c"a"
# Note: This function doesn't exist (yet?)
string.lpad("a")
string.lpadc(97)
string.lpadc(c"a")
"a"
String.chr(97)
String.chr(c"a")
If this enhancement will not be used often, can it be worked around with a few lines of script?
It is possible to use unicode value literals:
var char := 97 # a
These can be looked up on sites like unicodelookup.com.
It is also possible to use GDScript:
var char := "a".unicode_at(0)
However, this is slow.
Is there a reason why this should be core and not an add-on in the asset library?
It's GDScript syntax.