Dealing with broken ROBLOX gears in your game / Preventing damage/death with forcefield

I run a game that allows users to insert ROBLOX catalog gears by Gear ID (though, filtered through a blacklist). As time goes on, more and more of these gears end up breaking. Whether it spawns in as a static item that does nothing, kills players even with forcefield, fling players across a map, or whether they can for some reason move, destroy, and duplicate bricks in the game, I was curious if there was a simpler/quicker way of fixing these gears on a massive level as opposed to individually identifying, and editing the gears manually. Whether there are scripters that I could commission to do this for me, or pay to use their methods. I am looking to make gears more optimised and compatible in my game.

I do know that for popular broken gears, there are many free models that claim to be “fixed” versions of gears. Although I don’t doubt that some of these are real and work properly without any issues, I don’t like the idea of inserting dozens of random free models and really anything from the free model store that isn’t trusted. I have funds to commission people for patching these gears, but don’t know if that is something that people necessarily do, (not to make this a collaboration topic).

I’m also wondering if forcefield truly is the best solution to prevent players from dying or being affected by gears. There are some gears that can just somehow kill/damage and remove parts from other players regardless if they have forcefield or not. If there is a solution to making players actually immortal and unaffected by these gears, that would eliminate a large majourity of the gears that might need patching otherwise.

4 Likes

There are several gears I’m aware of that opt to subtract health directly instead of using Humanoid:TakeDamage(), which accounts for forcefields. I would suggest using player collision filtering in addition to forcefields so as to prevent this in physics-based gears like swords. This article might be useful for implementing that.
https://developer.roblox.com/en-us/articles/Player-Player-Collisions
This isn’t a perfect solution of course but it should work in most cases. Hope this helps!

2 Likes

Would this subsequently make these physics-based gears not work if a player doesn’t have a forcefield? I have a PvP On and a PvP Off function which adds and removes ForceField, and do still want these gears to be technically functional so long as the other player has PvP turned on.

I also noticed that many gears are only functional using R6 and vise versa. There is a function in the game which players can use to convert to R6 and R15 manually, but don’t know if there is any way to identify a gears compatibility and cause for that function to trigger.

Collision filtering can be toggled on or off for each player so that shouldn’t be an issue. For example, you could have a collision group for PvP On, another for PvP Off, and leave the default collision group for everything else. Simply move the player to the corresponding group and they should be able to collide with just the players in that group. I’d be happy to script a basic implementation for you if that helps.

As for R15 and R6, there isn’t a way to know for sure which one it works with, but you can make really good guesses. Something like keyword search within the gear for names containing “R15” and maybe the Catalog API for the time it was last updated.

EDIT:
Actually, this might be a simpler solution. At first I thought this was a dumb idea but turns out it works. Basically just give them infinite health and force max health every time it’s changed.

-- assuming there's already a player variable
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")

humanoid.MaxHealth = math.huge	-- give player infinite health
humanoid.RequiresNeck = false	-- for gears that kill by breaking joints
humanoid.BreakJointsOnDeath = false
local function fillHealth() humanoid.Health = humanoid.MaxHealth end
fillHealth()	-- make sure that the player's current health is full	

-- instantly refill health when it gets changed
humanoid:GetPropertyChangedSignal("Health"):Connect(fillHealth)		

For turning PvP back on, you would have to revert it and disconnect that event. The only exception I can think of is if a gear does something like humanoid.Health = 0 in a super laggy server, but I doubt there are any that do that.

2 Likes

Sorry for such a late response - I really appreciate your help and resourcefulness. Glad to have people willing to help an ol’ clueless stranger without expecting anything in return.

Firstly I’ll go off of your original message. I’ve been considering collision filtering as a way of preventing fling exploits, as I feel it is the only reliable option to stop them in a game like mine. Flinging has become a big issue in my game, and collisions is on the list of things that need to be worked on. Perhaps a bit out of the topic of discussion, but is there any way to disable player collisions for everyone, and still have physics based gears work? I have some faint ideas but don’t know if they’re feasible.

I do like the idea of checking the Catalog API for updated gears past a certain date. I feel a few outliers shouldn’t be difficult to tweak manually as well, at least when opposed to not having the function at all.

