I’ve been working on creating a system for creating and replicating physics parts exclusively on clients to keep things cool on the server.
I figured I needed a few things:
- a default template to fall back on/construct parts out of
- a pack of templates for reusable objects that can be altered on the fly
- complete freedom of customization for reasons unknowable
So far, what I’ve made basically just equates to an Instance.new replacement, but with kind of a weird twist…
Templates:
return {
-- if any properties are missing from the info we want to create a part with, fall back to this.
default = {
ClassName = 'Part';
Name = 'RedCube';
Parent = workspace;
CanCollide = true;
Anchored = false;
Shape = 1;
Size = Vector3.new(2,2,2);
Color = Color3.fromRGB(255,0,0);
Material = 272;
TopSurface = 0;
BottomSurface = 0;
} :: Part;
BlueBall = {
Name = 'BlueBall';
Shape = 0;
Size = Vector3.new(3,3,3);
Color = Color3.fromRGB(0,0,255);
} :: Part;
}
Part Creator:
templates = require(script.Templates)
return {
new = function(part, temp) -- name/template name, template name
part = if part ~= nil then tostring(part) else nil
temp = setmetatable(templates[temp] or templates[part] or {}, {})
-- compare template properties to ones provided and construct part accordingly.
return function(inf) -- Property table to draw custom info from
for prop,val in pairs(templates.default) do
if (inf[prop] or temp[prop]) and prop ~= 'Name' then continue
elseif prop == 'Name' then temp.Name = part or val continue end
temp[prop] = val
end
part = Instance.new(temp.ClassName)
-- swap part name for new instance, save a variable - assert class on return
for prop,val in pairs(temp) do
if prop == 'ClassName' or inf[prop] then continue end
part[prop] = val
end
for prop,val in pairs(inf) do
part[prop] = val
end
return part :: BasePart
end
end;
}
Changes to modules result in object instantiation somewhat resembling Java/C functions:
- Part properties can be assigned from a return table, rather than having to name the part for each property change.
physObj = require('Part Creator')
workspace.ChildAdded:Wait(3)
redCube = physObj.new() {
Position = Vector3.new(-20,1,-10);
}
-- Creates and positions a default part.
blueBall = physObj.new('BlueBall') {
Position = redCube.Position + Vector3.new(6,0,0);
}
-- Creates and positions a default Blue Ball.
otherCube = physObj.new('OtherCube') {
Position = blueBall.Position + Vector3.new(0,0,6);
}
-- Creates/positions a default part with the name "OtherCube"
otherBall = physObj.new(12, 'BlueBall') {
Position = otherCube.Position - Vector3.new(6,0,0);
}
-- creates/positions a default Blue Ball with the name "12"
myCylinder = physObj.new(true) {
Shape = 2;
Size = Vector3.new(8,4,4);
Color = Color3.fromRGB(0,255,0);
Position = redCube.Position + Vector3.new(3, 4.5, 3);
Orientation = Vector3.new(0,0,90);
}
-- Creates a custom cylinder named "true" using the properties provided.
-- Parts created can be referenced and changed later,
redCube.Orientation = Vector3.new(45,0,0)
otherBall.Color = Color3.fromRGB(124,124,0)
-- and info can be sent back and forth between the server/clients for replication if formatted properly further on.
Edit(s): Notes and some post formatting