Hello again. In the last lesson, you calculated game values such as coin totals and updated a variable with operators like += and -=. Those calculations worked, but Output showed labels and values on separate lines.
Now you will make clearer messages such as:
Nova has 39 coins.
That sentence combines fixed text with a changing value. You will learn two ways to build it in Luau:
- String concatenation with two dots,
.. - String interpolation with backticks and curly brackets
Both are useful in Roblox scripts for feedback, debugging, scores, shop messages, and event logs.
A message can contain fixed text and changing data
A string is text inside quotation marks:
local greeting = "Welcome!"
A variable can hold data that may change while the game runs:
local playerName = "Nova"
local coins = 39
Printing each piece separately works, but is not very readable:
print(playerName)
print(coins)
Instead, build one complete message that explains what the value means.

For example, we want Output to display:
Nova has 39 coins.
The player name and coin count are dynamic; the rest of the sentence is fixed text.
Concatenation: joining pieces with ..
Concatenation means joining strings together. In Luau, use two dots:
local firstWord = "Hello"
local secondWord = "world"
local message = firstWord .. secondWord
print(message)
Output:
Helloworld
Luau joined the text exactly as written. It does not add a space automatically.
Add the space inside one of your strings:
local firstWord = "Hello "
local secondWord = "world"
local message = firstWord .. secondWord
print(message)
Output:
Hello world
You can also place a space between the variables:
local firstWord = "Hello"
local secondWord = "world"
local message = firstWord .. " " .. secondWord
print(message)
The .. operator means “join these pieces of text.” It is not the same as +, which you used for numeric addition.
local coins = 39
print("Coins: " .. coins)
Output:
Coins: 39
Although coins is a number, Luau can convert it to text for concatenation. The coins variable itself is still a number, so you can continue doing math with it afterward.
local coins = 39
print("Coins: " .. coins)
print(type(coins))
Output:
Coins: 39
number
Roblox Luau Course - Episode 1: Fundamentals
Watch “Roblox Luau Course – Episode 1: Fundamentals” by Hoofer for a quick demonstration of concatenation. It reinforces why Luau uses two dots rather than the plus sign to join text.
In the section on strings, watch the concatenation demo. Focus on the moment where two dots join text and where additional text is added to an existing string.
Building a useful game message with concatenation
Return to the coin values from the previous lesson:
local playerName = "Nova"
local coins = 10
local questReward = 25
local potionCost = 8
coins += questReward
coins -= potionCost
At this point, coins contains 27. Use concatenation to report the result:
local playerName = "Nova"
local coins = 10
local questReward = 25
local potionCost = 8
coins += questReward
coins -= potionCost
local message = playerName .. " has " .. coins .. " coins after the quest."
print(message)
Output:
Nova has 27 coins after the quest.
Read the line gradually:
playerName .. " has " .. coins .. " coins after the quest."
Luau combines:
- the value stored in
playerName - the text
" has " - the current value stored in
coins - the final text
" coins after the quest."
Notice that the spaces are deliberately included inside " has " and " coins...".
Strings | Documentation - Roblox Creator Hub
Read the official Roblox Creator Hub guide to see the two main message-building techniques side by side: concatenation and interpolation.
In the “Combine strings” section, read the whole example sequence, especially the spacing explanation. Notice how the examples change from Helloworld! to Hello world!. Then read the full “String interpolation” section. Start at the interpolation introduction, then study the examples that insert variables and calculations. For now, ignore the final escape-rules example; the important idea is using backticks and curly brackets for values.
print() commas versus a complete string
You may also write:
local playerName = "Nova"
local coins = 27
print(playerName, "has", coins, "coins.")
Output will be readable:
Nova has 27 coins.
This works because print() accepts multiple values and displays spaces between them. It is convenient for a quick check in Output.
However, this is different from building a single message. If you want to store the message in a variable first, use concatenation or interpolation:
local playerName = "Nova"
local coins = 27
local message = playerName .. " has " .. coins .. " coins."
print(message)
A complete message variable is more useful later when you want to send text to a GUI label, a player notification, or another function.
Interpolation: insert values directly into text
Concatenation is reliable, but a long message can become visually busy because of all the .. operators.
String interpolation is a second way to build strings. Use:
- backticks
`around the entire string - curly brackets
{}around each value or expression to insert
local playerName = "Nova"
local coins = 27
local message = `{playerName} has {coins} coins.`
print(message)
Output:
Nova has 27 coins.
Compare the two styles:
-- Concatenation
local messageOne = playerName .. " has " .. coins .. " coins."
-- Interpolation
local messageTwo = `{playerName} has {coins} coins.`
Both produce the same text. Interpolation often makes a sentence easier to read because the text looks close to its final Output form.
A normal quotation mark string does not insert values from curly brackets:
local coins = 27
print("Coins: {coins}")
Output:
Coins: {coins}
That happens because quotation marks create an ordinary string. For interpolation, use backticks:
local coins = 27
print(`Coins: {coins}`)
Output:
Coins: 27
Interpolation can also evaluate a calculation inside the curly brackets:
local coins = 27
local bonus = 5
print(`Coins after bonus: {coins + bonus}`)
Output:
Coins after bonus: 32
The expression coins + bonus is calculated first, then its result is inserted into the message.
Type coercion | Documentation - Roblox Creator Hub
Read the short official explanation of why a number can appear naturally inside a concatenated message.
In the “Concatenation” section, read the examples beginning with number conversion in concatenation. The key point is that joining text with a number does not turn the original numeric variable permanently into a string.
Choose the clearer style
For this course, either approach is correct. Choose the one that helps you read the code accurately.
| Situation | A good choice |
|---|---|
| A short message or a simple text update | Concatenation or interpolation |
| A sentence containing several variables | Interpolation is often easier to scan |
| A quick temporary value check in Output | print() with comma-separated values can be convenient |
| A message you want to store and reuse | Concatenation or interpolation |
For example, this concatenation is correct, but it takes some attention to read:
local report = playerName .. " earned " .. questReward .. " coins and now has " .. coins .. "."
Interpolation presents the same report more like the final sentence:
local report = `{playerName} earned {questReward} coins and now has {coins}.`
Guided mini-project: quest receipt
Create or reuse your PracticeScript. This small project combines last lesson’s arithmetic with an Output message.
-- Show a player what happened to their coin total.
local playerName = "Nova"
local coins = 10
local questReward = 25
local potionCost = 8
coins += questReward
coins -= potionCost
local receipt = `{playerName}'s quest receipt:
Reward: {questReward} coins
Potion cost: {potionCost} coins
Final total: {coins} coins`
print(receipt)
Run the script. Output should show:
Nova's quest receipt:
Reward: 25 coins
Potion cost: 8 coins
Final total: 27 coins
This is one interpolated string, even though it appears on several lines in Output. The text is enclosed by one opening backtick before Nova and one closing backtick after coins.
Now change the values:
local questReward = 40
local potionCost = 12
Run it again. The message updates automatically because it uses the current variable values.
If you prefer concatenation, this one-line version produces an equivalent summary:
local receipt = playerName .. " finished with " .. coins .. " coins."
Common message-building mistakes
When a message looks wrong, check these patterns first.
One dot instead of two
A single dot is used for accessing a property, such as part.Name. It does not join text.
-- Incorrect for joining strings
local message = "Coins: " . coins
Use two dots:
local message = "Coins: " .. coins
Missing spaces
Luau does not insert spaces during concatenation:
local playerName = "Nova"
local coins = 27
print(playerName .. "has" .. coins .. "coins")
Output:
Novahas27coins
Put the intended spaces inside the text:
print(playerName .. " has " .. coins .. " coins")
Quoting a variable name
Quotation marks mean literal text, not “use this variable”:
local coins = 27
print("coins")
Output:
coins
Remove the quotation marks when you want the value:
print(coins)
Or include it in a message:
print(`Coins: {coins}`)
Using quotation marks for interpolation
This prints braces literally:
print("Coins: {coins}")
This inserts the value:
print(`Coins: {coins}`)
Key takeaways
A useful Output message combines explanatory text with your changing game values.
With concatenation, join pieces using two dots:
local message = playerName .. " has " .. coins .. " coins."
Include spaces yourself when concatenating.
With interpolation, use backticks and place values or calculations in curly brackets:
local message = `{playerName} has {coins} coins.`
Use commas in print() for a quick multi-value check, but use concatenation or interpolation when you need one complete reusable string.
Next, you will use Output not only to read successful messages, but also to understand a basic syntax error and fix the script that caused it.
Can't find a good explanation? Sign up and we'll make it for you
Sign up