This script idea does help me a bunch. I can definitely research some properties and come up with a solid script to try out that should hopefully tackle many of my gear related issues. Even having properties to connect to definitely gave me some ideas for some ways to prevent gears from doing non-fatal but obstructive things. It wouldn’t feel right for you to script any full implementation for me though haha. It may take me 10x longer but I love learning as I go and making mistakes that I’ll hopefully learn from. Advice and pointers is all I can ask for. Thank you for that. :slight_smile:

1 Like

No problem! And I would be more than happy to do a full implementation for you, since this could have applications beyond your game as well. I suppose I could accept pay if it makes you feel better.

Anyway, you’re welcome to message me directly if you prefer, because I’d rather not fill up your post with just my replies. :laughing:

I think this could absolutely work, although it may get a bit complicated. Lets say each player is in their own collision group save for their gears, the gears themselves go in a separate group. If the gears can collide with every player, but players can’t collide with each other, that should work as you described. Hopefully this diagram can explain it better:

Of course I left PvP out of this to keep it simple, but it’s the same idea, just with those green lines being red for players with PvP off. I’ve never tested this myself but it seems feasible in theory.

After messing around with the script you provided I was able to implement it and distinguish between the two PvP options. However, I did realise that ‘RequiresNeck’ and ‘BreakJointsOnDeath’ aren’t very necessary in practice considering once a gear breaks joints, the player is left with a “dead” and nonfunctional character that just doesn’t respawn. It’s unfortunate that there’s no property to prevent joints from breaking like that all together. Lots of “solutions” I found are talking about, “well if you don’t want joints to be broken then don’t write scripts that break them”, which doesn’t apply when working with ROBLOX gears that are inserted as requested instead of kept in storage. It seems like most gears that kill with ForceField are done by BreakJoints and every thread I’ve seen that inquires about it are shut down with that response. Not sure if there is a way to prevent it.

I’m honestly stumped on this one. I suppose you could either set the joint’s parent back or clone it right before it’s destroyed, so that it’s almost as if it never broke. I don’t know if either of these are fast enough to stop the humanoid from registering the death, but it’s worth a try.

Parent reset method:

local initialParent = joint.Parent

local function onAncestryChanged(_, parent)
   -- a nil value for parent means that the joint was destroyed
   if not parent then
      -- set the parent back to the initial one
      joint.Parent = initialParent
   end
end

-- check whenever the joint's parent changes
joint.AncestryChanged:Connect(onAncestryChanged)

Cloning method:
Subject to memory leaks if you’re not careful so only try this one if the first method doesn’t work.

local initialParent = joint.Parent
joint.Archivable = true    -- allow for cloning
local initial = joint:Clone()   -- preserve the joint in its initial state in case its properties change later on

local function onAncestryChanged(_, parent)
   -- a nil value for parent means that the joint was destroyed
   if not parent then
      -- make an exact copy of the joint and put it under the same parent
      local clone = initial:Clone()
      clone.Parent = initialParent

      -- hook up the event to the new joint
      clone.AncestryChanged:Connect(onAncestryChanged)
   end
end

-- check whenever the joint's parent changes
joint.AncestryChanged:Connect(onAncestryChanged)
1 Like

Here is the barebones implementation of the PvP collision system I outlined earlier. Anyone else who wants to use this is welcome to do so as well.
PvPCollision.rbxm (26.2 KB)

The only things you need to do for setup is place the script in ServerScriptService and enable Workspace.TouchesUseCollisionGroups in the Properties tab. After that’s done, run it and you should see this:

Once that works as intended, feel free to mess around with the script and incorporate it into your own system. I tried to make it as straightforward as possible, but don’t hesitate to ask questions if you get stuck.

After testing this for a bit, I realized that my last explanation was a little off. You don’t need each player in their own collision group, a PvP On group and a PvP Off group still works in the case of disabling all player collisions, as long as each group can’t collide with itself. I was also wrong about the gears. There needs to be two groups for gears depending on if the wielder has PvP on or off. That way, players with PvP off cannot affect those with PvP on. All of this has been corrected in the script.

3 Likes