The use cases below are extremely niche
We consider legacy meshes outdated and no longer beneficial. But maybe they are not entirely replaced by mesh parts? This article will cover remaining use cases for these founding fathers of mesh rendering on Roblox.
What is a legacy mesh?
Legacy meshes are meshes that are rendered via:
And the already deprecated one:
These instances were added quite early in Roblox’s development history. The earliest date I could track is 2011, which is 5 years older than their more modern counterpart, MeshPart. Which, if you think about how Roblox has not yet deprecated them yet, and the answer is, I don’t know either!
These meshes render the mesh data they are responsible for via attaching them to a BasePart. Ironically, you can even render them by attaching them to a MeshPart. This makes it override the current mesh the BasePart renders and instead inject it with a mesh it is responsible for:
Bad use cases
As mentioned above, these instances are old; while some meshes are able to support PBR, they still do not support LOD. So if you target high graphic details with a still decent performance, go with MeshParts instead. Those will be a lot more fitting for the job.
Also consider that legacy meshes do not override the collision data; it remains of the parenting BasePart collider and will not be influenced by the Scale property.
Good use cases
Any kind of operation that does not require collisions and includes setting the Size property can and should be done via legacy meshes. The reason is that setting the Size property is expensive and is caused by the fact that setting it not only changes the scale of the mesh that is being rendered but also the collider data. Which is unnecessary when you only need it for the visuals. That’s where DataModelMeshes come in clutch. Their Scale property is 2x times faster to set than the Size since it doesn’t include collider resizing. Here is a comparison benchmark using default Roblox’s profiler:
Size:
Scale:
This is a bad example data-wise, but it’s good enough to see the difference visually. You can benchmark it yourself using the code:
code below includes debug.profile functions, which will give you way more data driven output
Benchy
--!strict
--!optimize 2
-- ^ we are testing instance indexing so no need to deoptimize in order to have clear results
local RunService = game:GetService("RunService")
local PartSize = Instance.new("WedgePart",workspace)
local MeshSize = Instance.new("SpecialMesh",Instance.new("WedgePart",workspace))
MeshSize.MeshType = Enum.MeshType.Wedge
RunService.Heartbeat:Connect(function()
debug.profilebegin("Size")
PartSize.Size = Vector3.zero
debug.profileend()
end)
RunService.Heartbeat:Connect(function()
debug.profilebegin("Scale")
MeshSize.Scale = Vector3.zero
debug.profileend()
end)
Another amazing usage for the legacy meshes is replication optimization. DataModelMesh is far cheaper to serialize than MeshPart since it only includes 3 properties (2-3 extra depending on the variation). This makes it amazing for stuff that requires fast replication speeds. For example, if you change maps in your round-based game, you would want to avoid long loading times in order for people to start playing quicker.
There is also a unique ability of meshes to be able to be scaled past the default 2048 size limit (which is once again caused by the collider limitations). This allows you to make visual effects like sunrises and planets without having to involve editable meshes.
Summary
There are still lots of use cases where legacy meshes would be a lot more appropriate than MeshParts. What I showed above is mostly a low-level usage example. There are definitely art direction examples like simulating a retro look. Although their use cases are slowly being replaced by MeshParts, nonetheless they will remain a huge part of Roblox’s history toward a modern-looking engine



