Introducing Require-by-String

I quite don’t get it. Why are people dissatisfied with this? For example, C and C++ use the exact same system.

2 Likes

This is amazing!

As a person who uses many Modules, imagine the amount of code i can save with this new feature! Roblox Studio seems to be evolving very fast!

1 Like

I think it’s because people expected aliases to also be released in the same time.

2 Likes

incredibly solid, can increase efficiency in coding work

I prayed for days like this
image
This is pretty nice, wondering if aliasing is also planned.

4 Likes

you are correct, and the user you’re replying to is using it correctly as well. single dot accesses the scripts current directory (e.g. script.Parent ) and two dots for the parent dir (e.g. script.Parent.Parent ) normal roblox instance hierarchy just doesn’t explain this intuitively

3 Likes

sorry if im a bit dumb, but lets say i have a client script inside the player gui. how can you get modules that are in replicatedstorage?

3 Likes

Can we get this for instances too?

example:
Frame is a child of Main

local Frame = “./Main”

3 Likes

okay, now this is something i didnt expect we would get. cool feature.

2 Likes

Something like this would be nice. GDScript from the Godot Engine has a similar feature where you put a dollar sign in front of a string like that and it would get the instance for you with less code.

var object = $"path/to/object";

=

var object = get_node("path/to/object")

I’d love to see something like this added to Roblox, but I’m afraid that they won’t since they’re aiming for Luau to be embeddable for other software systems too.

8 Likes

i love it Very very use full, only weird thing is some non module things pop up

2 Likes

Hello all. I only just now caught wind of the discussion that had unfolded earlier in the Roblox OSS Discord. Please excuse me if I’m not completely getting something here, as I haven’t really done any sort of dev on Roblox in a little while now and may be missing something critical.

Referencing @Dekkonot’s reply earlier, if Roblox’s require-by-string implementation doesn’t find the indexed script in the same “directory” in DOM (current behavior), why not just try to index the script itself’s children as a fall-back? This shouldn’t break any legitimate existing behavior, as said require call would’ve thrown an error before anyway. It seems that the real argument now that this has already been deployed in production is if this ambiguity is OK in this context. Not something Roblox is new to, after all. :upside_down_face: Again, please correct me if there was a logical reason as to why this wasn’t the behavior implemented.

This was fairly similar to the behavior my wax project had in its runtime implementation (excuse the somewhat unpleasant code :sweat_smile:): wax/lune/lib/data/Template.luau at be78c89ed2e2f94634b0367f13f892f6ea3a0f8a · latte-soft/wax · GitHub

6 Likes

I think Roblox has the right idea, it’s just executed poorly

2 Likes

This is a step in the right direction, however, the path verbosity in how require() handles child instances needs to be addressed. Forcing require("./module/childModule") instead of allowing the more intuitive require("/childModule") adds unnecessary complexity and makes module referencing less streamlined. This improvement can be implemented while maintaining the current require("./module") functionality, ensuring backward compatibility for existing use cases.

4 Likes

doesn’t that completely get rid of the intellisense?

2 Likes

finally
image

2 Likes

by default it does. this is extra effort, but you can define type to describe structure of the module and annotate the variable

1 Like

that’s cool and all, but when are datastores getting updated?

current datastores can’t store anything besides integers, strings or booleans :person_shrugging:

i want to store vector3’s, color3’s, instances and so on
datastores are horrible :broken_heart:

2 Likes
  • What is the use case for wanting to store Vector3 values?

  • What is the use case for wanting to store Color3 values?

    • Why won’t using a table/numbers work for both aforementioned points?
  • What is the use case for wanting to store Instances?

    • How would this even work???
    • Won’t a string work for this?
8 Likes

Thanks for all of your feedback so far!

Our goal is to support cross-runtime compatibility for the Luau programming language. While this announcement brings us one step closer to that, we know there’s still more to do. Today, I want to share a little bit more about what’s still to come as well as address some of your comments and concerns.

Why do you care about cross-runtime compatibility?

