Introducing an Engine-Level Model Scale API [Beta]

Amazing update. Glad I don’t have to install a plugin for this anymore. So smooth. Might be an obvious question but, just to know for future reference, if I try to scale a 300 part model in real time, the game will crash, correct? (thinking about implementing the ant-man giant oil rig throwing animation)

You thanked yourself in third-person… lol


The particle scaling is a god-send. I cannot stress enough just how fantastic this update is going to be for work flow. Seriously, this is SUPER, SUPER useful. Thank you.

For my feedback, I’m fine with everything, but I do think instances shouldn’t scale when resizing a part, since parts don’t always scale uniformly. If someone wants to scale the part and its properties, they could just group the part, scale it, and then ungroup the part, which is super fast still with keyboard shortcuts. That would result in both functionalities being usable as opposed to just one.

Overall, incredible update. You guys outdid yourselves with this one, and I also really appreciate you reaching out to the community for further feedback on it.

1 Like

There’s nothing fundamentally wrong with calling :ScaleTo every frame. It does have the same caching as :PivotTo so you won’t run into floating point issues. You’ll just have to use your judgement because resizing physical stuff in the world is still significantly more expensive than moving it.

The big caveat is that you probably don’t want to scale stuff per-frame on the server because the operation will still replicate to clients as a bunch of separate Instance property changes, not as one atomic scale operation.

Per frame resizing of:

  • 3 MeshPart model? Reasonable use case.
  • 30 part prop? Still probably okay but you might want to reconsider if you’re considering doing it on multiple of these props.
  • 300 part house… questionable, might still work if you do it on the client only but would immediately throttle replication if you did it on the server.
  • 3000 part lobby? Things will definitely start exploding.

Sorry to bother, but I would like to know what is an engine level API? What’s the difference between it with the current state of the scale tool?

The old Scale tool was just a bespoke collection of Lua code which was written to work on specific types of Instances. You could copy this code out of the Scale tool and reuse it in a game or community plugin, but this would come with a lot of caveats. For Instance, there’s no guarantee that that code would continue to work on new types of Instance we add in the future.

Having an actual API in ScaleTo is us providing you some guarantees: That when you call ScaleTo on a Model, it’s going to scale that model in a consistent predictable way regardless of how the engine evolves in the future.

The other aspect is that when you call that API the engine can be a lot more clever about how it handles things, for example allowing packages to scale without modification. With the old scale tool Lua code it’s very difficult for the engine to figure out that what’s going on is actually a scale operation: All it sees is a bunch of separate property changes happening and the best it could have done was make an unreliable educated guess on whether a scale operation was happening.


Is this contemplated?

1 Like

That’s (almost) exactly what this is!

Though with the caveat that the content has to be in a Model (or temporarily be moved into one). This is a reasonable restriction because models are the Instance that has a 3d reference location in the form of their pivot, and you need some 3d reference location to do the scaling around.

Another reason for this restriction is that the model caches the “original” sizing for the extent of the session, such that you can rescale the model as many times as you want in the session without introducing a bunch of floating point error in object positions. It’s better to have only model pay the cost of supporting this caching rather than every Instance type.


I love you

  • love maple hospital dev team

Not quite friendly, right? If I have, like my example, a folder of distinct objects, and I want to scale them all proportionally, exactly like in studio, will I need to create a temporary model, move the folder as child of this model, scale the model, move back the folder again out of the model, delete the model? And will I first need to know the total size of the model to put all objects inside first?

1 Like

The idea here is that if you want to scale something geometrically it should be a Model, since Models are the geometric container that we put geometric operations such as movement, bounding box calculations, and now scaling on.

And will I first need to know the total size of the model to put all objects inside first?

No, the size doesn’t have to be involved. All you do need to do is set the WorldPivot of the model to the point you want to scale around. And you’d have to specify that point regardless even if there were an API not associated with Model.

If you are in editor then you can just use the scale tool. If you’re not in editor it should be easy to write the code to use a temporary model. Or a permanent one… if you really need something to be a Folder for editing convenience you could even have Lua code turn it into a Model at place startup time if you plan to scale it / move it around at runtime.


How come this means that light ranges can’t be extended? This staff reply made it seem like it was being looked into, not that:

