How should I make a vehicle part repair system?

I want to create a vehicle destroy system. Ok so um its like this, there is a ship in the water and it gets shot by a cannonball. Some parts get destroyed. The ship goes to a repair station and once its at full health, all the destroyed parts are restored. How do I do this?

EDIT: When I mean restored I also mean the parts and their welds.

2 Likes

Put your ship model in the ReplicatedStorage and then just copy it when you want to repair

1 Like

Best way to do that, is to make your boat of of tiny individual parts, together with a Health value.
Once that’s done, you should go create a script where if a cannonball hits that part, it breaks.
(With the usage of BasePart.Touched, explanation here: BasePart | Roblox Creator Documentation)

Then make the ship lose HP.
There is also another way where you could make the usage of velocity magnitude.

The last way is to make the usage of explosions & welds.
(Self explanatory)

To repair a ship’s HP, make a clone in ReplicatedStorage (or ServerStorage), and just make it copy to the destroyed ship once it’s repaired.

Hope this helped!
(I’ve got one of these systems myself, but for cars, to simulate realistic destruction, but without a repair system.)

1 Like

This is a pretty difficult system depending on how you set it up. I believe the simpler system is to replace the entire vehicle @kpmanaiden and @Ready2XD said.

Personally I was aiming at replicating the armoured patrol system which had special rules like the parts were repaired starting from the root part.

Either way you need to have these things Data on the original structure, which is for every part it needs to have a dictionary of connected parts, with welds you can use getConnectedParts. You will need to store this data with all the parts within the build in one massive dictionary.

This is for my repair system, just to identify the closest destroyed, or damaged part.

  1. Then starting from the root part perform flood fill and search all the parts around it.

  2. If the searched part is destroyed or damaged then begin the repairing process

  3. Repeat until all parts are repaired

Here is the flood fill structure

FloodFill
local findClosestDeadAndDamagedArmorEntity
findClosestDeadAndDamagedArmorEntity =  function (armorEntity,ignoreList)

--avoid checking through the same armor entity
	ignoreList = ignoreList or {}
	if ignoreList[armorEntity] then
		return
	end
	ignoreList[armorEntity] = armorEntity

	--checks current entity if dead or damaged, prioritizing dead
	--Has not get because it's a tag with no value retunred
	local isDead = world.Has(armorEntity,IsDeadComponent) -- My system to detect if parts are damaged
	if isDead then
		return armorEntity
	end

	local isDamaged = ServerWorldModule.isEntityDamaged(armorEntity)
	if isDamaged then
		return armorEntity
	end
	
	--search other connected parts
	local partsConnected = world.Get(armorEntity, PartConnectivityComponent)
	if partsConnected == nil then
		warn("No connected parts?")
		return nil
	end

	local aliveArmorEntity
	for _, part in pairs(partsConnected) do
		local armorEntity = ServerWorldModule.getArmorEntityFromPart(part) 
		if ignoreList[armorEntity] then
			continue
		end
		if not armorEntity then
			continue
		end
		local armorEntityToReturn = findClosestDeadAndDamagedArmorEntity(armorEntity,ignoreList) -- Perform recursion
		if armorEntityToReturn then
			aliveArmorEntity = armorEntityToReturn
			-- return armorEntityToReturn
		end	
	end
	return aliveArmorEntity
	-- warn("No armor entities found?") -- end of search no other connected parts should be ok
end

What you do once you found the destroyed part is an entirely different story. For a weld system you probably need to remember the specific weld from the current part to the next part and the C0 and C1 settings used to position it relative to each other. Also you will need to store the original part as a clone in order to avoid using :Clone() on a destroyed instance.

Personally, for my system I used an odd choice to make my parts invisible and noncollidable in order to avoid doing the above C0 and C1 math. But then there is another issue of making stuff like arms fall off when the upper arm is destroyed so I had to do flood fill again and detect that. This works but theres a bug with my implementation so yeah.

3 Likes

Rather than breaking off parts from the ship - you could simply hide them.

Let’s say the Mast of your ship gets damaged to the point of brekaing, and all parts of the ship have a NumberValue called Integrity

function CreateDebris(obj)		--create a duplicate part that will enact as the 'breaking' part of the ship
	local debris = obj:Clone()
	debris.Parent = workspace
	debris.Transparency = 0
	debris.CanCollide = true
	game.Debris:AddItem(debris,120) -- clears up after 2 minutes
end

function Repair(obj)		-- do something like this when you want to repair a part of the ship.
	obj.Integrity = 100
	obj.Transparency = 1
	obj.CanCollide = true
end


local mast = ship.Mast
if (mast.Integrity.Value <= 0) then -- your mast will still exist as is, but just be hidden.
	mast.Transparency = 1
	mast.CanCollide = false
	CreateDebris(mast)
end


1 Like

Sorry to bother you but how do I store the Integrity of all the parts efficiently.

Wait one more thing, what if I hit only the mast instead of sails. The sails would be floating as only the mast is broken. Any solution to that?