We want code written in Luau to be useful both inside and outside of Roblox. If someone writes an awesome Luau library and makes it open source, you should be able to use it in your experiences! We’re increasingly seeing adoption of Luau outside of Roblox, and we want you to be able to benefit from this. Likewise, if you have a library you want to share with others, we want to make that as easy as possible.

Why start with relative paths?

We decided to start with relative paths because they are easy to map onto the way instances work. Aliases and project-relative imports require a bit more thought and some amount of configuration. We plan to support those eventually, but we had to start somewhere, and this is where we decided was best.

How do I require modules elsewhere in my experience?

As part of this release you won’t be able to without using a potentially complex relative path. Of course, you can still use require with instances, just like you can today. We intend to make this easier. See our section on what’s still to come for more information.

How do I require modules inside of my script?

You can require them with ./<script-name>/module. This works because . represents the ‘parent’ of the script, similar to how it represents the directory of a file on the file system . We know this is different from accessing children directly and we’re open to adding support in the future based on the feedback we receive. However, we want to ensure that whatever solution we introduce can be used in open source Luau as well.

Why did you decide to go with this syntax?

About a year ago we made some changes to our import syntax in the Luau programming language. To learn more about why we chose this syntax for Luau you can read these RFCs. We wanted to support the same syntax in the Roblox engine as part of our cross-runtime compatibility effort. However, while developing this we discovered that just as Luau has special treatment for files called init.luau so do other tools used by many creators, specifically Rojo. That left us with a difficult choice to make:

  • Change the syntax for Luau again, breaking projects that had already adopted it.
  • Move forward with the existing syntax, knowing users of tools like Rojo may run into issues with cross-runtime code.
  • Drop cross-runtime support entirely and support different syntax on Roblox.

We immediately ruled out dropping cross-runtime support as we feel very strongly about making it easier for creators and users of the Luau language to be able to share code with one another. That left us with two options (frankly, neither was great) and we had to pick one. After much deliberation, we decided to preserve the existing behavior where requiring a directory with an init.luau file treats the file as a child of the directory. There was no clear “right” option, but we felt this was the least disruptive path forward.

  • Users of the existing behavior wouldn’t need to fix their projects to use the new syntax
  • Future features like aliases and project-relative imports will make it easier to write cross-runtime code that is compatible with external tools.
  • Creators using tools like Rojo can still use string-based imports, they just need to be aware of this nuance when using files called init.luau.
  • Creators relying on other tools can continue to use require with instances if they do not want to adopt this new feature.

As Dekkonot said before, there was no way forward that didn’t break compatibility with someone. We decided to prioritize cross-runtime support and existing code for this release but with our sights set on the future.

What is the compatibility issue with Rojo specifically?

Dekkonot actually provided a great explanation earlier in the thread.

You can use require by string with Rojo, but if you want to run your code in the Roblox engine and elsewhere - your require by string statements will be interpreted differently if you use init.luau in your code, and translate it to Roblox instances using Rojo. If you’re only writing code for Roblox then it’s something you’ll need to keep in mind (especially if you’re using other Luau tools) but it won’t prevent you from using string-based imports.

What's still to come?

We’re exploring the concept of a “Library” to represent a set of related Luau code. Exactly how you define that in the filesystem and Roblox is yet to be determined but we will have a consistent representation across both. When we talk about “project-relative requires” we’re referring to imports that are relative to the root of a library. Project-relative paths will always refer to the same module no matter where they’re used in your library making them even easier to navigate.

We’ll also be introducing aliases from the OS version of Luau. Aliases allow you to use shorthand in your import paths to quickly access other modules or libraries. For example you’ll be able to do things like:

  • @SharedModules/MyModule → /ReplicatedStorage/Modules/MyModule
  • @ServerStorage → /ServerStorage
  • @Roact → /ReplicatedStorage/Modules/Roact

You’ll be able to configure these manually for libraries and we are still looking at how to let you create aliases for all scripts in your experiences!

If there’s anything you feel I didn’t answer please let me know and I’ll follow-up! Once again, thanks for all of your feedback. We really appreciate it :grinning:

9 Likes