Undestructable Part

Hi there, so i’ve experience this weird bug when destroying a part, the part actually gets destroyed it even prints nil when printing its .Parent but the part actually still exist in the workspace.


here’s the code if needed:
Server:

local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local ServerScriptService = game:GetService("ServerScriptService")

local packages = ReplicatedStorage.Packages

local Network = require(ServerScriptService.ServerModules.Network)
local Knit = require(packages.Knit)
local TableUtil = require(packages.TableUtil)

local FISH_DATA = {}
local SPAWN_RATE = 2 --2
local MAX_DIST = 10
local OBJECT_DISTANCE = 5

local MainService = Knit.CreateService({
	Name = "MainService",
	Client = {},
})

function MainService:KnitInit()
	Players.PlayerAdded:Connect(function(player)
		for _, v in FISH_DATA do
			Network.AddToStack.Fire(player, v)
		end
	end)
end

function MainService:KnitStart()
	task.spawn(function()
		Players.PlayerAdded:Wait()
		while true do
			self:AddToStack()
			task.wait(SPAWN_RATE)
		end
	end)

	local start_pos = workspace.SpawnPoint.Position
	local end_pos = workspace.EndPoint.Position

	local total_distance = (end_pos - start_pos).Magnitude
	local travel_time = total_distance / 5 * 1000

	-- RunService.Heartbeat:Connect(function(deltaTime)
	-- 	local now = workspace:GetServerTimeNow()

	-- 	for _, v in FISH_DATA do
	-- 		local end_time = travel_time + v._timeCreated
	-- 		local elapsed = now - v._timeCreated
	-- 		local alpha = math.clamp((now - v._timeCreated) / (end_time - v._timeCreated), 0, 1)
	-- 		local pos = start_pos:Lerp(end_pos, alpha)

	-- 		v.Position = pos
	-- 		v.At.WorldPosition = pos

	-- 		if alpha == 1 then
	-- 			v:Destroy()
	-- 			self:RemoveToStack(v.Id)
	-- 		end
	-- 	end
	-- end)

	RunService.PostSimulation:Connect(function(deltaTime)
		local now = DateTime.now().UnixTimestampMillis

		for _, v in FISH_DATA do
			local elapsed = now - v._timeCreated
			local alpha = math.clamp(elapsed / travel_time, 0, 1)
			local pos = start_pos:Lerp(end_pos, alpha)

			v.Position = pos
			v.At.WorldPosition = pos

			if alpha == 1 then
				-- print(v.Id, " took ", elapsed, "s to reach")
				self:RemoveToStack(v.Id)
			end
			-- print(v.Position)
		end
	end)

	Network.Buy.On(function(player, id)
		-- Check if id is valid
		-- Check if the activated object is closer to the player
		-- Check if player has enough money to buy
		-- if yes then remove the object from stack and give it to the player
		-- if no then notify player not enough money
		local data = FISH_DATA[id]
		if not data then
			return
		end
		local humanoid_root_position = player.Character
				and player.Character:FindFirstChild("HumanoidRootPart")
				and player.Character.HumanoidRootPart.Position
			or nil
		if not humanoid_root_position then
			return
		end
		local dist = (data.Position - humanoid_root_position).Magnitude
		if dist > 15 then
			return
		end

		-- local DataService = Knit.GetService("DataService")

		-- if DataService:Get(player, "Cash") < data.Config.Price then
		-- 	return
		-- end

		-- DataService:Update(player, "Cash", function(old)
		-- 	return old - data.Config.Price
		-- end)

		self:RemoveToStack(id)
	end)
end

function MainService:AddToStack()
	-- Pick a random stuff
	-- Set their configs
	-- Spawn
	local at = Instance.new("Attachment")
	at.Parent = workspace.ConveyerPart
	at.Visible = true
	at.WorldPosition = workspace.SpawnPoint.Position

	local data = {
		Id = HttpService:GenerateGUID(false),
		Name = "Fishy",
		Config = {
			Type = "Head",
			Rarity = "Common",
			CurrencyPerSecond = `${1}/s`,
			Price = 1,
		},
		_timeCreated = DateTime.now().UnixTimestampMillis,
		Position = workspace.SpawnPoint.Position,
		At = at,
	}
	FISH_DATA[data.Id] = data
	Network.AddToStack.FireAll(data)
end

function MainService:RemoveToStack(id)
	-- Remove from the stack
	-- Auto add if someone got removed from the stack
	-- print(id, "Got removed!")
	for _, v in FISH_DATA[id] do
		if typeof(v) == "Instance" then
			v:Destroy()
		end
	end
	FISH_DATA[id] = nil
	Network.RemoveToStack.FireAll(id)
