[Beta] Lua Asset Creation for Creator Tooling with CreateAssetAsync

Hello Creators!

While we strive to make the best tools to help you create, we recognize that often, you know best. Which is why today, we are excited to announce two new Luau APIs that drastically expand what Creator Luau tooling is capable of.

The new APIs AssetService:CreateAssetAsync and AssetService:CreateAssetVersionAsync enable third-party Luau tooling to programmatically create and upload assets to your inventories.

These two functions are intended for use in both Studio plugins and the recently announced Open Cloud Engine API for Executing Luau.

The two functions have the following signatures:

AssetService:CreateAssetAsync(
  object: Object,
  assetType: Enum.AssetType,
  options: table
): Enum.CreateAssetResult, number | string

AssetService:CreateAssetVersionAsync(
  object: Object,
  assetType: Enum.AssetType,
  targetAssetId: number,
  options: table
): Enum.CreateAssetResult, number | string

-- return type is number if enum is 'Success', otherwise string

-- options table:
{
    Name: string, -- default: object.Name if applicable, otherwise non-optional
    Description: string, -- default: "Created with AssetService:CreateAssetAsync"
    CreatorId: number, -- default: logged in user (non-optional in OC Luau tasks)
    CreatorType: Enum.AssetCreatorType, -- default: User (non-optional in OC Luau tasks)
    IsPackage: boolean, -- default: true
}

Today, CreateAssetAsync supports 4 asset types:

  • Enum.AssetType.Model with object = any valid Instance root
    • By default uploaded Models are Packages, to create non-package Models set the IsPackage option to false
  • Enum.AssetType.Plugin with object = any valid Instance root
  • Enum.AssetType.Mesh with object = EditableMesh
  • Enum.AssetType.Image with object = EditableImage

Note that asset update is only supported for Model and Plugin asset types.

Getting Started

In Open Cloud Luau Tasks, you can just go ahead and call the API, it should work without any extra steps.

In Studio, enable the beta feature ”CreateAssetAsync Luau API” and make a local plugin, or call it from the command bar!

For more information on the API, see the documentation here:

Note: while CreateAssetAsync unconditionally supports EditableMesh/EditableImage, creating new Editablemesh/Images from cloud Luau tasks requires that the place used for the task have the Mesh/Image API enabled. See the In-Experience Mesh & Image API announcement for instructions on enabling.

Limitations

  • As stated, these APIs are intended for creator use-cases and thus are not available in-experience. Read about upcoming appropriate in-experience APIs in the In-Experience Mesh & Image APIs announcement
  • The APIs will not work when called from plugins acquired from the Creator Store (see below for explanation)
  • If there are unpublished content references in the subtree of a Model or Plugin (e.g. an EditableImage reference), the API call will fail, you should upload these first before uploading the containing model/plugin.
  • The APIs are currently limited at 30 requests per minute

Risks

Assets uploaded via these APIs will be reviewed and moderated identically to assets uploaded from existing Studio features (e.g. 3D Import/Bulk Importer) and are subject to the same consequences if they violate our policies. You are responsible for assets uploaded on your behalf!

For this reason, if you have the beta feature enabled, you should be more cautious when executing or copying local plugins that you have not written yourself or reviewed the code.

Note that this beta feature will not be automatically enabled even if you have auto-enrolled on.

What’s next

Enabling For Creator Store Plugins

As alluded to in the “Risks” section above, letting untrusted code upload assets on your behalf can be dangerous. Because of this, we need to give users the necessary tools to protect themselves from potentially malicious plugins. Next year we plan to introduce a new feature that will let users grant and withdraw permission to use these APIs for individual plugins; and, for plugins that have the permission, review and audit the assets a plugin is attempting to upload before they are uploaded.

Implementing this protection is complex, and will take some time. We recognize, however, that these APIs are extremely useful, which is why we chose to make them available to local plugins today, while we work on the permission system for Creator Store plugins.

We want your feedback!

First off, please let us know what other asset types you would like to see supported by this API!

We will be eagerly watching this thread for issues, requests, and comments you may have. These APIs are for you and your workflows, and we are committed to ensuring they serve you well!

Speaking of your workflows, supporting your tooling, and the ability for your tools and workflows to gracefully interact with Studio and our first party features will be an increasing priority for us moving forward. This API along with the recent Script Sync, and Open Cloud Luau tasks announcements are the first steps in a larger mission to ensure that you have the ability to create using the tools that you want and make you the most efficient.

Thanks!

@bluestann @icemountainrbx @Rusi_002 @ContextLost @DevelopmentDeadline @itsfrank17

81 Likes

This topic was automatically opened after 10 minutes.

Hi there, with the introduction of this, will we be able to write directly to a user’s clipboard? It seems unwieldy that we must use some roundabout way for a user to gain focus on a text box when with this feature we’re generating ids.

21 Likes

For meshes and images, why does it take Enum.AssetType.Mesh and Enum.AssetType.Image, shouldn’t it take Enum.AssetType.MeshPart and Enum.AssetType.Decal instead, so that you are able to distribute them on the store or archive them?

You cannot directly archive Mesh/Image assets, but you can archive MeshPart/Decal assets, and doing so will automatically archive any underlying Mesh/Image assets that are attached to the MeshPart/Decal. Anything the user uploads should be able to be archived.

