Decided to code a weld function since Luduvo's welding is broken

Since luduvo fixed AMD support, I’ve finally been able to use luduvo studio. I tried making some stuff, but I found that welding is broken. So I thought it would be a nice first scripting project in luduvo to make a welding script. I wasn’t able to stress test this setup in studio because luduvo studio decided that my character shouldn’t move around, so I’m just stuck floating in the air forever. But here is what I came up with:

Edit: THE CHARACTER IS STILL BROKEN. I’ve resorted to putting parts with varying mass above the welded groups to test if it breaks. And now it’s not just the character breaking, it studio every time I try and load a project… Trying to work with Luduvo studio is just cancerous at this point

V1, not very good
local weldPart1 = self

weldPart2 = weldPart1.Parent:FindFirstChild("weldPart2") -- the name of the part you want to weld to. In this instance, both parts are in a group, and the part with the server script is named "weldPart1" and the other part is named "weldPart2".

local difference = -4		-- weldPart2 is -4 studs away from weldPart2 on the x-axis. if you have more differences, that means more difference variables :  )

function Update(dt)
   if weldPart2 and weldPart2.Name == "weldPart2" then
      local pos = weldPart1.Position
      local rot = weldPart1.Orientation

	  weldPart2.Position = Vector3.new(pos.X + difference, pos.Y, pos.Z) -- move the welded part to the right spot using the difference variables
	  weldPart2.Orientation = rot -- update orientation. Probably needs fixing.
   end
end
V2, Automatic welding
--[[
			Steps on how to use it:
			1: insert server script into the model that has all the parts you want welded in.
			2: paste the script into the server script
			3: enjoy some pseudo-welding

			Note: Before doing all of this, I didn't even check to see if you can weld things using Luduvo's welding system that's already in place with Lua code. And I think that the only thing broken about it is the user interface, not the underlying code within it. So I think the code I made is basically useless, so maybe I'll look into just making an automatic welding script with code that uses Luduvo's actual welding system and not my own crappy version. I haven't tested to see if that way works, I just read someone on the forums that said you can do it that way.
--]]

local partTable = {} -- stores da parts
local partOffsets = {} -- Dictionary to store offsets
local isInitialized = false

local function scanForParts(instance)
   for i, child in instance:GetChildren() do
      local subChildren = child:GetChildren()

       if #subChildren == 0 then -- if it has 0 children, then it has to be a part, not a group.
           table.insert(partTable, child)
       else
           scanForParts(child) -- it has some parts in it, I guess we assume it's a group. Now, tell em' to bring out the whole ocean.
       end
   end
end

scanForParts(self)

--================================================================================--

-- Main logic & setup:

--================================================================================--

local CUSTOM_ORIGIN_NAME = "origin" -- You input the name of the part you want to have collisions and physics here!!!!!!!!!!!!!!!!!!11!1!1
local originPart = nil

for i, part in ipairs(partTable) do
   if part.Name == CUSTOM_ORIGIN_NAME then
      originPart = part
      table.remove(partTable, i) -- remove the custom origin part from the table so it doesn't calculate an offset to itself, because that would be dumb.
      break
   end
end

if not originPart then -- picks a random origin part if the one you chose cannot be found...
   originPart = table.remove(partTable, 1)
      if originPart then
         warn(originPart.Name .. " cannot be found. Did you spell it right?")
         warn("Due to the potential unwanted origin part, you may need to turn all collider values to automatic in your group...")
      end
end

if originPart then -- this part basically preps the orientation for trigonometry math, finds the distance difference between the secondaryPart and the originPart, and all that mumbo jumbo.
   local originPos = originPart.Position
   local originRot = originPart.Orientation

   local startRadY = math.rad(originRot.Y) -- Convert starting angle to radians
   local cosY = math.cos(startRadY)
   local sinY = math.sin(startRadY)

   for i = 1, #partTable do
       local secondaryPart = partTable[i]
       if secondaryPart then
           local worldPosOffset = secondaryPart.Position - originPos
        
	   	   local localX = worldPosOffset.X * cosY + worldPosOffset.Z * sinY
           local localZ = -worldPosOffset.X * sinY + worldPosOffset.Z * cosY
        
           local posOffset = Vector3.new(localX, worldPosOffset.Y, localZ)
           local rotOffset = secondaryPart.Orientation - originRot
		
			secondaryPart.Anchored = true -- allows to prioritize physics for the origin part, and not the secondary parts.
			secondaryPart.Collider = "None" -- fixes part collisions which can glitch out the unanchored object that is welded together.
        
           partOffsets[secondaryPart] = {
               posOffset = posOffset,
               rotOffset = rotOffset
           }
       end
   end
