[Beta] Open Cloud Engine API for Executing Luau

I literally need this. I’m making an icon library that’s already available for JS, but I also want to add it for Roblox

1 Like

hey, I currently have tests for ensuring collision group works properly which would be my use case

does settings Position and CFrame work right now?

(will add more info as i go through the setup)

2 Likes

This is amazing, thank you so much!

A few notes:

I store my game’s configuration in a datastore key so it can be updated across all servers in realtime, and part of any test suite would be making sure the changes are compatible with whatever the current live configuration is. Having at least readonly access to datastores is very important to my use case.

This limit isn’t great since as a project grows, it’s not hard to have a 30-second test suite - especially if you’re running any kind of performance benchmarks. For comparison, I usually set my test suite to timeout at 600 seconds.

This is super exciting to see! I’m looking forward to playing around with it.

4 Likes

You can use any APIs available to GameScripts, other than the deny-list we list here: LuauExecutionSessionTask | Documentation - Roblox Creator Hub

2 Likes

How do you use this without it overwriting and deleting everything in workspace?

2 Likes

image

you didn’t even read the post!

3 Likes

Excited to try this out. We’ve been wanting to do more with testing but it’s difficult to get everyone on board due to it being a messy process typically.

Some questions that come to mind immediately:

  1. Could there be an option to enable the APIs? You can already do this for Studio - I think you should be able to here as well. If I mess up production data, that’s on me!
  2. Where are you hoping to bring the limitations to over time? I personally would like to see more concurrent tasks and a bit longer than 30 seconds - which I know will happen, but to what extent?
  3. Is it possible to include arguments that can be passed to the script?
  4. Do you ever see the possibility of a fake player which can perform certain tasks (e.g. click UI buttons, interact with ProximityPrompts, etc.)?
1 Like

Openblox (my typescript api wrapper) now supports Luau Execution.
docs: executeLuau – Nextra

Executing A Script

import { LuauExecutionApi } from "openblox/cloud"

const scriptA = `local x, y = 3, 4; return x + y`
const scriptB = `local g, x = 3, 4; return g * x`

// Script from string.
const { data:executed } = await LuauExecutionApi.executeLuau({ universeId: 5795192361, placeId: 16866553538, script: `local x, y = 3, 4; return x + y` })

// Script from path string.
const { data:two } = await LuauExecutionApi.executeLuau({ universeId: 5795192361, placeId: 16866553538, script: "hello.luau" })

// Script from Buffer.
 const { data:three } = await LuauExecutionApi.executeLuau({ universeId: 5795192361, placeId: 16866553538, script: fs.readFileSync("hello.luau") })

// Multiple chained scripts.
const { data:four } = await LuauExecutionApi.executeLuau({ universeId: 5795192361, placeId: 16866553538, script: [ scriptA, scriptB, "hello.luau" ] })

Polling for execution completion.

import { LuauExecutionApi } from "openblox/cloud"
import { pollMethod } from "openblox/helpers"

type Results = number[]

const { data:executedTask } = await pollMethod(
  LuauExecutionApi.luauExecutionTask<Results>({
    universeId: 5795192361, placeId: 16866553538, version: 26,
    sessionId: "66d01389-6bac-4d6e-8414-ec9d5dab8297", taskId: "66d01389-6bac-4d6e-8414-ec9d5dab8297"
  }),

  async ({ data }, stopPolling) => data.state === "COMPLETE" && stopPolling(),
)

console.log(executedTask.error ?? executedTask.output.results)

Getting Execution Logs

const { data:logs } = await LuauExecutionApi.listLuauExecutionLogs({
  universeId: 5795192361, placeId: 16866553538, version: 26,
  sessionId: "66d01389-6bac-4d6e-8414-ec9d5dab8297", taskId: "66d01389-6bac-4d6e-8414-ec9d5dab8297"
})
5 Likes

I’d love to hear more about this in general (i.e. beyond the scope of this API release). What would your wishlist be for testing on Roblox?

1 Like

Awesome! Anything you can share about your usecase so we can learn more about where to go with our next versions?

1 Like

The concurrent tasks limit of 2 per universe was lame - so we just increased it to 10.

Given this is a brand new paradigm in Roblox, we wanted to start with very low limits and monitor usage carefully before making too drastic a set of changes.

5 Likes

Thank you for this! Just wanted to share my use case here:

I implemented this into my Discord user installed bot so it can be used anywhere in Discord (even DMs) which is going to be super useful when I want to test basic lua when helping people or testing code that is specific to my game when I’m on mobile/don’t wanna open studio.

8 Likes

Love it! Already got my game’s unit tests running in CI with this! :slight_smile:

3 Likes

This isn’t specific to my use case but I found the docs to be rather confusing.

For example, from one of the paths for the create luau execution session task endpoint it’s inferred you can create an execution from an existing session id - which seems bizarre. I don’t think is intended considering this endpoint returns a 404 error.
image

Similar things like this occur throughout the luau execution docs.

1 Like

Wow so happy to see this. IF there is any feedback on what you did or how we can make it better, we would love to know! Feel free to respond here or DM me.

3 Likes

We are looking at this on an API by API basis. Please let us know what you need, that isn’t available right now! We’re starting with script.Source in the very-near future.

