Skip to content

Why can't I add a String and an int?

Godot 4.x

You’ll see something like one of these in the Debugger panel. The function and property names will be your own:

_on_coin_collected(): Invalid operands 'String' and 'int' in operator '+'.
_on_coin_collected(): Invalid assignment of property or key 'text' with value of type 'int' on a base object of type 'Label'.
What’s happeningGo to
The error mentions operator '+'Gluing text and a number with plus
The error mentions Invalid assignment of property or key 'text'Assigning a number straight to a text property
It works, but you want padding, decimals or a nicer layoutFormatting the number

The script is on HUD and updates ScoreLabel every time a coin is collected.

  • HUDCanvasLayerhas scriptscript attached here
    • ScoreLabelLabelshows the score

+ on a String means “join two Strings”. score is an int, not a String, so Godot has nothing to join and stops:

hud.gd
extends CanvasLayer
@onready var score_label: Label = $ScoreLabel
var score := 0
func _on_coin_collected() -> void:
score += 1
score_label.text = "Score: " + score
score_label.text = "Score: " + str(score)

Fix: str() turns anything into a String. The C# version works as written because string interpolation ($"...") converts the number for you.

Assigning a number straight to a text property

Section titled “Assigning a number straight to a text property”

text on a Label only accepts a String. Handing it an int fails the same way, just with a longer error:

hud.gd
func _on_coin_collected() -> void:
score += 1
score_label.text = score
score_label.text = str(score)

The same goes for Button.text, LineEdit.text and RichTextLabel.text. Anything that isn’t already a String needs str() first.

When you want more than a plain number, use the % operator or format() instead of str(). %d is a whole number, %.1f is a float with one decimal, and %03d pads with zeros to three digits:

hud.gd
score_label.text = "Score: %d" % score
score_label.text = "Score: %03d" % score
time_label.text = "%.1f s" % time_left
score_label.text = "Score: {0}".format([score])

Hover the variable in the script editor to see its type, or drop print(typeof(score)) on the line above the failing one and run again. 4 means String, 2 means int, 3 means float. Whatever isn’t a String needs str() before it meets one. If the variable has no type, give it one (var score := 0 or var score: int = 0) so the editor can warn you before you run.