[Update] April 28, 2026
Hi Creators,
Today we’re launching Procedural Models, built on top of a new Instance type that lets you quickly create 3D models that automatically adapt to customizable attributes you define. This lets you dynamically adjust a model’s geometry, colors, or materials just by changing the value of different attributes. This is available in Roblox Studio to all creators under the “Edit-Time Procedural Models” Studio beta today!
Enabling the “Edit-Time Procedural Models” Beta Feature:
- Open the Beta Features panel in the system menu under “File → Beta Features”.
- Check “Edit-Time Procedural Models” enabling it.
- Restart Studio.
To get started, go to Studio, Insert Object, and select ProceduralModel. It comes with a ready-to-use template.
What are Procedural Models?
A ProceduralModel is a smart container. When you change the Size property or an attribute (like “Spacing” or “Material”), it triggers a Generator Module—a Luau script that rebuilds the model for you.
- Build Faster: Create buildings, bridges, or foliage that can regenerate based on parameters you set.
- Creator-defined Customization: Use custom attributes to drive design changes, like stair height or shelf count, and see results immediately.
- Engine-Level Integration: By filling in a single
OnGeneratefunction, you get automatic integration with the Studio undo stack, Team Create, Dragger tools, and the ability to use Procedural Models both while editing and (once out of beta) at runtime. - Idle until Activated: Procedural Models behave like standard models until a parameter changes. They don’t come with any extra execution overhead.
Creating Generator Modules
To get started, use Insert Object in Studio to insert a ProceduralModel. The inserted ProceduralModel will come with a helpful template to work from.
A ProceduralModel gets its parameters from the ModuleScript that its Generator property points to. This could either be a ModuleScript located under the ProceduralModel itself or in a common shared location like ReplicatedStorage. The Generator should define two things:
-
An
Attributesmap specifying which attributes trigger re-generation of the model and the default values of these attributes. The default values will be automatically added to the ProceduralModel if not already there. -
An
OnGeneratefunction that produces the data model content of the Procedural Model based on the parameter values.

Click here to see a code sample for the ladder with API details.
local ClassicRobloxLadderGenerator = {}
ClassicRobloxLadderGenerator.Attributes = {
RungSpacing = 2,
RungThickness = 1,
PostSize = 1,
Color = Color3.new(0.5, 0.3, 0),
}
ClassicRobloxLadderGenerator.OnGenerate = function(parameters, targetContainer)
local size = parameters.Size
local rungThickness = parameters.Attributes.RungThickness
local postSize = parameters.Attributes.PostSize
local count = (size.Y - rungThickness) // parameters.Attributes.RungSpacing + 1
local function createPart(position, size)
local part = Instance.new("Part")
part.Size = size
part.Position = position
part.Anchored = true
part.Color = parameters.Attributes.Color
part.TopSurface = Enum.SurfaceType.Smooth
part.BottomSurface = Enum.SurfaceType.Smooth
part.Parent = targetContainer
end
local position = Vector3.new(0, -size.Y / 2 + rungThickness / 2, 0)
for i = 1, count do
parameters:Pause() --> Break up work in case of large generation
createPart(position, Vector3.new(size.X - 2 * postSize, rungThickness, size.Z))
position += Vector3.new(0, parameters.Attributes.RungSpacing, 0)
end
createPart(Vector3.new(-0.5 * size.X + postSize / 2, 0, 0), Vector3.new(postSize, size.Y, size.Z))
createPart(Vector3.new(0.5 * size.X - postSize / 2, 0, 0), Vector3.new(postSize, size.Y, size.Z))
end
return ClassicRobloxLadderGenerator
Some details to keep in mind as you start creating Generator Modules:
- The
OnGeneratefunction should not modify the DataModel directly. It should only write results into the providedtargetContainerin order to interact correctly with engine systems. - The
OnGeneratefunction is allowed to yield or call yielding methods, for example,GeometryServiceCSG APIs. Generation is considered complete wheneverOnGeneratereturns. - Adding calls to
parameters:Pause()lets you break up work easily, pausing generation only when needed to avoid dropping frames. - The Attributes of a ProceduralModel will automatically be populated with default values from the
Attributestable in the Generator module. - The
OnGeneratefunction doesn’t have to handle position / scale. It generates a result of the specifiedSizearound the origin and the procedural model system automatically usesPivotTo/ScaleToto position results in the relevant ProceduralModel.
Generate Procedural Models with Assistant or MCP
In addition to writing a ProceduralModel by hand, you can use Assistant or Studio MCP to quickly create the generator logic for you using text prompts and reference images. Try out the new /generate_procedural_model command with a text prompt or image and it will generate a ProceduralModel complete with attributes, scripts, and utilities. Here are a few prompts to get you started:
/generate_procedural_model A stylized, round medieval castle features a red-brick base, a white-plastered upper tier, and a large terracotta conical roof. A single, dominant landmark tower stands beside numerous small, slender turrets, all anchored by green shrubbery.

/generate_procedural_model A procedural bridge that adjusts the number of suspension cables based on its length and has a 'Rust' material attribute to change the material type. |
/generate_procedural_model A cyberpunk inspired table with chairs dining set. Add the properties that when I scale the table longer or wider it adds more chairs proportionally. |
|---|---|
![]() |
![]() |
Assistant will figure out the best attributes based on your prompt, but if you ask for specific customizable attributes, it will try to include them. You can also use the Studio MCP server to generate a procedural model using generate_procedural_model.
Procedural models generated by Assistant are made up of primitive parts which give you more ways to edit and refine your model.

