Upcoming Changes to Destroy()

They can’t. Did you read my post or OP? They said things deleted on the server are deleted on the client.

Oops, the initial post displayed this so I got confused

let me see

Mm that is the same thing? I don’t understand what does that have to do with destroy replication from client to server not server to client

The replication to Destroy is one way I believe. Server to client only, and not the other way around. If an exploiter deletes something on the client, nothing will happen to the server. I believe you are confused.

If anyone can prove this, I’d be happy.

1 Like

I’m not sure you get me brother, create a value in your character on characteradded then go into playtest, delete it manually from the explorer on the client side then switch over to server side and it will replicate that is the problem you can test it yourself, as Max said above he tested it too.

1 Like

@Serrattor is saying that when you destroy an object under the character using a LocalScript (from the client in other words), it replicates to the server.

How the server sees it before the client destroys it:

After the client delete those objects this is what the server sees:

:red_circle: This is indeed an issue, if it were to be parts ok then, but anything else like deleting ValueBases, BindableEvents, among others, even Scripts is just too much.

5 Likes

I have just realised it works with bindableevents/functions too and I’m using like 3 of them in the character why is this a thingggg.
(I can’t use defensive mechanisms here either since some of my code looks like this)

plr.Character.Actions:Fire("AddStun",{
--stats n stuff
})

target.Actions:Fire("AddStun",{
--stats n stuff
})

used hundreds of times too, if for example the target deletes their actions event then the code errors and the character never gets unstunned, before assumptive workarounds I do have a duration setting with a task.delay set up on the bindable but for some cases I’m setting duration to math.huge which doesn’t trigger the task.delay so I can manually unstun the player after a randomized time in some cases.

This is literally a huge security issue at this point and I have to get to migrating to the player instance again, honestly…

1 Like

i literally just thought this would remove Destroy() instantly and we would have to drag it into the void

But anyways, thank you roblox team! I support you :grin:

No. It means that the setting ReplicateInstanceDestroySetting will be removed.

I’ve written a few quick scripts in the past that did; I always expected them to eventually break without notification. The fact that we’ve gotten two announcements about this surprises me. Strange caveats such as these make the engine unintuitive, and are precisely the reason why concerns of memory leakage are so common.

3 Likes

@SubtotalAnt8185

All instances that are descendants of the Player's .Character property (yep, all) can be deleted by them and the deletion will replicate to the server (for some reason). I’m still very much so not sure why this is actually the case, it doesn’t really even make sense from a backwards compatibility standpoint, but this is basically the premise behind “FE god mode”…

An exploiter will locally delete, then replace their Humanoid, and because there is no Humanoid, the player can’t die.

Last time I checked this actually applies to every descendant of the character. Joints, parts, Humanoids, the Humanoid’s animator, scripts, local scripts, tools, and even things in those tools. It’s actually quite obnoxious behavior and I’m hoping that it eventually changes.

Network ownership and this are entirely unrelated, it’s simply a very questionable quirk for player characters, which means it’s not usually a good idea to be putting any essential stuff into a player’s character (or into tools which is especially limiting :slightly_frowning_face:)

P.s. this has been an issue for multiple years, it’s always existed as long as FE has been around as far as I am aware.

7 Likes

This is actually intentional for whatever reason. I knew this existed ever since I actually messed around with it, and it’s quite a good feature. This also applies to BaseParts with the NetworkOwner set to the player.

1 Like

You could make a script check when a child is removed from a player’s character, and kill them if it is

This is a lazy example and it will cause memory leaks because I don’t disconnect the connections if the player leaves or dies so use an event handler PLEASe

local Cooldown = {}
local bannedObjects = {"BasePart","Script","Humanoid","Folder"}

local function isBanned(object)--please tell me there is a function that automatically does this
	for i,v in next, bannedObjects do
		if object:IsA(v) then
			return true
		end
	end
	return false
end

