OOP part creation method progress

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

1 Like

This just seems like an unnecessarily complicated way to just create an instance how you normally would.

Well, that is kinda literally almost my exact words in the post, and it’s only what I have so far. I do plan on expanding it to have more functionality down the line.

For example, the player feeds in some template data into a Gui and they can create a part of their choosing.

Or maybe they want to make the part explode, I can set the module to a metatable and add an explode function, and call the part with Part:Explode()

I’ll concede that maybe I don’t need a module full of templates, and could probably just keep the name as a property and list it in the return function, but I like the idea of being able to do

Instance.new("part") {
    Property1 = value1;
    Property2 = value2;
    Property3 = value3;
}

A lot better than

Part = Instance.new("part")
Part.Property1 = value1
Part.Property2 = value2
Part.Property3 = value3

The first method assigns all the properties immediately and allows for changing properties later, while the second one is explicitly changing properties after instantiating the object. I could be an idiot and stick a thread in between the object and one of the properties to change and it wouldn’t change until the thread finishes.

The brackets and indentation sorta scream out “hey dummy, this spot is for properties, don’t run any code in here.”