end

return MainService

Client:

local Debris = game:GetService("Debris")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local packages = ReplicatedStorage.Packages

local Network = require(ReplicatedStorage.ClientModules.Network)
local Knit = require(packages.Knit)

local server_time_offset = 0
local target_offset = 0
local OFFSET_SMOOTHING_SPEED = 0.01 -- smaller = smoother
local START_CFRAME = CFrame.new(-70.5, 1, -39.5, -4.37113883e-08, 0, -1, 0, 1, 0, 1, 0, -4.37113883e-08)
local END_CFRAME = CFrame.new(70.5, 1, -39.5, 0, 0, -1, 0, 1, 0, 1, 0, 0)

local MainController = Knit.CreateController({
	Name = "MainController",
	ObjectDatas = {},
})

function MainController:KnitInit() end

function MainController:KnitStart()
	Network.AddToStack.On(function(...)
		self:AddToStack(...)
	end)

	Network.RemoveToStack.On(function(...)
		self:RemoveToStack(...)
	end)

	local start_pos = START_CFRAME.Position
	local end_pos = END_CFRAME.Position

	local total_distance = (end_pos - start_pos).Magnitude
	local travel_time = total_distance / 5 * 1000

	-- Fail Syncing
	-- RunService.Heartbeat:Connect(function(deltaTime)
	-- 	local now = workspace:GetServerTimeNow()

	-- 	for _, v in workspace.Objects:GetChildren() do
	-- 		local created_time = v:GetAttribute("_timeCreated")
	-- 		if not created_time then
	-- 			continue
	-- 		end

	-- 		local end_time = travel_time + created_time
	-- 		local elapsed = now - created_time
	-- 		local alpha = math.clamp((now - created_time) / (end_time - created_time), 0, 1)
	-- 		local pos = start_pos:Lerp(end_pos, alpha)

	-- 		v.Position = pos
	-- 		if alpha == 1 then
	-- 			v:Destroy()
	-- 		end
	-- 	end
	-- end)

	-- Idk Yet
	RunService.PostSimulation:Connect(function(deltaTime)
		server_time_offset += (target_offset - server_time_offset) * OFFSET_SMOOTHING_SPEED

		local now = DateTime.now().UnixTimestampMillis + server_time_offset

		for _, v in workspace.Objects:GetChildren() do
			local created_time = v:GetAttribute("_timeCreated")
			if not created_time then
				continue
			end

			local elapsed = now - created_time
			local alpha = math.clamp(elapsed / travel_time, 0, 1)
			local pos = start_pos:Lerp(end_pos, alpha)

			v.Position = pos
			if alpha == 1 then
				v:Destroy()
			end
			-- print(v.Position)
		end
	end)
end

function MainController:AddToStack(objectData)
	-- Spawn Model
	local clientNow = DateTime.now().UnixTimestampMillis
	target_offset = objectData._timeCreated - clientNow

	local template = ReplicatedStorage.Template:Clone()
	template.CFrame = START_CFRAME

	template.BillboardGui.Frame.ObjectName.Text = objectData.Id
	template.BillboardGui.Frame.CurrencyPerSec.Text = objectData.Config.CurrencyPerSecond
	template.BillboardGui.Frame.Price.Text = objectData.Config.Price
	template.BillboardGui.Frame.Rarity.Text = objectData.Config.Rarity

	template.Name = objectData.Id
	template.Parent = workspace.Objects
	template:SetAttribute("_timeCreated", objectData._timeCreated)

	template.ProximityPrompt.Triggered:Connect(function()
		Network.Buy.Fire(objectData.Id)
	end)
end

function MainController:RemoveToStack(id)
	-- Remove Model
	local model = workspace.Objects:FindFirstChild(id)
	if not model then
		return
	end
	-- Add effects if you want
	-- print("YURR")
	model:Destroy()
	print(model.Parent)
end

return MainController

I see you are using find first child.

Without looking at the rest of the code im guessing somehow there are multiple parts with multiple ids.

Therefore 1 id part might get destroyed but another one might still exist.

I would suggest more preferably just using a direct reference with the instance object or recursive loop or :GetChildren untill there are no more children in workspace.

1 Like

Found the issue

Players.PlayerAdded:Connect(function(player)
		for _, v in FISH_DATA do
			Network.AddToStack.Fire(player, v)
		end
	end)
	task.spawn(function()
		Players.PlayerAdded:Wait()
		while true do
			self:AddToStack()
			task.wait(SPAWN_RATE)
		end
	end)

got called twice, thank you tho

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.