Did something major prevent an extension from being possible? There are many things that make longer light ranges important (e.g. even a moderately tall structure can’t have lights reach from the top to the bottom, a lamppost can only light up a tiny area).


Sorry for the confusion with the mixed messaging, but there is a method to the madness, edited the post to have less mixed messaging :slight_smile:

Short story: Some extension of light ranges (even a fair amount) may be possible but not enough to make it play nice with the scale API.

Long story:

Given how extremely conservative the current limit is, and just because of how lighting works, even if some extension of light ranges happens, developers are still likely to set the light ranges right up against the cap most of the time.

The scale API still needs to respect the underlying limits, so if you scale something that’s already up against the limit up, it won’t increase. But when you scale that thing back down it will decrease. That means with light ranges that are already always up against the limit, scaling them is actually counterproductive because it would actually decrease light ranges more often that it would handle them properly.

Add this to the general mechanics of lights, where range is a weird property. You’re incentivized to set it as high as possible regardless of whether you actually need the range so that you don’t have to fiddle around with it again as you move the light. That means no matter how big we make the range limit people are likely to often stay right up against it.

Light ranges are just a really weird case for the scale API.


What if I want to scale model with scale tool without using new scaling technique (as in doing rescaling while retaining same scale factor), will that be possible?
Good feature regardless, still sad we don’t get to have increased light range as it was mentioned, as it’s a nuisance in big areas.

So you’re telling me, apart from Move and Rotate, we can also SCALE animation objects??? To play in an animation???

This is fantastic, to celebrate here is too many dinosaurs. Previously this wouldn’t work because the models were huge and I couldn’t scale their animations.



The new scaling logic only applies if you scale a Model. If you ungroup a Model first or multiselect parts under it you’ll still get the simple scaling behavior that only scales Parts and Attachments when scaling that selection.

But furthermore you can combine this with the new Explorer filtering to get the old behavior even in complex scenarios: If you only select the BaseParts under the Model by filtering for them (filtering is:BasePart) you’ll be able to get an equivalent to the old scale behavior relatively easily.


Will there ever be support for smooth scaling without repeatedly having to call :ScaleTo()? I have a lot of use cases for needing to tween a models size (and position), like studio tools in-game, but it’s currently impossible.

Also, you can call Model:ScaleTo(0/0) and it’ll set its scale to nan which will effectively send the model to space. You can also do Model:ScaleTo(1/0) for infinity and you’ll encounter the same behavior.

Another possible bug is scaling a model that’s parented to another model. Calling ParentModel.ChildModel:ScaleTo(20) will scale its size like normal but will also offset its position. I can’t seem to get this to be reproduced 100% of the time though.

And finally, you can call Model:ScaleTo(true) and it’ll set the scale factor to 1. My guess is that it works because a true boolean value is represented as a 1 but I would still categorize it as unwanted behavior. You can create odd but functional code like so Model:ScaleTo(workspace ~= game.Players:WaitForChild("BullfrogBait")). Pretty interesting. :wink:

1 Like

I think this is going to be a major game changer for my workflow, thanks!

Unfortunately the engine is just not good at this. Being an engine that focuses on physics everything throughout the engine stack is optimized for fast high fidelity physics simulation, dynamic destruction, etc. Logical operations like scaling a hierarchy are unlikely to ever be very cheap because they would require optimizing in a different direction.

Though… having an API like this is actually a start. You can imagine a future where the engine sees you calling this API and is smart enough about it to do something more intelligent than just setting descendant properties and being done with it.

I am looking to add some sort of shim allowing the TweenService to call PivotTo / ScaleTo, however even if I do it won’t quite be what you’re looking for since you’ll only be able to use it to scale so complex of a model before you run into perf issues.

Good bugs. I prevented you from scaling to 0 but forgot to catch infinity / NaN too… facepalm. As for the child model case, fear not, I think I might know what’s going on there.

Fun fact: All reflection API methods which take number arguments actually treat booleans that way with false = 0 and true = 1. Don’t know the history on that one but it’s been that way since scripting was first introduced. This isn’t a specific coding decision in each API, it’s the general reflection system which handles that conversion automatically.


So it can be used if the publisher has the beta enabled? Or it can’t be used in game period until it’s out of beta?