2D doublesided plane vs roblox part efficiency

is it more efficient to use doublesided blender 2D plane (2 vertices), or a thin basepart (6 vertices)? I know that the difference is 3x but Roblox also knows basepart geometry by default.

i didnt find anything on this online… i guess i could spawn 10 000 of both and see which one crashes my computer faster. but hey if you know please tell

i believe you will get better frame rate with the mesh with 2 triangles

but Roblox’s parts get created faster if spawning many in quickly

-- i believe this loads faster but will have worse frame rate 
for i = 1, 100 do
    local part = Instance.new("Part")
    part.Parent = workspace
end

-- i believe this loads slower but this will have better frame rate
for i = 1, 100 do
    local clone = mesh:Clone()
    clone.Parent = workspace
end

but i think you should still benchmark it

also it should be more optimal to make your mesh 1 sided and use the MeshPart.DoubleSided property to make it visible from both side

-- obj file
-- vertices
v 0 0 0
v 1 0 0
v 0 1 0
v 1 1 0

-- texture coordinates
vt 0 0
vt 1 0
vt 0 1
vt 1 1

-- normals
vn 0 1 0

-- faces (triangles)
f 1/1/1 2/2/1 3/3/1
f 3/3/1 2/2/1 4/4/1

texture coordinates is optional so you can remove them if you are not using textures Wavefront .obj file - Wikipedia

also MeshPart.CollisionFidelity has a big impact so CollisionFidelity.Box will improve performance for the mesh

Creating a new part and modifying it is always faster than cloning. When cloning, it copies almost every property of an instance.

Let’s say you wanted to clone a part. You only care about its color, size, and transparency. The most common solution is:

local clonedPart = part:Clone()

But that is almost equivalent to

local function Clone(part:Part)
	local clone = Instance.new'Part'
	clone.Anchored = part.Anchored
	clone.CanCollide = part.CanCollide
	clone.CanQuery = part.CanQuery
	clone.CanTouch = part.CanTouch
	clone.Color = part.Color
	-- other properties (but not all)
	clone.Size = part.Size
	clone.Transparency = part.Transparency
	return clone
end
local clonedPart = Clone(part)

There are other properties that were copied that we do not need. We could have just done:

local function Clone(part:Part)
	local clone = Instance.new'Part'
	clone.Color = part.Color
	clone.Size = part.Size
	clone.Transparency = part.Transparency
	return clone
end
local clonedPart = Clone(part)

I tried benchmarking which is faster, and cloning was slower

Results

image

Increased clones
image

Code used
local av = 0
for i = 1, 10 do
	local s = os.clock()
	local clone = workspace.ClonePart
	for i = 1, 10000 do
		local part = Instance.new'Part'
		part.Color = clone.Color
		part.Size = clone.Size
		part.Transparency = clone.Transparency
	end
	av += os.clock()-s
	wait(.1)
end
print("Manual clone:",av/10)

wait(1)

av = 0
for i = 1, 10 do
	local s = os.clock()
	local clone = workspace.ClonePart
	for i = 1, 10000 do
		local part = clone:Clone()
	end
	av += os.clock()-s
	wait(.1)
end
print("Using Clone():",av/10)

yes its correct that clone is slower then Instance.new

but we cant do

local mesh = Instance.new("MeshPart")
mesh.MeshId = "..."
mesh.Parent

so we have no choice but to clone meshes so we must take that into consideration when using meshes

and i believe specialmesh might are slower then meshparts but should be benchmarked

yeah i did some testing

i couldnt get .obj planes imported to roblox so i used .fbx format instead. i also measured 2 methods, one that tests how much time cloning takes, one that tests fps when looking directly at many cloned objects

tldr, the parts performed 2x better in every test.
but .fbx plane takes 12 kb filespace compared to .obj taking 1 kb on my computer. so if .obj worked it could have changed the results a lot

heres the results my pc got in case anyone sees this post in the future

time taken to clone 10 * 10 000 objects (10 for-loops of 10 000 instances)

  • part average ~ 0.11 seconds (out of 4 tests)
  • mesh average ~ 0.25 seconds (out of 4 tests)
  • mesh (onesided, not doublesided) ~ 0.25 seconds (out of 4 tests) (little performance difference, stopped testing this)

fps when looking directly at 100 000 clones inside each other, size around Vector3.new(1, 0.001, 0)

  • part average ~ 3.6 fps (over 10 seconds)
  • mesh average ~ 1.8 fps (over 10 seconds)

I was initially going to DM you a file of a plane but I was interested in comparing file sizes between .obj and .fbx so here’s this:

The file from exporting a single plane from blender as .obj is 345bytes, I was able to shrink the file down to 120 bytes by removing a few default arguments in the .obj file, the final source of the file being

v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v 1.000000 0.000000 -1.000000
f 1/1/1 2/2/1 4/3/1 3/4/1

Unfortunately Roblox seems to inflate that size back up to 336 bytes when downloading it from the server. However, if we compare this to a generic part export, we can see, in bytes, how much larger a part is when downloading it again from the server.
Result of up/downloading the plane keep in mind, 336 bytes:
9692545604.obj (336 Bytes)

So let’s strip the file of any default arguments/comments/headers and whatnot and create a bare-bones cube .obj file so we can see how much larger a plane is compared to a part:

I was able to narrow down a cube to this:

Summary
v 1 1 -1 
v 1 1 1 
v 1 -1 -1 
v 1 -1 1 
v -1 1 1 
v 1 1 1 
v -1 1 -1 
v 1 1 -1 
v 1 1 1 
v -1 1 1 
v 1 -1 1 
v -1 -1 1 
v -1 1 1 
v -1 1 -1 
v -1 -1 1 
v -1 -1 -1 
v -1 -1 -1 
v 1 -1 -1 
v -1 -1 1 
v 1 -1 1 
v -1 1 -1 
v 1 1 -1 
v -1 -1 -1 
v 1 -1 -1 

vn 1 0 0 
vn 1 0 0 
vn 1 0 0 
vn 1 0 0 
vn 0 1 0 
vn 0 1 0 
vn 0 1 0 
vn 0 1 0 
vn 0 0 1 
vn 0 0 1 
vn 0 0 1 
vn 0 0 1 
vn -1 0 0 
vn -1 0 0 
vn -1 0 0 
vn -1 0 0 
vn 0 -1 0 
vn 0 -1 0 
vn 0 -1 0 
vn 0 -1 0 
vn 0 0 -1 
vn 0 0 -1 
vn 0 0 -1 
vn 0 0 -1 

f 1/1/1 2/2/2 3/3/3 
f 3/3/3 2/2/2 4/4/4 
f 5/5/5 6/6/6 7/7/7 
f 7/7/7 6/6/6 8/8/8 
f 9/9/9 10/10/10 11/11/11 
f 11/11/11 10/10/10 12/12/12 
f 13/13/13 14/14/14 15/15/15 
f 15/15/15 14/14/14 16/16/16 
f 17/17/17 18/18/18 19/19/19 
f 19/19/19 18/18/18 20/20/20 
f 21/21/21 22/22/22 23/23/23 
f 23/23/23 22/22/22 24/24/24 

So to upload and download it again from the servers which shows us the size difference/“absolute” amount of memory it takes up,
1.6kb, 1612 bytes to be specific.
9692748674.obj (1.6 KB)

So, uploading a more complex mesh actually causes the filesize to be larger than the file size exported from studio.

Also, here’s the plane .rbxm, use as you please.
plane.rbxm (2.9 KB)

1 Like