end

function Update(dt) -- this is the core updater where all the logic does the logic stuff for every single frame.
   if originPart then
      local originPos = originPart.Position
      local originRot = originPart.Orientation

      local currentRadY = math.rad(originRot.Y) -- convert the current orientation to radians for the trigonometry functions for the origin part
      local cosY = math.cos(currentRadY)
      local sinY = math.sin(currentRadY)
	
      if not isInitialized then
         for secondaryPart, _ in pairs(partOffsets) do
            secondaryPart.Anchored = true -- allows to prioritize physics for the origin part, and not the secondary parts a second time just to be sure it actually did it...
            secondaryPart.Collider = "None" -- fixes part collisions which can glitch out the unanchored object that is welded together a second time just to be sure it actually did it...
         end
         isInitialized = true
      end
	
      for secondaryPart, data in pairs(partOffsets) do
         local localOffset = data.posOffset
		
         local rotatedX = localOffset.X * cosY - localOffset.Z * sinY -- rotates the local offsets into the world space to match the rotation direction
         local rotatedZ = localOffset.X * sinY + localOffset.Z * cosY -- I hated this part.
		
         secondaryPart.Position = Vector3.new(originPos.X + rotatedX, originPos.Y + localOffset.Y, originPos.Z + rotatedZ)
		
         secondaryPart.Orientation = originRot + data.rotOffset
	   
      end
   end
end
What using Luduvo's welding system would look like
--[[
		So, as you can see it's much simpler to do it this way, coding wise. But when you use it, you will find that 
		it is way less stable than the system I have in place in V2. If you have large builds in place with 
		overlapping parts, the model will simply fling apart and glitch out. 
		You could hypothetically fix this by removing collisions for the parts in the model, but that doesn't seem 
		to work with this.

		So, the takeaway is to just use V2 of my code, this is simply an example of how it would work. 
		Who knows, this code might be useful some day if they ever decide to fix welding.
--]]

local partTable = {}

local function scanForParts(instance)
for i, child in instance:GetChildren() do
local subChildren = child:GetChildren()

    if #subChildren == 0 then
        table.insert(partTable, child)
    else
        scanForParts(child)
    end
end

end

scanForParts(self)

local main = partTable[1]

local function CreateWeldsAndWeld()

if not main then return end

for i, Part in ipairs(partTable) do
	if Part ~= main then
		Part:AddComponent("Weld")
		Part.BreakForce = 0
		Part.Other = main
	end
end

end

CreateWeldsAndWeld()
2 Likes

I really don’t like how such a fundamental functionality of Luduvo is just straight up broken. I do hope they fix this soon, as people can’t make anywhere close to “advanced” level games with the current FUNCTIONAL elements.

I do understand that Luduvo is relatively small compared to a massive conglomerate like Big ‘R’, but this I feel is an urgent problem that could make the already tiny player count shrink even more, due to the lack of more “custom” experiences.

1 Like

Well I think they have a very small developer team, but literally all they need to do to fix this problem is update the user interface within Luduvo studio. Such a simple problem to fix, but they probably have more important things to fix right now because they just released Luduvo to the public very recently.

They also mentioned me in a recent patch note, but didn’t address the issue correctly… they had a link to one of my posts about how the user interface was broken, and said “Creating a weld joint between a moving part and an anchored part no longer crashes.” Unable to weld things in Luduvo studio if you read that forum post, I never really mention anything about creating a weld joint between a moving part and an anchored part. Makes me think they were using ai, but who knows.

But anyways, at game creators can use the script I made, and it’s most likely better than the weld system they have/will have.

1 Like