Luau Recap: October 2020

Luau didn’t replace anything from past Lua in Roblox. The tutorials should still help the same and there will likely be a surge of new tutorials to help if there was change.


I read the entire list. I won’t pretend I fully understood all of it (yet) however that gives me goals to move towards. Just wanted to note that I did indeed read it and I’m sure there are many that will, even if most won’t.

I’m actually very glad there will be a type checker but I would think that would be a very extensive project.

I don’t know if you have seen this one on github for Lua but it’s a good idea of project depth you’re facing:

There’s so many extra functions specific to Roblox too and all the ways those apply.

Good luck!


Luau is fully released, the type checker is still in beta, and when it is released I bet it will still have a toggle option.


I meant as in that the beta features of Luau aren’t replacing anything in currently and widely used Luau.

Perhaps I meant to say Luau’s beta features than Luau. It is my mistake.

I honestly don’t use type checking nor have I looked thoroughly at Luau’s beta features so what I mean to say is, the experience from Roblox Lua in the past and Luau now won’t change anything dramatically right now in how we’ll code.

1 Like

This question gets asked often, and the answer is always the same:

You can use as many or as few of the new features as you’d like. Some of them may make you more productive in the long run, but 100% of the code you know how to write today will continue to work, so if you just want to use what you know today - you don’t need to learn anything else.


bruh -> makes no sense, because “=” means equals and => <= makes more sense cause it means equals to or larger etc… ‘-’ more like a minus

Awesome! Cant wait to learn more about luau :heart_eyes:

1 thing tho, can luau be used in a lua script, like a mix?

1 Like

Luau is a fork of Lua with extra features added.


I’m assuming its to prevent typos and confusion as >= and <= are used in comparisons, and presumably to make typed luau more in line with other typed languages.


I tried making a random prime finder script I wrote in 5 minutes parallel. Well, I guess it works as the resource monitor shows 6 threads more than without running it parallel, but it is definitely in its early stages.

This might not be related, but it seems my average CPU usage in studio can never go over 25% , which makes testing performance benefits really hard.


It is an arrow. How do you write arrows in normal text?

1 Like

Any changes on the handling of nullable types? My main concern is whether or not values that are specifically tested to be non-nil will be treated as such in the type checker.


function SomeFunction(someArg: string?)
    if (someArg ~= nil) then
        -- This will complain about mismatch between string and (string | nil)
        -- despite the nil check just above.

        -- Will the type checker ever be conscious about checks like this?

function SomeOtherFunction(someArg: string)
    -- Do something with the non-nullable string here.

Also, what about how modules load types? I always thought of a require where the target module exports types to be akin to an include or using statement, but from what I can tell on the Luau website, referencing those types is only possible via:

local Module = require(...)
local Var: Module.ExportedType = ...

Are there any plans to lift the requirement of prepending Module. onto the type expression?


Right now you can use if someArg then, which will refine the type of someArg within the if block to remove the nil variant. We aren’t doing this for comparisons or for and/or chains, which is planned but not for v0 (so will likely only happen early next year).

No changes in this regard yet; we will need to dive into some use cases for this to make sure having a separate way to import types is valuable here.

Not at the moment, similarly how require always puts the results into the resulting variable’s “scope” (short of using getfenv).


For parallel luau, will the new method, ConnectParallel get its camelCase name connectParallel?

I’m asking because people still use the deprecated method connect instead of Connect and they might want to be consistent.

I’m guessing they wouldn’t add features to cater to deprecated use cases.


The limit is the same between the engine and the Lua APIs and it’s not fixed - it depends on how many cores the computer has (for client/studio) and on the max player count (for server), although server atm is just a hardcoded 4 - but that’s going to change. Either way there’s no difference between different engine subsystems from the core allocation perspective. All scheduling is done automatically with no ability to pin threads to cores, details to come.


Will there be any way to ensure two threads are kept on separate cores?

If not then I would worry about how I can keep an intensive thread from slowing down another one.

Does this mean that in order for us to get the best performance from multithreading if we have a large project is for us to set the player limit to Max. Then just manually distribute players across servers using TeleportService?

1 Like

Question with regards to parallel Lua - can all threads work with Instances, so long as they don’t touch the main data model? It’d be convenient to be able to construct instance hierachies in separate threads, and parent them to the data model later in the main thread.


I’ve found a few bugs and have a few suggestions that I’m not sure are known of yet but wanted to talk about them anyway.
I got a few crashes from doing stuff like this when I require and try to use these classes (because when I tried to export AFTER declaring my module, it didnt want to work)

export type MyClass = TEMP
--... setup
type TEMP = typeof(
return module

I have tried other methods of getting my class to work but meh, everything always crashes studio.

And I also noticed that templated functions I guess aren’t working yet, so I wasn’t able to get appropriate type checking for this.

local ifn: <T, U>(any, T, U) -> T | U = function(a, b, c)
    if a then
        return b
        return c

I also wonder if templated calls will be a thing. Would be interesting to see stuff like this:

local result: Folder = parent:WaitForChild<Folder>("folderName")
local attachments: Array<Attachment> = char:GetDescendants<Attachment>()

As for type safety, I do enjoy how it gives warnings, although the false positives are a bit difficult to deal with. For example, some properties of an object may be nil, but I believe sometimes it is better to give benefit of the doubt when accessing things like children by name or stuff like PrimaryPart when it is assumed that it already exists. There are also times where it just doesn’t want to show autocomplete for the types I have assigned. example:

local root: BasePart? =  model.PrimaryPart
while not root do
    root = model.PrimaryPart
print(root.Velocity) --warnings
local established: Part = root --also warnings
local part: Part = workspace.Baseplate --warnings for accessing child maybe could be ignored?

Other examples:

type Array<T> = {T}
local hinges: Array<HingeConstraint> = {}
for _, item: Instance in next, obj:GetChildren() do
    if item:IsA("HingeConstraint") then
        hinges[#hinges + 1] = item --warnings here for some reason

I was also thinking of maybe adding something like as and is operators to cast or check types, example for above:

if item is HingeConstraint then
    hinges[#hinges + 1] = item as HingeConstraint --or make the casting implicit since we did a check with "is"

Enums also are for some reason not behaving properly.

local state: Enum.UserInputState = Enum.UserInputState.Begin --warning from type setting, when deducing, uses EnumItem anyway
local state: EnumItem = Enum.UserInputState.Begin --works but doesnt mark specific enums

Also, since the deprecation of __meta, it makes it difficult to standardize class types. You might have, for example, a constructor that is called like this: =  function(
    parm1: number?
): abc
    return setmetatable({Value = parm1 or 0}, meta)

and then make a typing for abc with typeof(), but it will usually say that Value is number | nil aka number?, although this makes sure it is always a number. Althought I see that internally its represented with @metatable, I can’t seem to use that either
I also noticed that variadic functions arent getting too much love with LuaU, so I hope to see more about them in the future.