--- title: Model generation description: How text prompts and preset schemas can generate both static 3D assets and fully functional models such as vehicles that drive, planes that fly, and weapons that shoot. --- Through text prompts and preset schemas, you (and players in‑experience) can generate both static 3D assets and **fully functional** models such as vehicles that drive, planes that fly, and weapons that shoot. This guide demonstrates how to use `Class.GenerationService:GenerateModelAsync()|GenerateModelAsync()` as part of a dynamic, player‑driven creative experience. ## Overview `Class.GenerationService:GenerateModelAsync()|GenerateModelAsync()` enables generation of multi‑mesh geometries with the following advantages: - The provided [schema](#schema-based-generation) defines how the generated geometry will be broken into parts. - Any object generated in-experience will be replicated and visible to all players, allowing them to build together in real‑time. - Generated meshes are higher fidelity with better overall forms, silhouettes, more detail, and fewer artifacts. Generated textures are more coherent and detailed, with less graininess and less pronounced baked‑in lighting. - Generation times have lower latency, enabling quicker and more responsive creation in experiences. - You and even players during gametime can specify bounding boxes to suggest size and proportions of the generated model. - An optional max triangle count keeps generated objects performant for your experience. ## Schema-based generation To create articulated, functional objects, the generated geometry must be separated into multiple `Class.MeshPart|MeshParts`. For example, to create a drivable car with wheels that spin and steer, at least five `Class.MeshPart|MeshParts` are needed: one for the car body and four for each of the car's wheels. `Class.GenerationService:GenerateModelAsync()|GenerateModelAsync()` achieves this through a preset **schema** as shown in the following code snippet: ```lua title="Script in ServerScriptService" local GenerationService = game:GetService("GenerationService") local Workspace = game:GetService("Workspace") -- Set up inputs for the generated geometry local inputs = { TextPrompt = "green dragon car with 4 wheels" } -- Set schema to the predefined five-model car chassis local schema = { PredefinedSchema = "Car5" } -- Make the call to generate the model local success, result, metadata = pcall(function() return GenerationService:GenerateModelAsync(inputs, schema) end) if success then -- Scale model to target size and position near world center local targetSize = 16 local modelSize = result:GetExtentsSize() local scaleFactor = targetSize / math.max(modelSize.X, modelSize.Y, modelSize.Z) result:ScaleTo(scaleFactor) result:PivotTo(CFrame.new(0, result:GetExtentsSize().Y / 2, -40)) -- Anchor all parts so that the meshes don't fall apart for _, descendant in result:GetDescendants() do if descendant:IsA("BasePart") then descendant.Anchored = true end end -- Name the model and parent it to workspace result.Name = "BasicDragonCarGeneration" result.Parent = Workspace else warn(result) end ``` `Class.GenerationService:GenerateModelAsync()|GenerateModelAsync()` currently supports two fixed schemas: `Car5` which produces a car with a body and four wheels, and `Body1` which yields a single `Class.MeshPart` object. Additional schemas will be supported in the future, as well as creator‑customized (open) schemas. The following image shows the expected output and its construction as it appears in the [Explorer](../studio/explorer.md) hierarchy: ## Retargetable scripts In Roblox, **behaviors** typically encompass the scripts, attachments, [constraints](../physics/index.md#constraints), and other instance types attached to static textured geometries to make them functional. Since `Class.GenerationService:GenerateModelAsync()|GenerateModelAsync()` generates a wide range of geometries on‑the‑fly, **retargetable scripts** must be attached to automatically adapt behaviors to expected functionality. For example, consider an experience where players get to make their own drivable cars. `Class.GenerationService:GenerateModelAsync()|GenerateModelAsync()` takes the player prompt and generates five distinct meshes (body and four wheels) via the `Car5` [schema](#schema-based-generation). Then, a preset retargetable script adapts its driving behavior to the size and shape of the model to ensure the car is drivable and its wheels spin realistically. ```mermaid block-beta columns 1 block:Main columns 5 Prompt(["   prompt   
   (creator)   "]) Generate{" Geometry 
 Generator 
(Roblox)"} Geometry(("GEOMETRY
   single / multi-mesh   ")) space:2 Schema(["   schema   "]) space Retarget{"    Retarget    