If you want to start generating your own Procedural Models, check out our tips to get the best results from Assistant or read below to learn how to manually write the code yourself. Full documentation is available here.
Creator Store
Procedural Models can be published to the Creator Store; what was previously an entire foliage asset pack could instead be a couple of highly parameterized Procedural Models!
To make sure Procedural Models on the Creator Store are safe to use, they’re automatically sandboxed when inserted and can only use generation related APIs within their own hierarchy. By default this sandboxing is present but not shown. Set Workspace.SandboxedInstanceMode = Experimental in the Properties pane if you want to inspect or adjust the Sandboxing on a ProceduralModel’s generator.
How the sandboxing works:
- Sandboxing uses the script capability system. Inserted Procedural Models have the
Sandboxedproperty set on their generator module to enable sandboxing, and the module’sCapabilitiesproperty is restricted to only things needed for generation. - In addition to being denied sensitive APIs access (E.g. DataStore and HttpRequest), the generator is not given
AccessOutsideWritepermission, preventing it from modifying anything else. - The generator module and
ProceduralModelitself have separate independent sets of capabilities. This lets you keep the edit time generation code very locked down without disrupting normal runtime code in the model.
What’s Next
We plan on launching additional improvements to Procedural Models in the near future including:
- More ways to adjust parameters directly in the viewport.
- Continued quality improvements to models generated by Assistant.
- An Engine API for in-game procedural model generation similar to how 3D models are generated in game using GenerateModelAsync.
We’re hoping to launch this fully in the coming weeks; stay tuned, and we’ll update this post when we do!
Known Issues
Click here to view
ProceduralModelshave a bug in Team Create: they may create multipleGeneratedfolders. If this happens, you can delete one of theGeneratedfolders to restore correct behavior. A fix is coming next week.- You can’t turn Procedural Models into Packages yet. We’ll enable this soon.
- Since the ProceduralModel re-runs its script and overwrites the existing instances every time a parameter changes, any manual edits you make to the Generated folder will be lost during the next update. To make permanent, bespoke changes, you should first finalize your parameters and then clear the Generator property. This “bakes” the result into a standard model, severing the link to the script and ensuring your manual refinements aren’t overwritten.
- A
ProceduralModelcan get “stuck” at zero size when resizing it via the Scale tool. For now this can be fixed by adjusting theSizeproperty in the Properties pane. ProceduralModel:ForceGeneration()is not implemented yet.- ProceduralModel doesn’t interact well with Studio’s “Join Surfaces” option, joints will be broken during generation. We plan to provide intuitive joint behavior.
FAQs
Click here to view
-
How do I make the Generator modify the existing contents of my Model?
- This is not supported. You will need to have the generator make a copy of an existing template model to modify. We’re investigating ways we could support modifying existing content rather than generating from scratch in a future iteration.
-
How do I turn a
ProceduralModelinto a normal Model?- The simplest way to do this is to clear the
Generatorproperty in the properties pane. Without a generator, theProceduralModelwill just keep its existing results. Using a ClassChanger plugin to change theProceduralModelinto aModelalso works.
- The simplest way to do this is to clear the
-
How do I turn an existing Model into a ProceduralModel?
- We don’t have an official way to do this yet. The simplest way to introduce some procedural behavior to an existing model is to point a
ProceduralModelat a generator module, which has a copy of the existing model under it as a template to clone from during generation.
- We don’t have an official way to do this yet. The simplest way to introduce some procedural behavior to an existing model is to point a
-
Do Procedural Models work with packages?
ProceduralModelPackages aren’t supported yet, but we hope to introduce support soon. If you’re familiar with package configurations, you can see how we plan to have the two features mesh together in the future with them both using Attributes as configuration.
-
How are generation errors handled?
- If the Generator encounters an error, the ProceduralModel contents will be replaced with an error state placeholder.
-
How does
ProceduralModelinteract withScaleTo/PivotTo?ScaleTo/PivotTowill not trigger regeneration. You have two distinct sizing options – Doubling the Size property of a ProceduralModel will generate new results with twice the extent, vs doubling the Scale will uniformly scale the smaller results.
-
How does the ProceduralModel interact with Undo / Redo?
- Once generation completes, the generation results for a
ProceduralModelget associated with the change history waypoint that initiated the change. If you save and exit before generation completes the generation will be performed the next time the server starts up.
- Once generation completes, the generation results for a
-
How does the
ProceduralModelinteract with network replication?- The peer that initiated the parameter change does the generation. If you change an attribute on the server, the server will generate and replicate the generation results. If you change an attribute on the client at runtime, that client will perform the generation locally.
-
I want to pass a Wheel model to use into my Car as a parameter, how do I do this?
- There is not a good mechanism for this currently. We have work underway to support Instance Reference attributes which will naturally provide support for this.
-
If I remove a part from a procedural model will it stay removed?
- Only until you reparameterize it. The next time the
ProceduralModelgenerates the GeneratedFolder will be replaced with a new one without any manual edits you made.
- Only until you reparameterize it. The next time the

