Need help with stability system

  1. What do you want to achieve? Keep it simple and clear!
    I would like to make a stability system like from this video : https://www.youtube.com/watch?v=FrYwXCN_TRI&t=208s at 3:24. I need a script to detect when a structure gets destroyed then to check if any other connections are available for the structures above it to be held up by and if not then destroy everything.

  2. What is the issue? Include screenshots / videos if possible!
    I can’t seem to get it working.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried raycasting but it is not effective in this situation because that just removes everything above the destroyed structure and it doesn’t check to see if another structure is holding everything up. I have looked on DevForum and on YouTube for solutions but there was nothing so I decided to create this post.

Here is my script, it is a server script in my “Builds” folder in workspace.

local BuildsFolder = script.Parent
local connections = {}

function isConnectionExist(Structure, Attachment1, Attachment2)
	
	for _, connection in pairs(connections) do
		
		if connection.Structure == Structure then
			
			if (connection.Attachment1 == Attachment1 and connection.Attachment2 == Attachment2) or (connection.Attachment1 == Attachment2 and connection.Attachment2 == Attachment1) then
				
				return true
				
			end
			
		end
		
	end
	
	return false
	
end

function removeConnection(Structure)
	
	for i, connection in ipairs(connections) do
		
		if connection.Structure == Structure then
			
			table.remove(connections, i)
			
			break
			
		end
		
	end
	
end

BuildsFolder.ChildAdded:Connect(function(NewStructure)
	
	for i, v in pairs(NewStructure:GetDescendants()) do
		
		if v:IsA("ObjectValue") and v.Value ~= nil and v.Name == "AttachmentThatIsAttachedToThis" then
			
			local Health = NewStructure:FindFirstChild("Health")
			
			local Attachment1 = v.Parent

			for i, v2 in pairs(BuildsFolder:GetDescendants()) do
				
				if v2 == v.Value then
					
					local Attachment2 = v2
					
					if not isConnectionExist(NewStructure, Attachment1, Attachment2) then
							
						table.insert(connections, {Structure = NewStructure, Attachment1 = Attachment1, Attachment2 = Attachment2})

						print("Added connection : ", connections)
						
					end
					
					Health:GetPropertyChangedSignal("Value"):Connect(function()
						
						if Health.Value <= 0 then
							
							if isConnectionExist(NewStructure, Attachment1, Attachment2) then
								
								removeConnection(NewStructure)
								
								print("Removed connection : ", connections)
								
							end
							
						end
						
					end)
					
				end
				
			end
			
		end
		
	end
	
end)

Each structure has a bunch of values in them but I’m just going to list the important ones. They are “Health” and “Stability” which are IntValues. Then the structure has attachments in the different parts for the snapping feature like from Rust and each attachment has an ObjectValue in it named “AttachmentThatIsAttachedToThis” and the value of that gets set to the attachment its being attached to with a server script that handles the placement. Also the attachment its being attached to ALSO has an “AttachmentThatIsAttachedToThis” ObjectValue in it so it keeps track of which attachments are attached to what. Also each attachment has an attribute named “Placed” for the snapping system so it can check if it has been placed. So technically it shouldn’t be too hard to make the stability system but for some reason I can’t seem to get it working. The script works perfectly by the way, it prints the table after every placement and it has the right attachments and structure names in it and then removes it when the structure’s health dips below 0 or is equal to 0 and I use my destroy tool to set the health to 0 for testing. Any ideas would be lots of help to me, I just need the idea of how I could achieve this and then I can most likely script it myself.

What you can do is use WeldConstraints for connecting platforms. When placing platforms on the floor, you can anchor them, but when placing platforms on platforms, you don’t anchor them. Then when there is nothing to hold the platforms, they will just fall. But in case you don’t want them to fall but instead disappear, you can just check if the AssemblyRootPart is anchored (it is a property of part) and if it isn’t then destroy it.

1 Like

Thats a good idea, but my structures are models not a single part and also they have a custom destroy effect which I want to trigger with the script. So i dont think that will work

Actually wait, I’ll quickly try it but what i dont understand is the assemblyRootpart

AssemblyRootPart is kinda like a part that is considered the main one out of the connected parts. If one of the connected parts is anchored, it automatically becomes the assembly root part, and if not, the engine chooses the most fitting one.

1 Like

Oh ok, thanks clarifying i understand now. Also i tried that solution but it didnt work. I need to find a new way to make the stability system.

Hmm… Here is another thing you can try. Store somewhere which structures are grounded. Then when one structure is destroyed, get all the structures that are connected to it. Then for the parts that are connected, get the parts that are connected to them, and keep doing that until there aren’t more connections or until one of the is grounded. While doing that, put the structures in a table so that you can delete them all instead of doing this code for every single structure.

Here is what a pseudo code would look like:

function Destroy(toBeDestroyed)
     local FirstAdjacent = GetAdjacent(toBeDestroyed)
     for i, firstStructure in FirstAdjacent do
          if IsAlreadyDestroyed(firstStructure) then
               continue
          end
          local Group = {firstStructure}
          local Iterate = {firstStructure}
          local IsGrounded = false
          while not IsGrounded do
               local nextStructure = table.remove(Iterate, 1)
               if not nextStructure then
                    --make code here to destroy all in the Group
               end
               for i, adjacent in GetAdjacent(nextStructure) do
                    if Group[adjacent] then
                         
                    else
                         table.insert(Group, adjacent)
                         table.insert(Iterate, adjacent)
                         if adjacent.Grounded then
                              IsGrounded = true
                              break
                         end
                    end
               end
          end
     end
end

It is only a pseudo code, and there were no tests if it works but it probably should.

EDIT: forgot to mention that the GetAdjacent function should return all connected structures to the passed structure.

1 Like

Thanks for your help but i think i found out how to do it using GetConnectedParts() and then welding each structure to eachother

1 Like