[UPDATE: 2.0] SmartCreate. An easy way to create Instances

Info

The struggle of having Instance.new() not support properties is quite an annoyance. Well, this module solves this issue by allowing you to create any instance with properties, attributes, and children with just one function!


😊 Easy and Clean Configuration

This module uses arrays to edit the properties of an Instance. This allows for an easy and clean way to create instances.


For example:

Create("Part", {
		Name = "Smart",
		Parent = workspace,
		Color = Color3.fromRGB(255,255,255),
	})

You can also get the ValueBase instance with any values by using CreateVaseBase(Value: any, Properties: Properties?)

For Example:

CreateValueBase("StringType") -- Returns StringValue
CreateValueBase(2) -- Returns IntValue
CreateValueBase(2.22) -- Returns NumberValue
CreateValueBase(true) -- Returns Boolvalue
CreateValueBase(CFrame.new(1,1,1)) -- Returns CFrameValue
CreateValueBase(Vector3.new(4,4,4)) -- Returns Vector3Value
CreateValueBase(BrickColor.new("Really red")) -- Returns BrickColor
CreateValueBase(Color3.fromRGB(255,255,255)) -- Returns Color3Value
CreateValueBase(Ray.new(Vector3.zero, Vector3.yAxis * 100)) -- Returns RayValue

⚡Performance*

NOTE: This is only in some test cases, SmartCreate is faster than Instance. new() in a few microseconds, but the speed is negligible.

Smart Create is much faster than using the ROBLOX Default method.

Test Case Code

ROBLOX Default
--Setting the property of part
local Part = Instance.new("Part", workspace)
Part.Color = Color3.fromRGB(255,255,255)
Part.CFrame = CFrame.new(1,10,0)
Part.Anchored = true
Part.CanCollide = true
Part.Size = Vector3.new(2,10,2)

--Setting the attributes of part 
Part:SetAttribute("IsTouched", false)
Part:SetAttribute("DefaultSize", Vector3.new(1,1,1))

--Setting the Touched Event of the part
Part.Touched:Connect(function(otherPart)
	print(otherPart.Name .. " touched!")
end) 

Part:GetPropertyChangedSignal("Name"):Connect(function()
	print("Name changed to "..Part.Name)
end)

--Setting the child of the part
local Head = Instance.new("Part", workspace)
Head.Size = Vector3.new(5,5,5)
Head.Anchored = true

Part.Parent = Head 
SmartCreate
Create("Part", {
		Name = "Smart",
		Parent = workspace,
		Color = Color3.fromRGB(255,255,255),
		CFrame = CFrame.new(1,10,0),
		Anchored = true,
		CanCollide = true,
		Size = Vector3.new(2,10,2),

		Attributes = {
			["IsTouched"] = false,
			["DefaultSize"] = Vector3.one,
		},

		Touched = function(otherPart)
			print(otherPart.Name .. " touched!")
		end,

		GetPropertyChangedSignal = {
			args = {"Name"},
			callback = function(object)
				print("Name changed to "..object.Name)
			end,
		},

		Children = {
			Create("Part", {
				Name = "Head",
				Size = Vector3.new(5,5,5),
				Anchored = true
			})
		}
	})

Setup

ROBLOX Method:

  1. Download the module from Marketplace
  2. Place it on your desired path

Wally Method:

  1. Add SmartCreate = "ashp116/smartcreate@^2.1.0" to your wally.toml for your project
  2. Run wally install

Example Script:

local SmartCreate  = require(PATH_TO_SMART_CREATE)
local Create, Edit = SmartCreate.Create, SmartCreate.Edit

local CoolPart= Create("Part", {
        Name = "CoolPart",
        Parent = workspace,
        Color = Color3.fromRGB(255,255,255),
        CFrame = CFrame.new(0,0,0),

        Touched = function(otherPart)
			print(otherPart.Name .. " touched!")
		end,

		GetPropertyChangedSignal = {
			args = {"Name"},
			callback = function(object)
				print("Name changed to "..object.Name)
			end,
		},

		Children = {
			Create("Part", {
				Name = "CoolPart2.0",
				Size = Vector3.new(5,5,5),
				Anchored = true
			})
		}
    })