Can you let us know your use case for increasing over 30 seconds? We plan to increase this, but understanding what people use this for is important in making sure we do this in a sensible way.

We know we need to support passing data into this API better. Today you need to template a string into your script. We’re looking at the best way to support here. Arguments will likely be part of the story but we may need other mechanisms for passing in larger amounts of data.

This is a huge topic! No immediate plans but we are thinking about what the story should be for client testing. This will take a while to figure out, so any feedback about your use cases are helpful here.

4 Likes

Thanks for the candid feedback here - and for taking the time to type up your use case in more detail!

The background here is that we are being cautious. I totally get why it might feel like we’re being too cautious. Given we were launching a whole new way of interacting with the platform, some of the things we worried about included:

  • Open Cloud has distinct scopes for some of the same things that Lua APIs can access. Would users expect the DataStoreService Lua API to work, even though the DataStoreService Open Cloud scope is not present on the API key?
  • Open Cloud is premised on granular access to resource, whereas scripts in the engine enjoy broad access.

Ultimately - we want to give you the ability to call these APIs from cloud Luau execution, we just wanted to take a bit more time to plan how to support this. Feedback that this restriction is blocking a real + pressing use case for you is very useful. We’ll discuss more internally and get back to you when we know the next steps.

6 Likes

I get the reasoning and appreciate it, though it reminds me of how you already can do this… sort of. If you have access to publish to the universe (or even directly edit in Studio), you already can manipulate data stores without the OpenCloud permissions.

However, I won’t argue too much on this point because I think it’s worth exploring potential ways to secure this rather than blowing it wide open just because of something else. Two wrongs don’t make a right.

Other than those APIs, I think there is specific value in allowing AssetService:CreatePlaceAsync() since you cannot perform this task with OpenCloud as it is now. The endpoint only exists for user authentication.

This isn’t very thorough but should give you an idea as to what we’d like to see:

We have a separate tutorial place in our experience which is a cut down version of our main game. Sometimes, when we ship updates, the tutorial place can break because of a dependency on something only available in the main game.

Generally, we would like to quickly test if a player is able to join, load their data, interact with the first quest giver, and accept the quest. This is usually a strong indicator that the rest of the tutorial will continue on smoothly. We might add a few more checks where possible and necessary.

Specifically we would need:

  • A Player object
  • Ability to trigger ProximityPrompts
  • Ability to send inputs

Our experience has cases like this but it is very very bad when the tutorial breaks due to something stupid. Not being able to automate this process slows us down since we have to make sure every individual thing works.

Maybe a more specific question is, when does the 30 second timer begin? I was originally thinking that it might include load time and our main place is quite large, so I wanted a bit longer to accommodate… however, it doesn’t make sense to include load time.

I see this as parallel with serverless functions that have a time limit. Sometimes, you wish you had just a bit more head room for certain things. I can see growing interest in higher limits when certain APIs are allowed, such as updating the place.

I don’t have an immediate use case yet as I’ve been locked in on completely unrelated work and haven’t been able to test this out yet. I’ve got the itch to completely rip and tear through our stuff and find use cases.

At minimum, is there a way to gracefully end tasks that go over their limit (e.g. game:BindToClose)?

1 Like

You’ve got 10 requests / player / minute as a soft limit and a few more requests from the 60 buffer that Roblox gives you.

I definitively think there is a way to migrate in your case. Alternatively, you could also have a piece of code that starts a bulk migration if it detects the current reserved server owner is you or one of your devs.

In conclusion, I’d suggest you migrate. Cheers!

2 Likes

Hey, so firstly this feature is AMAZING! Never thought Roblox would ever expand capabilities to this extent.

Now my main question is, could we get persistent task servers from this? essentially having a never ending task? I suggested this a LONG time ago . This would allow us to program matchmaking for instance by having a sort of “brain” server to manage everything, along with caching of datastores certain datastores. Now that we have MessagingService and MemoryStoreService, we can already enable communication between servers, but logic is still a bit difficult to do for peer to peer instead of peer to main server. I understand the matchmaking system was announced, however I’m sure some games will still need to implement their own type of system because of how their own games are designed.

In my use case for a persistent task server is I have factions and a TON of territory on my space game, and each server has to load ALL factions data that exist on the territory (so players can see name of ownership, etc), and the sheer number of factions loaded could exceed a thousand for example, by having a server manage updating the faction data (because it could be updated by many servers at once, datastores may conflict or have problems even with UpdateAsync), it would manage the MemoryStoreService to keep a cache of the latest data, then in the background saving changes to datastore without conflicts since it can merge changes. (Example would be multiple servers adding new members to the faction at the same time, the faction data would have a list of members)

Another use case is handling reserve servers and teleports, right now each sector of my map has a reserve key associated with it, so if a player enters that territory, they’re teleported to that server. The problem is if that server is full, i need a system to automatically expand to another server, but it can’t be a regular server since the reserve keys are what tells the server what sector data to load. By having the task server, it’d allow me “ask” it where to teleport, and based on the players relation (faction, wars, etc) it could then decide to open up a new server, currently with just MemoryStoreService, this is not very easy to handle.

I’m sure there are many more use cases for a persistent task, it is already a running place, just with a time limit, so by allowing 1 or even a few to be persistent per experience would open up countless possibilities, while also reducing the need for externally hosted web servers.

2 Likes