How to weld large objects together?

If you want the core to be the control cell, its going to be the control cell and not much you can do about it other than trying to prevent unbalanced models.

What editor are you talking about?

The editor is what the pictures from the original post were from. Its where the user designs their organism, where physics is not needed since everything is static.

1 Like

If the user tries to delete a cell that has other cells attached to it, have them verify that they actually want to do that. For the mechanics i suggest you to just delete the other cells that were held on by that one cell to prevent other issues. If you don’t want to do that, you’d have to reconnect them and that is gonna take a lot of time and its gonna have a performance impact.

1 Like

Hmm, or I could go the route that Evolve by @ClanAtlas works (similar to my game, but made in a 2D environment with cubes instead of a 3D environment with spheres), where the user flat-out can’t delete the object. But this may have a high performance cost when trying to delete something, but certainly less than reconnecting everything I suppose.

2 Likes

Yeah so either don’t let them delete it, have them verify that they actually want to delete it and remove the other cells attached or have the whole model basically recomputed.

Alright, I’ll work on an algorithmn for preventing deletion if it effects weld tree, i’ll update you once I think its complete

Alright good luck on the game man

1 Like

Thanks, I’m going to make a Devlog on it soon once I’ve done enough, want me to tag you in the devlog once its posted?

Yeah sure man i wanna see how you figure it out

I made this algorithmn, which loops through each cell’s connections until it eventually hits the core.

excludeCell is the cell that will be deleted, and this function is run to ALL of the cells before the deletion, only if all of the returns from all the cells return true, then excludeCell can be deleted.

Haven’t tested it out yet but the theory works out. Only problem is that this has to loop in EVERY cell (Apart from core obviously) and has to loop until it finds a connection through brute force.

2 Likes

Fixed a few bugs, including non-cells being caught by GetPartsBoundInRadius, and it not actually calling back.

1 Like

studio crashed, there was probably a bug in there

1 Like

Fixed the code, but a possible problem

For large amount of cells like here, it can take upto 200 ms just to proccess if a cell can be deleted

Output shows the delay in ms. It prints every time a new cell is added

It practically runs through every cell and loops through all of its connections until it hits core.

Edit: I theorized a solution, where parts already proccessed to connect to the core are saved into a dictionary, and if a cell borders one of those, it is certain that its connected

>90% FASTER

After implementing cached paths, where cells that have already been calculated to have an indirect connection to Core, which if a cell is bordering one of these cells known to be indirectly connected to the core, then it knows that that cell is also indirectly connected.

This alongside stopping to check cells if a false is detected, is a very good optimization to the system

Could you show your code? I can try to optimize it further.

local function CheckIndirectConnection(checkCell, excludeCell, extraCache:{}?)
	local startos = os.clock()
	local alreadyListed = {excludeCell, leditorFol.cnct, leditorFol.temp}
	local connected = false
	
	local deteCache = extraCache or {}

	local function proccess(cell, notaddlist)
		if deteCache[cell] then connected = true return end
		table.insert(alreadyListed, cell)
		
		local size : Vector3 = cell.PrimaryPart.Size
		local radius = math.max(size.X, size.Y, size.Z) / 2
		
		local olp = OverlapParams.new()
		olp.FilterType = Enum.RaycastFilterType.Exclude
		olp.FilterDescendantsInstances = alreadyListed
		
		local inArea = workspace:GetPartBoundsInRadius(cell:GetPivot().Position, radius + .1, olp)
		local listedModels = {}
		for _, part in pairs(inArea) do
			local cellModel = FindModelParentOfCell(part)
			if cellModel.Name == "Core" then connected = true break end
			if not listedModels[cellModel] then
				listedModels[cellModel] = true
				if deteCache[cellModel] then connected = true break end
				proccess(cellModel)
			end
		end 
	end
	proccess(checkCell)
	return connected
end

local function CIC_all(list, excludeCell)
	local cancel = true
	local cachedSaved = {}
	for _, cell in pairs(list) do
		if cell.Name == "Core" then 
		else

			local bool = CheckIndirectConnection(cell, excludeCell, cachedSaved)
			if bool then
				cachedSaved[cell] = true
			else
				cancel = false
				break
			end
		end
	end
	return cancel
end

CIC_all (CheckIndirecConnection all) is the function called to check if removing a cell would effect any cell’s connection

oh yeah btw the benchmarks from the previous two screenshots are in ms, never mentioned that as I assumed it was self-explanatory

You can reuse overlapParams and also instead of doing:

if value == "alright" then

else
	-- Main code

You can do:

if value ~= "alright" then
	-- Main code

Code:

local function CheckIndirectConnection(checkCell, excludeCell, extraCache:{}?)
	local startos = os.clock()
	local alreadyListed = {excludeCell, leditorFol.cnct, leditorFol.temp}
	local connected = false

	local deteCache = extraCache or {}
	
	local olp = OverlapParams.new()
	olp.FilterType = Enum.RaycastFilterType.Exclude

	local function proccess(cell, notaddlist)
		if deteCache[cell] then connected = true return end
		table.insert(alreadyListed, cell)

		local size : Vector3 = cell.PrimaryPart.Size
		local radius = math.max(size.X, size.Y, size.Z) / 2

		olp.FilterDescendantsInstances = alreadyListed

		local inArea = workspace:GetPartBoundsInRadius(cell:GetPivot().Position, radius + .1, olp)
		local listedModels = {}
		for _, part in pairs(inArea) do
			local cellModel = FindModelParentOfCell(part)
			if cellModel.Name == "Core" then connected = true break end
			if not listedModels[cellModel] then
				listedModels[cellModel] = true
				if deteCache[cellModel] then connected = true break end
				proccess(cellModel)
			end
		end 
	end
	proccess(checkCell)
	return connected
end

local function CIC_all(list, excludeCell)
	local cancel = true
	local cachedSaved = {}
	for _, cell in pairs(list) do
		if cell.Name ~= "Core" then 
			local bool = CheckIndirectConnection(cell, excludeCell, cachedSaved)
			if bool then
				cachedSaved[cell] = true
			else
				cancel = false
				break
			end
		end
	end
	return cancel
end

You could also try using native code generation.

1 Like

Parallel Luau may also be useful.

The editor script was over 500 lines long but I decided to rewrite the entire script anew for readiability, performance and reliability issues.

Will update soon on the new algorithmn I will put inplace!