HierarchyBuilder - simplified React/Fusion

Hierarchy Builder

Download: Here | Github: Here |

We all love instance frameworks for their features. But sometimes we really need the bare minimum from them. And hierarchy builder is exactly that.

local buildInstance = require(HierarchyBuilder)

buildInstance{ Name = "This is";
   Type = "Folder";
   Parent = workspace;

   { Type = "Folder";
      
      _init = function(self:Folder)
         self.Name = "how"
      end;

      { Name = "it looks";
         Type = "Configuration";
      };
   };
}

Preview image

Features
  • The core idea is minimal, offering ease of use without complex abstractions.
  • Allows creating instance hierarchies that are easy to visualize at runtime, making it clear what instances will be created.
  • Redundant Instance Creation with _count
  • Ability to do very specific initializations trough _init
Summary

This is a very lightweight “framework” which provides ability to create readable hierarchies without bloatware code. Basically a “minimum viable solution”.

It is simple yet provides a really good foundation for features you might want to add.

Guide

Structure

all tables in the hierarchy should have a Type index:

local example = { Type = "Folder";
   { Type = "Configuration"
      { Type = "Frame"
         
      };
   };
}

To build, simply put the table into the function:

local buildInstance = require(InstanceBuilder)
local test = buildInstance(example) -- it will also return reference to the built instance

Or you can directly build, like:

buildInstance{ Type = "Folder";
   { Type = "Configuration"
      { Type = "Frame"
         
      };
   };
}

you can also put an actual instance instead of a type string in case you are building from a pre-existing instance:

local example = { Type = workspace:FindFirstChildOfClass("BasePart")

}

Note:
All instances inside the hierarchy are created individually, not through clone. This is done to avoid issues with _init, with the exception being if you put Type as an instance, that would be cloned.

This is required since you can’t really do a hierarchy without creating an instance of any type.

Instance params

you can change instance parameters just as you would usually trough Instance.new:

local example = { Name = "TestPart" -- I highly suggest to put the names on the same line as you open the table, this is mostly done for convenient reading
   Type = "Part"

   Parent = workspace;
   Position = Vector3.new(12,10,0);

   { Type = "NumberValue";
      Value = 10; 
      -- no need for a parent param since we already build under the Part
   };
}

If instead you put Type as an instance, it will override the properties you specified in the table, with the exception being Parent since roblox itself resets it.

Note:
Hierarchy will always build their properties and children first before setting their own parent to a specified instance if Parent index is specified

_init

you can specify a function to be run after the whole hierarchy is created:

local example = { Name = "Events";
   Type = "Folder"

   Parent = game:GetService("ReplicatedStorage");
   { Name = "PlayerRemote";
      Type = "RemoteEvent"

      _init = function(self:RemoteEvent)
         self.OnClientEvent:Connect(function()
            print("hello!")
         end)
      end; 
   };
}

It will run in deferred mode. Which is on the next frame.

_count

you can specify the amount of individual instances to create through _count:

local example = { Name = "PartStorage";
   Type = "Folder";

   Parent = workspace;
   { Type = "Part";
      _count = 1000;
   };
}

you can also combine it with the _init to have some custom behavior for generating properties:

local example = { Name = "PartStorage";
   Type = "Folder";

   Parent = workspace;
   { Type = "Part";
      Size = Vector3.new(0.5,0.5,0.5);

      _count = 1000;
      _init = function(self:Part,id:number) -- if _count is specified, _init will have a second paramater which corresponds to it's creation place in hierarchy
         local x,y = id % 100,math.floor(id*0.01)
         self.Position = Vector3.new(x,0,y) -- generate parts of 100 by 100 grid
         self.Name = `Part_{x}-{y}`
      end;
   };
}

End notes

You can see more examples at Github

This module is distributed “as is.”, meaning you are free to change whatever you would want to

Report all issues at github and I will take a look

7 Likes

1.0.1

  • Fixed issue with _init running twice when _count is present

This works great! What id like to see though is a performance comparison between using HierarchyBuilder and just Instance:Clone or using the Instance library, overall pretty cool though

I really couldn’t precisely benchmark my module. But from what I have gotten, I can tell you that it is not much different from individual instance creation.

You can try it to see for yourself:

local t:number
t = os.clock()
--individual
local a = Instance.new("Part")
a.Name = "test"

local g = Instance.new("Folder")
g.Name = "test2"
g.Parent = a

local b = Instance.new("ImageLabel")
b.Name = "asdas"
b.Size = UDim2.fromScale(1,1)
b.Parent = g

a.Parent = workspace

print(os.clock()-t)
task.wait()
t = os.clock()
--buildInstance

buildInstance{ Name = "test";
	Type = "Part";
	Parent = workspace;
	
	{ Type = "Folder";
		Name = "test2";
		
		{ Name = "asdas";
			Type = "ImageLabel";
			Size = UDim2.fromScale(1,1);
		}
	}
}

print(os.clock()-t)