behavior
(creator)"} space FunctionalModel((("    FUNCTIONAL    
MODEL"))) Prompt --> Generate Generate --> Geometry Geometry --> Retarget Retarget --> FunctionalModel Schema --> Generate end style Main fill-opacity: 0, stroke-opacity: 0; style Prompt color:white, fill:RoyalBlue; style Schema color:white, fill:RoyalBlue; style Generate color:white, fill:#9933FF, fill-opacity:0.7; style Retarget color:white, fill:RoyalBlue; style Geometry color:white, fill:SeaGreen style FunctionalModel color:white, fill:SeaGreen ``` To test retargetable scripts: 1. Download the `Behaviors.rbxm` file. 2. In Studio's [Explorer](../studio/explorer.md) hierarchy, right‑click `Class.ReplicatedStorage`, select **Insert** ⟩ **Import Roblox Model**, and choose the downloaded file. The model unpacks into several folders. 3. Copy and paste one of the following code snippets into a server `Class.Script` within `Class.ServerScriptService`, depending on the object type you'd like to generate. This example generates a functional car with a brake, nitro boost, audio and visual effects, and an on‑screen UI speedometer. ```lua title="Script in ServerScriptService" local GenerationService = game:GetService("GenerationService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") -- Set up inputs for the generated geometry local inputs = { TextPrompt = "green dragon car with 4 wheels" } -- Set schema to the predefined five-model car chassis local schema = { PredefinedSchema = "Car5" } -- Make the call to generate the model local success, result, metadata = pcall(function() return GenerationService:GenerateModelAsync(inputs, schema) end) if success then -- Scale model to target size local targetSize = 16 local modelSize = result:GetExtentsSize() local scaleFactor = targetSize / math.max(modelSize.X, modelSize.Y, modelSize.Z) result:ScaleTo(scaleFactor) -- Load "makeFunctional" module for "CarBehavior" local makeFunctional = require(ReplicatedStorage.Behaviors.CarBehavior.makeFunctional) -- Reference car parts by names guaranteed through the "Car5" schema local body = result:FindFirstChild("body") local frontLeftWheel = result:FindFirstChild("front left wheel") local frontRightWheel = result:FindFirstChild("front right wheel") local rearLeftWheel = result:FindFirstChild("rear left wheel") local rearRightWheel = result:FindFirstChild("rear right wheel") -- Set behavioral configuration parameters local config = { seatPosition = "inside", invisibleWhenSeated = false } -- Attach behavior via the "makeFunctional" script local functionalModel = makeFunctional(result, frontLeftWheel, frontRightWheel, rearLeftWheel, rearRightWheel, body, config) -- Position the model near world center functionalModel:PivotTo(CFrame.new(0, functionalModel:GetExtentsSize().Y / 2, -40)) functionalModel.Name = "BasicDragonCarGeneration" functionalModel.Parent = Workspace else warn(result) end ``` To test other generated models with retargetable scripts in the `Car5` schema, change the `TextPrompt` string value on line 7 and playtest again. Ideas include: - `"yellow sports car with a spoiler"` - `"purple bat car with 4 wheels"` - `"giant monster truck with spiked roof"` This example generates a basic plane using the `Body1` schema that flies through player input. ```lua title="Script in ServerScriptService" local GenerationService = game:GetService("GenerationService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") -- Set up inputs for the generated geometry local inputs = { TextPrompt = "basic paper airplane with two wings" } -- Set schema to the predefined static body local schema = { PredefinedSchema = "Body1" } -- Make the call to generate the model local success, result, metadata = pcall(function() return GenerationService:GenerateModelAsync(inputs, schema) end) if success then -- Scale model to target size local targetSize = 30 local modelSize = result:GetExtentsSize() local scaleFactor = targetSize / math.max(modelSize.X, modelSize.Y, modelSize.Z) result:ScaleTo(scaleFactor) -- Load "makeFunctional" module for "AirplaneBehavior" local makeFunctional = require(ReplicatedStorage.Behaviors.AirplaneBehavior.makeFunctional) -- Set behavioral configuration parameters local config = { seatPosition = "ontop", forwardSpeed = 80, turnSpeed = 8 } -- Attach behavior via the "makeFunctional" script local functionalModel = makeFunctional(result, config) -- Place model slightly above ground to let it fall into place local boundingBox = functionalModel:GetBoundingBox() local location = Vector3.new(0, boundingBox.Y / 2 + 3, -40) functionalModel:PivotTo(CFrame.new(location)) functionalModel.Name = "BasicPlaneGeneration" functionalModel.Parent = Workspace else warn(result) end ```