Edit(CoolPart, {
   CFrame = CFrame.new(0,10,0)
})

API

Types

Properties:

[string] : any,
Parent: Instance,
Attributes: {[string] : string | boolean | number | UDim | UDim2 | BrickColor | Color3 | Vector2 | Vector3 | NumberSequence | ColorSequence | NumberRange | Rect},
Children: {Instance}

Methods

Create (ClassName: string, Properties: Properties) → Instance

Edit (Object: Instance, Properties: Properties) → Instance

CreateValueBase (Value: Any, Properties: Properties?) → ValueBase

Updates

1.0 - July 28, 2023
  1. Launch
  2. Bug Fixes
2.0 - July 30, 2023
  1. Added support for ValueBase creation from any data types
  2. Added support for Function properties of an Instance. Resolving : function of instances

FEEDBACK

Please reply to this post, it would help me a lot. You can comment on my work, or I need to fix any bugs, or even just want help. I will be updating the module.

Thanks for reading :slight_smile: and hope this helped !!!

Gist

: SmartCreate.lua · GitHub

13 Likes

Cool
Just wanted to point out you put August for the first version instead of July :wink:.

3 Likes

If you try to parent the Part to workspace (without using the second parameter). Would your module still be faster than Roblox’s version?

2 Likes

Feels a bit misleading, I’m pretty sure the reason why “ROBLOX Default” is slower is because you are setting the parent before setting the properties. Which is argued against in this post: PSA: Don't use Instance.new() with parent argument

Not sure if you’re using parent afterwards to spin the narrative that SmartCreate is faster because I don’t see how that’s possible.

6 Likes

Haha thx for the catch, time’s flying by.

1 Like

Oh, I am not sure, let me test it out and see.

Hey so I tested it out, and it seems as if SmartCreate is faster. I used the same SmartCreate code, but here is the updated version of ROBLOX default.

In this new test, the results are the same. SmartCreate is faster. SmartCreate sets the parent of the instance in sync. Also, Roblox Default is calling the variable repeatedly to edit properties, which might be the reason.

But there are limitations in these experiments, such as computer specs, the version of the studio, and the instance I am trying to create.

Graph: Graphing Calculator

--Setting the property of part
local Part = Instance.new("Part")
Part.Color = Color3.fromRGB(255,255,255)
Part.CFrame = CFrame.new(1,10,0)
Part.Anchored = true
Part.CanCollide = true
Part.Size = Vector3.new(2,10,2)

--Setting the attributes of part 
Part:SetAttribute("IsTouched", false)
Part:SetAttribute("DefaultSize", Vector3.new(1,1,1))

--Setting the Touched Event of the part
Part.Touched:Connect(function(otherPart)
	print(otherPart.Name .. " touched!")
end) 

Part.Parent = workspace

--Setting the child of the part
local Head = Instance.new("Part")
Head.Size = Vector3.new(5,5,5)
Head.Anchored = true

Head.Parent = Head

This is literally impossible, I’m gonna run my own tests because I think you’re being deceptive.

Sure, but I have run my tests with no deceptions. If there are any inaccuracies, lmk.

1 Like

image
Roblox’s is faster than SmartCreate’s

Code:

local Create = require(game.ServerScriptService:WaitForChild("SmartCreate")).Create

local start = os.clock()

Create("Part", {
	Name = "Smart",
	Parent = workspace,
	Color = Color3.fromRGB(255,255,255),
	CFrame = CFrame.new(1,10,0),
	Anchored = true,
	CanCollide = true,
	Size = Vector3.new(2,10,2),

	Attributes = {
		["IsTouched"] = false,
		["DefaultSize"] = Vector3.one,
	},

	Touched = function(otherPart)
		print(otherPart.Name .. " touched!")
	end,

	Children = {
		Create("Part", {
			Name = "Head",
			Size = Vector3.new(5,5,5),
			Anchored = true
		})
	}
})

print(os.clock() - start .. ": SmartCreate's time")

local start = os.clock()

