Luau Recap: June 2020

Is there any reason to use type() nowadays? The only use I can find is that if you need to check it was a userdata for some odd reason.

(Sandboxing Page)

debug. library has been removed to a large extent, as it has functions that aren’t memory safe and other functions break isolation; the only supported functions are traceback and getinfo (with reduced functionality).

We also have profilebegin/profileend :slight_smile:

Props to the people working on this! Luau is becoming seriously awesome.

4 Likes

Please note that at this time we are not ready to make Luau implementation publically available in the source form. Right now the only interface to Luau is the Roblox engine (exposed in Roblox game client/server and Roblox Studio).

Is there (even the very unlikely chance) that Luau will ever be open sourced anytime in the next year or two?

13 Likes

Ok. This system clock is confusing me, so I want to clarify some things. For context, I use tick() for everything right now, including computing spring deltas for updating a UI element.

Is this grid accurate?

The implication is I should use os.clock() or time() for EVERYTHING, unless I want stuff to synchronize with the game time. I’m ok with clocks running backwards if my clock doesn’t lag, although maybe that can create stutter?

Can you tell me if:

  • time() lags if simulation lags
  • time() is 1:1 with real time, or would disconnect?
  • What is time()"s resolution?
  • What does “stable baseline” mean in reference to os.clock()? Does os.clock() run backwards? Does it drift over time?
  • Does calling any of these methods have performance implications?
21 Likes

os.clock() isn’t relative to anything in particular. I think your table is correct otherwise? time() indeed reflects the simulation time so it’s not a good solution for UI animations :-/

edit ah, no, time() baseline is wrong in the table - time() actually starts when the game starts (which is important! on mobile this means it’ll start when the user hits Play, not when they started the app)

This is a surprisingly complex topic :smiley:

10 Likes
  • time() lags if simulation lags

Yes.

  • time() is 1:1 with real time, or would disconnect?

It’s 1:1 with simulation time, so it can disconnect. It’s good to use when you’re using it to model simulation of your own objects.

  • What is time()"s resolution?

It’s advanced every frame by the precise amount of time (~microseconds) it took to complete the last frame, but note that it’s actually the same during the frame - which is good for simulation because this means you can use it in multiple scripts and have a consistent simulation behavior

  • What does “stable baseline” mean in reference to os.clock()? Does os.clock() run backwards? Does it drift over time?

It just means that you shouldn’t assume that “0” in os.clock() timeline means anything. It should be monotonic, which means that whether it drifts over time or not is, uh, dependent on your definition of drifting (drifting from what?)

  • Does calling any of these methods have performance implications?

time() and os.clock() are pretty fast. os.time() might be a touch slower? I wouldn’t be hugely concerned with this unless you call either in a tight loop.

10 Likes

The description of hex escapes on this page is incorrect; the syntax is \xAB, not \0xAB.

Otherwise, this seems like… a description for a github repo, not just for us. Specifically, the details on sandboxing and embedding Luau give me pause since it reads like a pitch for using Luau and explanation of it… :eyes:

I don’t have anything specific to say about this thread beyond “thanks for the website” though. I’ll spare you running commentary as I read through it.


Was this ever properly announced anywhere or is this just on the website?

3 Likes

Excellent information! Thank you! I’ve had several discussions about what exactly to use, so this is very good to learn!

A few more questions:

  • I’m hearing that I should replace all my tick() calls with os.clock() calls! Does that seem right?
  • Is time() good for clock/spring steps in cameras? I think maybe using that would fix some issues with animations.
  • Is time() the same as RunService.Heartbeat() and RunService.Stepped()'s dt?
    • Can I avoid using these parameters, and just use time() instead, if I wanted to?

Does this updated table look correct?

Thank you so much, this is very interesting.

11 Likes

Thanks!

As noted the site serves both Roblox developers who want to be up to date on what Luau can do, and also as an information portal to answer “what, why, how” questions about Luau vs Lua. Also Roblox community tends to be very technical and curious so the extra detail hopefully doesn’t hurt either! No comments other than this :smiley:

We supported this from day 1 I believe, but I don’t recall if this was described in the original type checking beta post. This is part of the motivation to have the web site :slight_smile:

1 Like

Probably not, because this would mean it slows down when physics starts to throttle. For this the ideal case for us would be to expose a time value similar to game time (which is what time() returns) that’s a consistent render time synced with RenderStepped…

Although we have pretty bold plans re: physics simulation that may affect this. For now I think os.clock() is an adequate replacement to tick() for anything that doesn’t need the “almost UNIX timestamp” characteristics?

Is time() the same as RunService.Heartbeat() and RunService.Stepped()'s dt?