local playerService = game:GetService("Players")
playerService.PlayerAdded:Connect(function(Player)
	local Name = Player.Name
	Player.CharacterAdded:Connect(function(Character)
		Character.ChildRemoved:Connect(function(Child)
			if not Cooldown[Name] and isBanned(Child) then
				Cooldown[Name]=true
				Character:BreakJoints()
				Player.CharacterAppearanceLoaded:Wait()
				Cooldown[Name] = nil
			end
		end)
	end)
end)
playerService.PlayerRemoving:Connect(function(Player)
	local Name = Player.Name
	Cooldown[Name] = nil
end)

2 Likes

Odd enough we can’t delete the clothing haha. They could do the same for other Instances under character, but whatever. The best solution right now is to not put anything important under a character.

It does not apply to BaseParts with the network owner set, that’s entirely separate. A part’s network owner is simply who is simulating the physics, it has nothing to do with anything beyond physics replication (and things like .Changed events for CFrame don’t replicate directly because no property changes replicate, they just replicate as physics to the server).

The behaviour shouldn’t exist. While maybe at one point it was intended, it isn’t really a “feature” persay, it’s not something you want to rely on. It’s probably either a bandaid fix for some old issue that FE at one point had (and probably no longer has), or its an oversight, but, in any case, it’s a security flaw and an annoyance, and it eventually will have to go. You definitely shouldn’t be relying on it at all, or your game might break if and when it eventually is removed.

@uwuCulturist The problem with this is you might still delete some things server-side, and, things like FallenPartsDestroyHeight will delete parts in the player. It’s probably likely that the Parent property won’t fire a .Changed event so you could try filtering server-side changes by GetPropertyChangedSignal("Parent") and I’m betting a .Destroying event won’t replicate either, but I’m just speculating on that, that’s my assumption based on how other similar things work in the engine. In any case you could probably test which events fire and if there is an event that won’t fire server-sided by the client deleting the descendant, but will by the server deleting it, that is a way to differentiate on the server between a client deleting a character descendant and the server doing it.

That’s also a way you can filter out server-side teleports when doing anti-cheat, since .CFrame and .Position won’t fire changed events (the player can only teleport themselves because they have network ownership and thus have authority over their character’s physics, which isn’t replicated through .Changed events so they don’t fire on the server unless server-side code is setting them)

7 Likes

I actually just made a post about this recently.

Almost seems as if Roblox took a pretty nasty design implementation and swept it under a rug, for who knows how long.

1 Like

Yep, if I remember correctly, for some reason something about how accessories replicate in general changed about 1-3 years ago (don’t really remember when), which I recall being around when HumanoidDescriptions were added. This effects other things too, for example (this is probably an unintentional side effect actually) clients can no longer drop accessories even though there used to be a feature where pressing = would drop your accessories.

I believe this hat dropping behaviour even still exists in the engine because I’ve seen it replicated in some Roblox games under specific circumstances (ones with their own methods of giving players accessories, like the bloxy awards event from two or three years ago) but it doesn’t work on vanilla Roblox avatars because of that weird change (whatever it is that makes accessories special)

My speculation was that the client and server have two different accessory instances, but, that’s just speculation. In any case accessories do seem to have inconsistent replication compared to other instances.

P.s. tool dropping is similar and is still something the client can do (even if CanBeDropped is off), if you have a tool, and you move it to the workspace or the player’s backpack on the client, it will replicate, but anywhere else and it won’t. And because of the descendant thing, you can still delete tools client-side if they’re held by the player and it will replicate (last time I checked, obviously things change so that might not be true anymore but probably is).

3 Likes

It’s been known about and discussed for a while but it’s relevant enough to this change people are talking about it more I guess but yeah. I hope that people’s sudden interest here gets it fixed :smile:

1 Like

Unexperienced scripters
Prolly the same people who dont use task.wait

Try setting the player’s parent to nil, or destroying it manually.