[Studio Beta] Introducing Procedural Models: Build Parametrized 3D Models with Code or AI

[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:

  1. Open the Beta Features panel in the system menu under “File → Beta Features”.
  2. Check “Edit-Time Procedural Models” enabling it.
  3. 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 OnGenerate function, 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 Attributes map 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 OnGenerate function that produces the data model content of the Procedural Model based on the parameter values.

image3

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 provided targetContainer in order to interact correctly with engine systems.
  • The OnGenerate function is allowed to yield or call yielding methods, for example, GeometryService CSG APIs. Generation is considered complete whenever OnGenerate returns.
  • 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 Attributes table in the Generator module.
  • The OnGenerate function doesn’t have to handle position / scale. It generates a result of the specified Size around the origin and the procedural model system automatically uses PivotTo / ScaleTo to 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.
2. Castle_cropped

/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.

image4

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 Sandboxed property set on their generator module to enable sandboxing, and the module’s Capabilities property 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 AccessOutsideWrite permission, preventing it from modifying anything else.
  • The generator module and ProceduralModel itself 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
  • ProceduralModels have a bug in Team Create: they may create multiple Generated folders. If this happens, you can delete one of the Generated folders 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 ProceduralModel can get “stuck” at zero size when resizing it via the Scale tool. For now this can be fixed by adjusting the Size property 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 ProceduralModel into a normal Model?

    • The simplest way to do this is to clear the Generator property in the properties pane. Without a generator, the ProceduralModel will just keep its existing results. Using a ClassChanger plugin to change the ProceduralModel into a Model also works.
  • 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 ProceduralModel at a generator module, which has a copy of the existing model under it as a template to clone from during generation.
  • Do Procedural Models work with packages?

    • ProceduralModel Packages 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 ProceduralModel interact with ScaleTo / PivotTo?

    • ScaleTo / PivotTo will 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 ProceduralModel get 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.
  • How does the ProceduralModel interact 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 ProceduralModel generates the GeneratedFolder will be replaced with a new one without any manual edits you made.
268 Likes

This topic was automatically opened after 10 minutes.

PROCEDURAL MODELS!!!

they’re really exciting =) my favorite part is being able to write code and have the results show in real time

76 Likes

I told you anakin the AI are taking ova! No but in all seriousness very useful in a lot of circumstances.

18 Likes

Did you even read the post? It’s basically just smart models, not instantly AI generated models

56 Likes

Really interesting concept. It will make it easier for builders to make one “base” model and then be able to easily scale it while maintaining the look.

Is this something that only updates within Studio (static/unchangeable in a live game), or are we able to dynamically scale models with this in a live experience? It could be cool for building games to let players experiment with different-sized variants of base props without having to generate them all ahead of time.

10 Likes

Yes I did. It’s AI. Behind all the “smart models” It’s just AI. So it’s over for modelers making models because people can just get a model from the assistant itself.

6 Likes

I can only imagine what sandbox games could do with this.

16 Likes

This is cool, but doesn’t seem Instance Pointers yet. The parts inside the Generated Folder would also just replace the content unfortunately.

You wouldn’t be able to edit attributes mid play run, e.g. you wouldn’t be able to use the solid modeling cutting API and cut through a part, and then change the color on a procedural model using attributes. It would undo everything based on the Module Script you created.

I wonder if they have seen the feedback I wrote. :thinking:

And I wonder if they’ve seen this: ProceduralModel, how to enable it before they announce the beta for it, it looks interesting

wait so they made OOF from text to 3D? :thinking:

8 Likes

Brother read. Atp ur trying to farm anti-AI clout. These models run a script based on changes to the model’s property/attributes. I mean yeah you can use AI to help you create this script, but why is that harmful? It’s not, especially since you won’t need to depend on a scripter just to use this feature.

44 Likes

okay this is actually cool-
especially the ladder example.

Now, I can dynamically use AI and scripting both at the same time to increase the height of a ladder based on a player’s account age… or something like that, idk.

But still, very cool, and will be VERY handy for me in future.

7 Likes

This is what it would be like if the scaling tool became conscious of its own decisions.

It looks like a highly useful system that understands its environment and allows you to create more effectively and intelligently.

7 Likes

this is super cool, great update!

2 Likes

Yes, once the feature is out of beta and enabled in live games, ProceduralModels will respond to parameter changes in-game just like they do in Studio.

Though you’ll have to be much more conservative with when you do generation and how much generation you do in-game because creating large numbers of Instances dynamically can get expensive.

Yes, a parameter that references other Instances isn’t supported yet.

We’re working on adding Instance-reference attributes right now, which will naturally extend ProceduralModel with support for parametric references to other content to include in the generation (E.g.: “Car” ProceduralModel with “Wheel” parameter)

14 Likes

aaaand “Local Packages” too ? :pleading_face:

and built-in util function for Wait Until ObjectValue Value similar?

1 Like

Figuring out the right way to support that sort of mechanic is actually one of the things that has made Instance-reference attributes take a long time to arrive.

4 Likes

This is huge for world and level design workflows. Being able to scale designs like this provides artistic freedom with less manual tweaks needed, very delighted to see this in the engine because I was always on the verge of creating a plugin to do this. Artistic programmers are winning!

3 Likes

This is absolute cinema, I’ll definitely be trying this out!! I hope that the generator module can be separated from the model itself, to reduce boilerplate. If you copy and paste the model a bunch of times, this leads to the module being duplicated as well, making it harder to maintain! Packages wouldn’t work well to fix that.

4 Likes

10/10 :smiling_face_with_three_hearts: I trusted Roblox Assistant, I can sense the future already, I believe it’s gonna be great! Since Assistant was introduced, yes its basically trash way back before, but hey, now it’s slowly getting better. Same on dynamic faces, some of them are now accurate. Keep going, I believe in you.

5 Likes

The actual hookup is the Generator property of the ProceduralModel, which doesn’t care where the ModuleScript is.

We packaged the generator ModuleScript under the ProceduralModel in the sample for simplicity, but there is no issue with moving the generator to a shared location like ReplicatedStorage and having multiple ProceduralModels reference it.

5 Likes