Luau and C# Comparison

Roblox uses the Luau programming language. The following code samples and tables indicate some of the differences between syntaxes for C# and Luau.

Line Endings

You don't need semicolons in Luau, but they don't break the syntax.

Reserved Keywords

The following table has Luau's reserved keywords mapped to their C# equivalent. Note it doesn't show all C# keywords.

Lua C#
and
break break
do do
if if
else else
elseif else if
then
end
true true
false false
for for / foreach
function
in in
local
nil null
not
or
repeat
return return
until
while while

Comments

Comments in Luau

1-- Single line comment
2
3--[[ Resulting output:
4 Block comment
5--]]
6
Comments in C#

1// Single line comment
2
3/*
4 Block comment
5*/
6

Strings

Strings in Luau

1-- Multi-line string
2[[This is a string that,
3when printed, appears
4on multiple lines]]
5
6-- Concatenation
7s1 = "This is a string "
8s2 = "made with two parts."
9endString = s1 .. s2
10
Strings in C#

1// Multi-line string
2"This is a string that,\nwhen printed, appears\n on multiple lines."
3
4string multiLineString = @"This is a string that,
5when printed, appears
6on multiple lines";
7
8// Concatenation
9string s1 = "This is a string ";
10string s2 = "made with two parts.";
11string endString = s1 + s2;
12

Tables

To learn more about tables in Luau, see Tables.

Dictionary Tables

You can use tables in Luau as dictionaries just like in C#.

Dictionary tables in Luau

1local dictionary = {
2 val1 = "this",
3 val2 = "is"
4}
5
6print(dictionary.val1) -- Outputs 'this'
7print(dictionary["val1"]) -- Outputs 'this'
8
9dictionary.val1 = nil -- Removes 'val1' from table
10dictionary["val3"] = "a dictionary" -- Overwrites 'val3' or sets new key-value pair
11
Dictionary tables in C#

1Dictionary dictionary = new Dictionary()
2{
3 { "val1", "this" },
4 { "val2", "is" }
5};
6
7Console.WriteLine(dictionary["val1"]); // Outputs 'this'
8dictionary.Remove("val1"); // Removes 'val1' from dictionary
9
10dictionary["val3"] = "a dictionary"; // Overwrites 'val3' or sets new key-value pair
11dictionary.Add("val3", "a dictionary"); // Creates a new key-value pair
12

Numerically-Indexed Tables

You can use tables in Luau as arrays just like in C#. Indices start at 1 in Luau and 0 in C#.

Numerically-indexed tables in Luau

