GenerationService

Show Deprecated
Not Creatable
Service

GenerationService enables you to generate 3D objects from text prompts using Roblox's Cube 3D foundation model. This enables the generation of objects like environmental props in-experience.

You can control the output by providing an optional Vector3 to the SuggestedSize parameter. Rather than simply rescaling the result, this parameter guides the model during the creation process, influencing it to create a mesh that attempts to match the proportions and size of your specified bounding box.

Mesh generation is a two step process:

  1. GenerateMeshAsync() starts the mesh generation process using a text prompt and other required parameters. It returns a unique identifier (generation ID) that can be used to retrieve the future result.
  2. LoadGeneratedMeshAsync() loads the generated mesh into the experience. The mesh is returned as a MeshPart or Model.

Currently, GenerationService only supports the following usage:

As a result, when a mesh generation request originates from a client, the client must send a signal to the server to initiate generation. Once the server determines that generation is complete, it should notify the appropriate client to call LoadGeneratedMeshAsync() and retrieve the mesh. Note that since the generated mesh is loaded with EditableMesh content and only on the client, it is not replicated to any other clients.

See this demo experience for a more detailed example including usage of the SuggestedSize option (click the button and Edit in Studio).

Code Samples

This setup includes server-side functionality to handle mesh generation requests from clients.

Server-Side Mesh Generation