--Setting the property of part
local Part = Instance.new("Part")
Part.Name = "Smart"
Part.Color = Color3.fromRGB(255,255,255)
Part.CFrame = CFrame.new(1,10,0)
Part.Anchored = true
Part.CanCollide = true
Part.Size = Vector3.new(2,10,2)

--Setting the attributes of part 
Part:SetAttribute("IsTouched", false)
Part:SetAttribute("DefaultSize", Vector3.one)

--Setting the Touched Event of the part
Part.Touched:Connect(function(otherPart)
	print(otherPart.Name .. " touched!")
end) 

--Setting the child of the part
local Head = Instance.new("Part")
Head.Name = "Head"
Head.Size = Vector3.new(5,5,5)
Head.Anchored = true
Head.Parent = Part

Part.Parent = workspace

print(os.clock() - start .. ": Roblox's time")
3 Likes

Also this is the same for SmartCreate. So this is what I mean by it’s literally impossible to be faster than Roblox’s method.
image

1 Like

wait its strange because for me it is the reverse. I took your code and reversed it

1 Like

Yea I know, I was also confused when I tested. I ran like 20 tests and it gave the same results.

1 Like

Here I added task.wait(5) so the render time of drawing the “Part” doesn’t affect each other methods.

Here is the code:

local SmartCreate = require(game.ReplicatedStorage.Packages.SmartCreate)
local Create = SmartCreate.Create
task.wait(5)
local start = os.clock()
Create("Part", {
	Name = "Smart",
	Parent = workspace,
	Color = Color3.fromRGB(255,255,255),
	CFrame = CFrame.new(1,10,0),
	Anchored = true,
	CanCollide = true,
	Size = Vector3.new(2,10,2),

	Attributes = {
		["IsTouched"] = false,
		["DefaultSize"] = Vector3.one,
	},

	Touched = function(otherPart)
		print(otherPart.Name .. " touched!")
	end,

	Children = {
		Create("Part", {
			Name = "Head",
			Size = Vector3.new(5,5,5),
			Anchored = true
		})
	}
})

print(os.clock() - start .. ": SmartCreate's time")

task.wait(5)

local start = os.clock()

--Setting the property of part
local Part = Instance.new("Part")
Part.Name = "Smart"
Part.Color = Color3.fromRGB(255,255,255)
Part.CFrame = CFrame.new(1,10,0)
Part.Anchored = true
Part.CanCollide = true
Part.Size = Vector3.new(2,10,2)

--Setting the attributes of part 
Part:SetAttribute("IsTouched", false)
Part:SetAttribute("DefaultSize", Vector3.one)

--Setting the Touched Event of the part
Part.Touched:Connect(function(otherPart)
	print(otherPart.Name .. " touched!")
end) 

--Setting the child of the part
local Head = Instance.new("Part")
Head.Name = "Head"
Head.Size = Vector3.new(5,5,5)
Head.Anchored = true
Head.Parent = Part

Part.Parent = workspace

print(os.clock() - start .. ": Roblox's time")

1 Like

Well this is certainly strange. These measurements are averaged across hundreds of thousands of runs, and SmartCreate is consistently faster than Instance.new() (regardless of whether it has a parent argument)

2 Likes

woah, your experiment is more accurate. But now the question is, should use SmartCreate than Instance.new() , because it is faster and easier to create instances? I certainly didn’t expect SmartCreate to be faster than Instance.new()

1 Like

The performance gap between utilizing Instance.new() and this resource is merely in microseconds, making it a case of microoptimization for those primarily concerned with speed. However, for those dealing with the creation of a large number of instances, this resource proves valuable as it streamlines the process, eliminating redundancies related to instance creation, property setting, attribute configuration, and event connections. It’s important to note that this resource may not hold the same level of usefulness for all users.

4 Likes

I agree speed is something not all users might find useful. On the contrary, the initial reason for the module was to create instances with bulk properties, attributes, or children with just one function, rather than traditionally refer to the instance multiple times. As you have stated.

1 Like

We arent living in 1986 anymore bro. It dosent matter if its 0.00001 microsecond faster.

3 Likes

This module isn’t even faster, it’s the exact same speed and maybe more memory because they’re using arrays.

2 Likes