1local npcAttributes = {"strong", "intelligent"}
2
3print(npcAttributes[1]) -- Outputs 'strong'
4print(#npcAttributes) -- Outputs the size of the list
5
6-- Append to the list
7table.insert(npcAttributes, "humble")
8-- Another way...
9npcAttributes[#npcAttributes+1] = "humble"
10
11-- Insert at the beginning of the list
12table.insert(npcAttributes, 1, "brave")
13
14-- Remove item at a given index
15table.remove(npcAttributes, 3)
16
Numerically-indexed tables in C#

1List npcAttributes = new List{"strong", "intelligent"};
2
3Console.WriteLine(npcAttributes[0]); // Outputs 'strong'
4Console.WriteLine(npcAttributes.Count); // Outputs the size of the list
5
6// Append to the list
7npcAttributes.Add("humble");
8// Another way...
9npcAttributes.Insert(npcAttributes.Count, "humble");
10
11// Insert at the beginning of the list
12npcAttributes.Insert(0, "brave");
13
14// Remove item at a given index
15npcAttributes.Remove(2);
16

Operators

Conditional Operators

Operator Lua C#
Equal To == ==
Greater Than > >
Less Than < <
Greater Than or Equal To >= >=
Less Than or Equal To <= <=
Not Equal To ~= !=
And and &&
Or or ||

Arithmetic Operators

Lua C#
Addition + +
Subtraction - -
Multiplication * *
Division / /
Modulus % %
Exponentiation ^ **

Variables

In Luau, variables don't specify their type when you declare them. Luau variables don't have access modifiers, although you may prefix "private" variables with an underscore for readability.

Variables in Luau

1local stringVariable = "value"
2
3-- "Public" declaration
4local variableName
5
6-- "Private" declaration - parsed the same way
7local _variableName
8
Variables in C#

1string stringVariable = "value";
2
3// Public declaration
4public string variableName
5
6// Private declaration
7string variableName;
8

Scope

In Luau, you can write variables and logic in a tighter scope than their function or class by nesting the logic within do and end keywords, similar to curly brackets {} in C#. For more details on scope in Luau, please see the Scope.

Scoping in Luau

1local example = "Example text"
2
3do
4 local example = example .. " changed!"
5 print(example) -- Outputs 'Example text changed!'
6end
7
8print(example) -- Outputs 'Example text'
9
Scoping in C#

1string example = "Example text";
2
3{
4 example += " changed!";
5 Console.WriteLine(example); // Outputs 'Example text changed!'
6}
7
8
9Console.WriteLine(example); // Outputs 'Example text'
10

Conditional Statements

Conditional Statements in Luau

1-- One condition
2if boolExpression then
3 doSomething()
4end
5
6-- Multiple conditions
7if not boolExpression then
8 doSomething()
9elseif otherBoolExpression then
10 doSomething()
11else
12 doSomething()
13end
14
Conditional Statements in C#

1// One condition
2if (boolExpression) {
3 doSomething();
4}
5
6
7// Multiple conditions
8if (!boolExpression) {
9 doSomething();
10}
11else if (otherBoolExpression) {
12 doSomething();
13}
14else {
15 doSomething();
16}
17

Conditional Operator

Luau doesn't offer a direct equivalent to the C# conditional operator, a ? b : c. However, the Luau idiom a and b or c offers a close approximation, provided b isn't false or nil.

Approximate of the conditional operator in Luau

1local max = x > y and x or y
2
Conditional operator in C#

1int max = (x > y) ? x : y;
2

Loops

To learn more about loops in Luau, see Control Structures.

While and Repeat Loops

While and Repeat loops in Luau

1while boolExpression do
2 doSomething()
3end
4
5repeat
6 doSomething()
7until not boolExpression
8
While and Repeat loops in C#

1while (boolExpression) {
2 doSomething();
3}
4
5do {
6 doSomething();
7} while (boolExpression)
8

For Loops

Generic For loops in Luau

1-- Forward loop
2for i = 1, 10 do
3 doSomething()
4end
5
6-- Reverse loop
7for i = 10, 1, -1 do
8 doSomething()
9end
10
Generic For loops in C#

1// Forward loop
2for (int i = 1; i <= 10; i++) {
3 doSomething();
4}
5
6// Reverse loop
7for (int i = 10; i >= 1; i--) {
8 doSomething();
9}
10
For loops over tables in Luau

1local abcList = {"a", "b", "c"}
2
3for i, v in ipairs(abcList) do
4 print(v)
5end
6
7local abcDictionary = { a=1, b=2, c=3 }
8
9for k, v in pairs(abcDictionary) do
10 print(k, v)
11end
12
For loops over lists in C#

1List<string> abcList = new List<string>{"a", "b", "c"};
2
3foreach (string v in abcList) {
4 Console.WriteLine(v);
5}
6
7Dictionary<string, int> abcDictionary = new Dictionary<string, int>
8{ {"a", 1}, {"b", 2}, {"c", 3} };
9
10
11foreach (KeyValuePair<string, int> entry in abcDictionary) {
12 Console.WriteLine(entry.Key + " " + entry.Value);
13}
14

Functions

To learn more about functions in Luau, see Functions.

Generic Functions

Generic functions in Luau

1-- Generic function
2local function increment(number)
3 return number + 1
4end
5
Generic functions in C#

1// Generic function
2int increment(int number) {
3 return number + 1;
4}
5

Variable Argument Number

Variable Argument Number in Luau

1-- Variable argument number
2local function variableArguments(...)
3 print(...)
4end
5
Variable Argument Number in C#

1// Variable argument number
2void variableArguments(params string[] inventoryItems) {
3 for (item in inventoryItems) {
4 Console.WriteLine(item);
5 }
6}
7

Named Arguments

Named Arguments in Luau

1-- Named arguments
2local function namedArguments(args)
3 return args.name .. "'s birthday: " .. args.dob
4end
5
6namedArguments{name="Bob", dob="4/1/2000"}
7
Named Arguments in C#

1// Named arguments
2string namedArguments(string name, string dob) {
3 return name + "'s birthday: " + dob;
4}
5
6namedArguments(name: "Bob", dob: "4/1/2000");
7

Try/Catch Structures

Try/Catch Structures in Luau

1local function fireWeapon()
2 if not weaponEquipped then
3 error("No weapon equipped!")
4 end
5 -- Proceed...
6end
7
8local success, errorMessage = pcall(fireWeapon)
9if not success then
10 print(errorMessage)
11end
12
Try/Catch Structures in C#

1void fireWeapon() {
2 if (!weaponEquipped) {
3 // Use a user-defined exception
4 throw new InvalidWeaponException("No weapon equipped!");
5 }
6 // Proceed...
7}
8
9try {
10 fireWeapon();
11} catch (InvalidWeaponException ex) {
12 // An error was raised
13}
14