time() isn’t a delta time, but it should be the same as the first argument to Stepped.

5 Likes

Why does the “view project on GitHub” redirect to 404? Might want to fix it or even better make Luau open source, I would love to use Lua + static types in my external backend for my Roblox game.

2 Likes

The Luau repository is private, and Luau’s implementation isn’t ready to be publicly available in it’s source form yet, as said in the Open Source section of Why Luau?

Please note that at this time we are not ready to make Luau implementation publically available in the source form. Right now the only interface to Luau is the Roblox engine (exposed in Roblox game client/server and Roblox Studio).

3 Likes

We don’t generally oppose syntax changes, however syntax changes are the highest impact changes to the language and as such they deserve a lot of scrutiny. For example, syntax that provides an alternate method to spell something without significant readability / performance improvements might not be a good idea. There’s no clear cut rules here, here’s a snippet from an internal discussion we’ve had on this topic a few months ago with my comments:

Hopefully this helps. We will add new syntax if we decide that it’s really impactful, but we won’t add new syntax just because language X has it or just because it seems like a neat idea.

On constants, there’s some information here https://roblox.github.io/luau/compatibility.html#lua-54. We may pursue this but it currently doesn’t have substantial upsides, and it’s not obvious that one more way to declare a local is a good idea. There’s probably a long way before this in establishing mutability constraints within the type system.

edit oh, the “feature points” in the comment above are in reference to an excellent Negative 100 Points - Strongly Emergent (unfortunately the original article has been lost when MSDN blogs were discontinued).

7 Likes

A lot of this is really exciting! Thank you so much for all the work you have been doing on increasing usability and performance.

How would you feel about renaming time() to simulatedTime() or simulatedtime()?

Also, are structs in the pipeline?
Ideally these would get the same performance:

function add(
	a1, a2, a3, a4, a5, a6, a7, a8, a9
	b1, b2, b3, b4, b5, b6, b7, b8, b9
)
	return
		a1 + b1,
		a2 + b2,
		a3 + b3,
		a4 + b4,
		a5 + b5,
		a6 + b6,
		a7 + b7,
		a8 + b8,
		a9 + b9
end


type structType = [
	[1]: number;
	[2]: number;
	[3]: number;
	[4]: number;
	[5]: number;
	[6]: number;
	[7]: number;
	[8]: number;
	[9]: number;
]

function add(A, B)
	return [
		[1] = A[1] + B[1];
		[2] = A[2] + B[2];
		[3] = A[3] + B[3];
		[4] = A[4] + B[4];
		[5] = A[5] + B[5];
		[6] = A[6] + B[6];
		[7] = A[7] + B[7];
		[8] = A[8] + B[8];
		[9] = A[9] + B[9];
	]: structType
end
4 Likes

These are all great changes; I’ve been using elapsedTime() as of late because it doesn’t do the same weird time zone shifts that tick() does. os.clock() is definitely going to make my life so much easier!

I’m still anxiously waiting for the type checker to be released in full so that I can use it in production, but I also appreciate a well-done language over a rushed one.

Particularly hoping to see more with function generics, importing module types statically without requiring that module at runtime, and having classes as first-class citizens. I can’t wait to start an upcoming project in a typed luau codebase, but the type system seems to lack a few more features for me to use it the way I want to use it. I’m hoping syntax can be added in the future if not added at release at the very least.

Well, we can’t really rename things :slight_smile: can introduce new names and deprecate old names. In general I’m not sure this deserves a global, so at that point I’d probably bias to some set of RunService properties with descriptive names…

We’re thinking about this but nothing on the immediate roadmap. (edit oh I should mention that we’re considering structs with named fields of course :smiley: see records from https://www.youtube.com/watch?v=vScM-nk5Avk)

6 Likes

Secretly more excited for this than any other update.

That being said, since you’re basically overhauling the language… can I get a continue? :pleading_face:

1 Like

After giving it some more thought, I am coming before you to humbly ask for an update on function generics. Namely: are they still on the roadmap for typed Luau?

Also, as Luau is formally declared a superset, can we have .luau as a valid file type in Studio for saving scripts to a file and importing them from files? It makes sense to distinguish between Lua and Luau at this point.

5 Likes

image

:eyes:

3 Likes

I completely converted my game from tick() to os.clock() with no problems. I almost always calculated time deltas using tick() to keep timing accurate even if something throttles or skips a frame, and it’s a relief to have a precise method like os.clock() that won’t lose floating point precision as we get further from the unix epoch.

4 Likes

Yeah syntax for generic functions is on the roadmap but after we get types out of beta

3 Likes