8 Likes

Additionally, have the restrictions on temporary images been lifted off? In the most recent update, it appears that passing temporary ids through the editable image creation api just causes it to error now.

2 Likes

I have no use for this at the moment but I love the direction Roblox is heading in with this.

However: having this is not a substitution for having endpoints to directly perform these uploads. Particularly with plugins and models, it’s really not acceptable that we cannot upload these without also going through the process of cloud execution.

10 Likes

Thanks for the reply, the API makes Image and Mesh assets directly because we do not want to make assumptions on how you might want to use the resulting ID. E.g. an Image ID can be used in a number of different contexts that are not Decals.

For example, if you wanted to use an Image for an ImageLabel, if the API returned a Decal asset ID, you would have to insert the Decal with InsertService to extract the image asset to then use in the ImageLabel. It would also be additional clutter in your inventory.

To your concern about archiving, even if we created Decals or MeshParts, we would still have to also create an Image or Mesh asset (respectively), since Decal/MeshPart does not contain the actual image/mesh data and are just instances that point to an asset id. So while you would be able to archive the Decal, it would not affect the Image asset the Decal is pointing to.

Finally, while archiving for image/meshes is currently not supported, there is active work being done for asset privacy and access control that should help alleviate these issues in the future.

Edit: I think we absolutely could support Decal and MeshPart as additional asset targets, your point (which I think was an edit?) about creator store is a good one! In that case one might have to call the API twice:

  1. CreateAssetAsync(editableImage, Enum.AssetType.Image, ...
  2. Use the resulting asset id to set the Texture property of a Decal
  3. CreateAssetAsync(decal, Enum.AssetType.Decal, ...
3 Likes

The language is called Luau, but great job otherwise!

6 Likes

Got really excited about this update and saw that Creator Store plugins can’t access the methods yet. :sob:

This would make it so easy for users of my plugin to create, publish, and use edited meshes in their games.

Very cool though - I can’t wait until we can use this in published plugins.

2 Likes

Will we see the ability to upload animations via this new method? Bulk uploading animations is one of the most tedious tasks and being able to streamline uploads would be extremely helpful!

3 Likes

Will this be normalized more? The OpenCloud Asset API currently creates Decal assets which I have to then download using the AssetDelivery API and parse for the Texture property in external tooling.

Thankfully due to resources like Lune it’s less worse than it could be, but still feels unnecessary.

1 Like

Yes, this is planned :+1:

(words words words)

4 Likes

I’d argue it’d be the opposite since Decals can actually be archived, which also archives its underlying Image asset. Only being able to create Images would leave you in a situation where you might have a bunch of Images that you can’t hide on your creations page (under Development Items > Images), since there is no way to directly archive those.

As I mentioned before, archiving a Decal/MeshPart also automatically archives any underlying Image/Mesh assets that are included in the Decal/MeshPart. Both Decals and Images on the creations page have a “Show archived” toggle for a reason.

Supporting Decal/MeshParts as an option (not forced) would be fine - there probably are use cases where someone would genuinely prefer just having an Image/Mesh be created with no additional Decal/MeshPart, if they don’t care about being able to archive the asset and want to skip the extra step of having to call InsertService on the asset to extract an underlying Image/Mesh ID.

Having to call the API twice (as opposed to just creating a Decal from an EditableImage, with the Image asset being created automatically) seems a bit weird though, does this mean you would theoretically just be able to attach any random Image ID in your inventory to a newly-created Decal asset?

1 Like

Absolutely love this update! Is it possible to be able to use the feature in Live experiences some time in the future? I know it might pose many risks (as it previously did before, when it was working for life experiences) but this feature can be super useful for experiences where users draw and create their own images

1 Like

Thank you for the additional information! We’ll take some time to review this and reply with our conclusion.

I clearly have to better inform myself on the unique interaction between Decal/MeshPart assets and the referenced image/meshes; this seems like a legitimate use-case! It will also depend on what our longer-term plans are regarding archiving with the upcoming asset privacy changes.

CreateAssetAsync(editableImage, Enum.AssetType.Decal, ...) might be a valid way forward for this.

Thanks again!

2 Likes

The APIs in this announcement are explicitly not meant for in-experience, thus they will likely not be available in that context; however a different set of in-experience appropriate APIs that achieve a similar outcome are being worked on as mentioned to in the recent EditableMesh/Image announcement

1 Like

Please take a look at the What’s Next section about Store plugins: [Beta] Lua Asset Creation for Creator Tooling with CreateAssetAsync

For this reason, plugins from the creator store cannot access the API, and we are working on features that will let users control which plugins can/cannot access the API, and review individual upload requests issued by plugins

2 Likes

Will functionality similar to what the sacred ThumbnailGenerator and CaptureService: CaptureScreenshot() provide ever be made available in “Cloud Luau Tasks”/Studio or even better live servers.

Functionality like this would be SO useful paired with CreateAssetAsync

3 Likes

This is actually already on our radar, albeit for other reasons. I can’t make any promises, but it’s something we’re considering trying to make happen in 2025. Thanks for the feedback and use case, that definitely helps us prioritize.

4 Likes

This is great. I already have plans to justify these APIs’ addition to the engine and further their value for creators on the platform. Well done.

1 Like