local GenerationService = game:GetService("GenerationService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Create a RemoteEvent for client-server communication
local generationEvent = Instance.new("RemoteEvent")
generationEvent.Name = "GenerationEvent"
generationEvent.Parent = ReplicatedStorage
-- Create a RemoteEvent to send generation results back to clients
local generationResultEvent = Instance.new("RemoteEvent")
generationResultEvent.Name = "GenerationResultEvent"
generationResultEvent.Parent = ReplicatedStorage
-- Handle mesh generation requests from clients
generationEvent.OnServerEvent:Connect(function(player, prompt)
print("Generating mesh for player", player.Name, "with prompt:", prompt)
-- Generate the mesh on the server
local success, generationId, contextId = pcall(function()
return GenerationService:GenerateMeshAsync(
{ ["Prompt"] = prompt },
player,
{},
function(intermediateType, intermediateGenerationId, intermediateContextId)
-- Send intermediate result to the requesting client
generationResultEvent:FireClient(
player,
intermediateGenerationId,
true -- isIntermediate
)
end
)
end)
if success then
-- Send the final generation ID to the client
generationResultEvent:FireClient(player, generationId, false)
print("Successfully generated mesh with ID:", generationId)
else
generationResultEvent:FireClient(player, nil, false)
warn("Failed to generate mesh:", generationId)
end
end)

The following example adds client-side functionality to request mesh generation from the server and display the results. This code assumes that the two RemoteEvent instances created by the server-side example (GenerationEvent and GenerationResultEvent) exist inside ReplicatedStorage.

Client-Side Mesh Generation

local GenerationService = game:GetService("GenerationService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Reference to RemoteEvent instances created in server-side script
local generationEvent = ReplicatedStorage:WaitForChild("GenerationEvent")
local generationResultEvent = ReplicatedStorage:WaitForChild("GenerationResultEvent")
local player = Players.LocalPlayer
-- Store generated meshes
local generatedMeshes = {}
-- Function to request mesh generation
local function requestMeshGeneration(prompt)
print("Requesting mesh generation for prompt:", prompt)
generationEvent:FireServer(prompt)
end
-- Handle generation results from the server
generationResultEvent.OnClientEvent:Connect(function(generationId, isIntermediate)
if not generationId then
warn("Generation failed")
return
end
print(isIntermediate and "Loading intermediate result..." or "Loading final result...")
-- Use generation ID generated on the server to retrieve and load the mesh
local mesh = GenerationService:LoadGeneratedMeshAsync(generationId)
if mesh then
-- Clean up previous mesh if it exists
if generatedMeshes[isIntermediate and "intermediate" or "final"] then
generatedMeshes[isIntermediate and "intermediate" or "final"]:Destroy()
end
mesh.Parent = workspace
-- Position the mesh in front of the player
local character = player.Character
if character and character:FindFirstChild("HumanoidRootPart") then
local rootPart = character.HumanoidRootPart
mesh:PivotTo(rootPart.CFrame * CFrame.new(0, 0, -10))
end
-- Store the mesh for cleanup
generatedMeshes[isIntermediate and "intermediate" or "final"] = mesh
print(isIntermediate and "Loaded intermediate result" or "Loaded final result")
else
warn("Failed to load mesh")
end
end)
-- Example usage
requestMeshGeneration("toy robot")

This server-side script gets the size from a Part in the Workspace named SizeBox and tells the client when the model is ready.

Server-Side Mesh Generation With Suggested Size

local GenerationService = game:GetService("GenerationService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Create a RemoteEvent for client-server communication
local generationEvent = Instance.new("RemoteEvent")
generationEvent.Name = "GenerationEvent"
generationEvent.Parent = ReplicatedStorage
-- Create a RemoteEvent to send generation results back to clients
local generationResultEvent = Instance.new("RemoteEvent")
generationResultEvent.Name = "GenerationResultEvent"
generationResultEvent.Parent = ReplicatedStorage
local sizeBox = Workspace:WaitForChild("SizeBox")
generationEvent.OnServerEvent:Connect(function(player, prompt)
-- Get the size from the part
local boundingBoxSize = sizeBox.Size
print("Server received request; using SuggestedSize:", boundingBoxSize)
-- Run the generation in a separate thread
task.spawn(function()
local success, generationId = pcall(function()
return GenerationService:GenerateMeshAsync(
{ ["Prompt"] = prompt },
player,
{ ["SuggestedSize"] = boundingBoxSize } -- Use the size from the box
)
end)
if success and generationId then
print("Server generation complete; sending ID to client:", generationId)
-- Tell the client it's ready and provide the position for the new model
generationResultEvent:FireClient(player, generationId, sizeBox.CFrame)
else
warn("Server generation failed:", generationId)
end
end)
end)

The following example sends the generation request to the server via a parent TextButton. This code assumes there's a Part named SizeBox in the Workspace. It also assumes that the RemoteEvent instance created by the server-side example (GenerationEvent) exists inside ReplicatedStorage.

Button-Triggered Mesh Generation With Suggested Size

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Reference to RemoteEvent instance created in server-side script
local generationEvent = ReplicatedStorage:WaitForChild("GenerationEvent")
local button = script.Parent
local PROMPT = "cabinet"
button.Activated:Connect(function()
local prompt = PROMPT
print("Client requesting generation with prompt:", prompt)
generationEvent:FireServer(prompt)
end)

The following code, placed in a LocalScript in StarterPlayerScripts, listens for the server's signal and loads the model. This example assumes there's a Part named SizeBox in the Workspace. It also assumes that the RemoteEvent instance created by the server-side example (GenerationEvent) exists inside ReplicatedStorage.

Client-Side Mesh Generation With Suggested Size

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GenerationService = game:GetService("GenerationService")
local Workspace = game:GetService("Workspace")
local sizeBox = Workspace:WaitForChild("SizeBox")
-- Reference to RemoteEvent instance created in server-side script
local generationEvent = ReplicatedStorage:WaitForChild("GenerationEvent")
generationEvent.OnClientEvent:Connect(function(generationId, targetCFrame)
print("Client received signal to load model with ID:", generationId)
local success, result = pcall(function()
return GenerationService:LoadGeneratedMeshAsync(generationId)
end)
if success and result then
result.Parent = Workspace
result:PivotTo(targetCFrame)
print("Client successfully loaded and placed model")
-- Make the box a transparent, non-collidable container
sizeBox.CanCollide = false
sizeBox.Transparency = 0.85
else
warn("Client failed to load model:", result)
end
end)

Summary

Methods

Properties

Methods

GenerateMeshAsync

Yields

Parameters

inputs: Dictionary
player: Player
options: Dictionary
intermediateResultCallback: function

Returns

LoadGeneratedMeshAsync

Yields

Parameters

generationId: string

Returns

Events