How does all the new Vector3.new values not lag roblox?

I was wondering how roblox does not lag because of all the new Vector3’s. If it does lag roblox is there any way to delete a vector3 value?

Your question is very unclear, please elaborate. Which “Vector3s” are you referring to?

Im referring to the .position Vector3.new’s. Doesn’t new create a new vector?

like
game.Workspace.Part.Position = Vector3.new(something)

Vector3s are highly optimized userdatas in Roblox, they don’t lag anything unless they’re running instructions themselves (would have to be a lot). They would only take up more memory, and not a lot with that. You could apply this logic to anything:

  • How do all the parts in Roblox not lag?
  • How do all the scripts in Roblox not lag?
  • How do all the CFrames in Roblox not lag?
  • How do all the x in Roblox not lag?

Here’s the source code for Vector3 (an attempted replica I believe)

-- Vector3 class
 
local vector3 = {__type = "vector3"};
local mt = {__index = vector3};
 
-- built-in functions
 
local sqrt = math.sqrt;
local acos = math.acos;
local cos = math.cos;
local sin = math.sin;
 
-- private functions
 
local function calcMagnitude(v)
	return sqrt(v.x^2 + v.y^2 + v.z^2);
end;
 
local function normalize(v)
	local magnitude = sqrt(v.x^2 + v.y^2 + v.z^2);
	if magnitude > 0 then
		return vector3.new(v.x / magnitude, v.y / magnitude, v.z / magnitude);
	else
		-- avoid 'nan' case
		return vector3.new(0, 0, 0);
	end;
end;
 
-- meta-methods
 
function mt.__index(v, index)
	if (index == "unit") then
		return normalize(v);
	elseif (index == "magnitude") then
		return calcMagnitude(v);
	elseif vector3[index] then
		return vector3[index];
	elseif rawget(v, "proxy")[index] then
		return rawget(v, "proxy")[index];
	else
		error(index .. " is not a valid member of Vector3");
	end;
end;
 
function mt.__newindex(v, index, value)
	error(index .. " cannot be assigned to");
end;
 
function mt.__add(a, b)
	local aIsVector = type(a) == "table" and a.__type and a.__type == "vector3";
	local bIsVector = type(b) == "table" and b.__type and b.__type == "vector3";
	if (aIsVector and bIsVector) then
		return vector3.new(a.x + b.x, a.y + b.y, a.z + b.z);
	elseif (bIsVector) then
		-- check for custom type
		local t = type(a);
		local cust = t == "table" and a.__type or t;
		error("bad argument #1 to '?' (Vector3 expected, got " .. cust .. ")");
	elseif (aIsVector) then
		local t = type(b);
		local cust = t == "table" and b.__type or t;
		error("bad argument #2 to '?' (Vector3 expected, got " .. cust .. ")");
	end;
end;
 
function mt.__sub(a, b)
	local aIsVector = type(a) == "table" and a.__type and a.__type == "vector3";
	local bIsVector = type(b) == "table" and b.__type and b.__type == "vector3";
	if (aIsVector and bIsVector) then
		return vector3.new(a.x - b.x, a.y - b.y, a.z - b.z);
	elseif (bIsVector) then
		-- check for custom type
		local t = type(a);
		local cust = t == "table" and a.__type or t;
		error("bad argument #1 to '?' (Vector3 expected, got " .. cust .. ")");
	elseif (aIsVector) then
		local t = type(b);
		local cust = t == "table" and b.__type or t;
		error("bad argument #2 to '?' (Vector3 expected, got " .. cust .. ")");
	end;
end;
 
function mt.__mul(a, b)
	if (type(a) == "number") then
		return vector3.new(a * b.x, a * b.y, a * b.z);
	elseif (type(b) == "number") then
		return vector3.new(a.x * b, a.y * b, a.z * b);
	elseif (a.__type and a.__type == "vector3" and  b.__type and b.__type == "vector3") then
		return vector3.new(a.x * b.x, a.y * b.y, a.z * b.z);
	else
		error("attempt to multiply a Vector3 with an incompatible value type or nil");
	end;
end;
 
function mt.__div(a, b)
	if (type(a) == "number") then
		return vector3.new(a / b.x, a / b.y, a / b.z);
	elseif (type(b) == "number") then
		return vector3.new(a.x / b, a.y / b, a.z / b);
	elseif (a.__type and a.__type == "vector3" and  b.__type and b.__type == "vector3") then
		return vector3.new(a.x / b.x, a.y / b.y, a.z / b.z);
	else
		error("attempt to divide a Vector3 with an incompatible value type or nil");
	end;
end;
 
function mt.__unm(v)
	return vector3.new(-v.x, -v.y, -v.z);
end;
 
function mt.__tostring(v)
	return v.x .. ", " .. v.y .. ", " .. v.z;
end;
 
mt.__metatable = false;
 
-- public class
 
function vector3.new(x, y, z)
	local self = {};
	self.proxy = {};
	self.proxy.x = x or 0;
	self.proxy.y = y or 0;
	self.proxy.z = z or 0;
	return setmetatable(self, mt);
end;
 
function vector3.FromNormalId(id)
	pcall(function() id = id.Value or id end);
	if (id == 0) then -- right
		return vector3.new(1, 0, 0);
	elseif (id == 1) then -- top
		return vector3.new(0, 1, 0);
	elseif (id == 2) then -- back
		return vector3.new(0, 0, 1);
	elseif (id == 3) then -- left
		return vector3.new(-1, 0, 0);
	elseif (id == 4) then
		return vector3.new(0, -1, 0);
	elseif (id == 5) then
		return vector3.new(0, 0, -1);
	end;
end;
 
function vector3.FromAxis(id)
	pcall(function() id = id.Value or id end);
	if (id == 0) then -- right
		return vector3.new(1, 0, 0);
	elseif (id == 1) then -- top
		return vector3.new(0, 1, 0);
	elseif (id == 2) then -- back
		return vector3.new(0, 0, 1);
	end;
end;
 
function vector3:Lerp(v3, t)
	return self + (v3 - self) * t;
end;
 
function vector3:Dot(v3)
	local isVector = v3.__type and v3.__type == "vector3";
	if (isVector) then
		return self.x * v3.x + self.y * v3.y + self.z * v3.z;
	else
		error("bad argument #1 to 'Dot' (Vector3 expected, got number)");
	end;
end;
 
function vector3:Cross(v3)
	local isVector = v3.__type and v3.__type == "vector3";
	if (isVector) then
		return vector3.new(
			self.y * v3.z - self.z * v3.y,
			self.z * v3.x - self.x * v3.z,
			self.x * v3.y - self.y * v3.x
		);
	else
		error("bad argument #1 to 'Cross' (Vector3 expected, got number)");
	end;
end;
 
return vector3;

It illustrates how the real Vector3 works in Roblox, and how they are optimized efficiently.

Hopefully I answered your question.

2 Likes

Vector3s are garbage collected automatically which prevents them from hanging around in memory after they are used. Nowadays, Vector3s are more performant than in previous years as per the following posts:

Thank you for the information!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.