[Beta] Lua Asset Creation for Creator Tooling with CreateAssetAsync

Hey I’m trying to upload a Model but 2 of my newer UnionOperations are causing it to fail
image

However, it works fine when I destroy these UnionOperations

This could be related to this beta feature which I have now disabled
image

Thank you for the input, I agree, the functionality we are building for review of upload requests from cloud plugins could also be used for local plugins.

The API will not leave explicit opt-in beta (i.e. ignore the auto-enroll switch) until we have full, and safe, support for store plugins. So for now, you can guarantee you are safe by not enabling the beta.

We are also considering a switch to enable/disable the API entirely for local plugins too which would default to disabled; and I see no harm in having a Studio setting that would force the same review feature that will be available for Store plugins on local scripts/plugins too.

One thing that is important however, is that there is an option to enable unprompted upload, one of our goals is to make it such that user-plugins are able to re-implement asset features on par with our first-party features, like the 3D importer. It would be unfeasible for a custom import plugin to import large 3D scenes with potentially 100s of meshes/textures if each asset needed to be reviewed individually. We also recognize that these APIs are useful for automation, which prompts nullify.

But that does not preclude the ability to opt-into or out-of different settings matching different risk profiles!

Interesting, it is very unlikely to be related to that other beta feature.

For transparency, a few different Studio/engine features rely on uploading assets behind the scenes to work properly when a place is published. Sometimes, Studio will temporarily use local data that will be replaced by an asset id later.

Some examples of this are CSG unions, SurfaceAppearance (texture packs), or HSR (hidden surface removal) for layered clothing. When uploading a Model, the API traverses the subtree, and if any such data is in the temporary local state, it will error. This is to prevent you from unknowingly creating assets that will not function properly when used in the future.

In the case of CSG, in Studio, we should be able to trigger the creation of this “behind the scenes” data for you, but that has not yet been implemented.

I expected this error to impact Cloud Luau tasks for CSG, but not Studio, apologies for my oversight.

For now, I think this (unfortunate) workaround might work:

  • Save the place to Roblox
  • Try calling the API again without modifying the Unions

Apologies if I misunderstood your use-case, I am not using this as justification to not implement the functionality with EditableImage, but simply wanted to point you to CaptureService:CaptureScreenshot() in case it might be useful to you here

This is awesome! been wanting to update Packages with CI/CD for a while now

will provide feedback later when i get a chance to use it!


Am I understanding this correctly? would I be able to use this in CI/CD?

@itsFrank17

1 Like

Yes absolutely! Refer to the Open Cloud Luau Execution API Announcement for more info on the CI/CD execution context!

Hey, would this allow us to upload KeyframeSequences as Animations (that can be played back ingame)? Animation upload workflow is clunky right now and making a plugin to speed it up would be great, just not sure if that Model type would upload usable Animations or if they’d just be uploaded as a model

1 Like

Yes, this is planned, I will need to better familiarize myself with the Animation system and distinction between KFS and Animation assets, but what matters is that we want to make it possible to create a working animation assets from scratch in pure-luau using this API.

2 Likes

For a real-world example, the Flipbook plugin is automatically published to the Creator Store via GitHub workflows when 1) a PR is merged to the main branch, which publishes to a development copy of the plugin, and 2) a GitHub release is made, which publishes to the production copy

Here’s a link to the release workflow: flipbook/.github/workflows/release.yml at main · flipbook-labs/flipbook · GitHub

The meat of it is handled via Lune scripts (that call Python scripts, it’s a little all over the place atm). The publish-plugin script handles the bulk of the logic. What I wound up doing was repurposing the Python scripts supplied by Roblox in the place-ci-cd-demo repo to first upload an rbxl containing a built copy of the plugin to a Roblox experience, and then using this Luau execution task I’m able to publish the plugin to the Creator Store.

In an ideal world I’d do all this with Luau, but the Python scripts were able to get things up and running quickly.

Feel free to poke around and repurpose anything for your own work

2 Likes

I currently use this for my CI/CD as well, I have it build > test > publish the game to Roblox

I’m currently looking for a way to upload/update Packages from .rbxm (model) file directly through HTTP request rather than running Luau execution task, although that is totally fine, I can make this work for my needs

thanks for sharing!

1 Like

This is amazing! Finally, I can throw away the code I wrote to convert EditableMesh to plain text .obj

1 Like

I’m excited for animations to be supported! Uploading animations is a current bottleneck in my plugin; the best I can do now is prompt plugin:SaveSelectedToRoblox(). Manually naming an animation, specifying the group, and setting the AssetId is slow, so being able to do this programmatically would help speed up my workflow. This is awesome, thanks!

1 Like

Is this what the CI/CD asset API is supposed to be?

No worries. I am speaking purely from a development asset generation standpoint - i.e. thumbnails in UI. This API is not suitable for that as I need to preserve the background transparency or I will have tons of downloading and error prone postprocessing to do.

1 Like

Would it be possible to open up the Open Cloud endpoint for uploading mesh and image assets directly? With this new AssetService API, it is possible to automatically upload mesh and image assets from an external program, but only through the context of Open Cloud Luau Tasks. Is there a reason why this extra step needs to be taken, and I can’t just directly upload the assets without going through Luau cloud execution? Since Luau tasks are cloud-based, it’s only adding extra latency to the development pipeline.

1 Like

Sorry it took a while to reply, on the surface this sounds like a really cool capability for plugin authors, and definitely something we would like to enable.

There are serious questions about safety and consistency of the Studio experience, so we will probably need to invest in better per-plugin permissions before we can consider building such an API.

Thankfully, part of taking this API (CreateAssetAsync) out of beta, does involve improved plugin permission investments, so we may be able to re-use what we are building for asset upload to deliver a clipboard API.

No promises, but if we can do it safely, I think we should :slight_smile:

2 Likes

This is amazing, and thanks a lot for this update.

Will you introduce more supported asset types in the future? If so what would those be?

1 Like

Finally, amazing feature!

My plugin is now usable :partying_face:

Still praying for exceptions in the Editable Image creation permission check

3 Likes

This is pretty awesome, I’ve been able to use this successfully to publish my Luau Language Server Companion plugin from GitHub to Roblox seamlessly! It was the last missing piece for my fully automated release workflow, thank you so much!

Example implementation: Create workflows to publish Companion plugin by JohnnyMorganz · Pull Request #858 · JohnnyMorganz/luau-lsp · GitHub (with a workflow run)

What is the reason behind these being necessary to provide in an OpenCloud Luau task context?
If I looked at an example OpenCloud response, it already has my user prepopulated, so it seems that OpenCloud already knows what user is logged in here:

{
    createTime = "2024-12-08T14:00:43.297Z",
    error = {
        code = "SCRIPT_ERROR",
        message = "No logged in user, CreatorId must be provided as it can not be inferred",
    },
    path = "...",
    script = "",
    state = "FAILED",
    updateTime = "2024-12-08T14:00:46.780Z",
    user = "68136726", -- this is me!!
}
1 Like

yeah, that is what i have been wondering too, why do we have to use Luau Execution Tasks instead of the Open Cloud API directly with Http requests?