How can I filter out Female Chest UGCs?

I see no obvious easy solution to this. There’s always going to be false positives with whatever method you choose.

What you said here is probably the best:

My recomendation however is to forget about it and move onto something else. I think its more beneficial to allocate more resources into developing the main crux of your game.

3 Likes

Failed completely just because I can’t detect layered clothing because layered clothing is actually on top of the character not where it is on the character.

1 Like

Okay, so. Just got back from the gym and made whatever this abomination is:
NOTE THIS DOESN’T WORK WITH LAYERED CLOTHING

local test_list = {Enum.AccessoryType.Back,Enum.AccessoryType.Front,Enum.AccessoryType.Unknown}

local min_accuracy = 0.8

local ray_params = RaycastParams.new()
ray_params.FilterType = Enum.RaycastFilterType.Include

for _,child in pairs(script.Parent.Victim:GetChildren()) do
	if child:IsA("Accessory") then
		test = false
		for _,acc_type in pairs(test_list) do
			if child.AccessoryType == acc_type then
				test = true
			end
		end
		if test then
			local fake_accessory = game:GetService("AssetService"):CreateMeshPartAsync(child.Handle.SpecialMesh.MeshId)
			fake_accessory.Name = "FakeAccessory"
			fake_accessory.Anchored = true
			fake_accessory.Parent = workspace
			fake_accessory.CFrame = script.Parent.FakeTorso.CFrame*script.Parent.Victim.Torso.CFrame:ToObjectSpace(child.Handle.CFrame)
			
			ray_params.FilterDescendantsInstances = {fake_accessory}
			
			local rays_hit = 0
			local rays_not_hit = 0
			local rays_should_have_hit = 0
			local rays_should_not_have_hit = 0
			
			for _,attachment in pairs(script.Parent.FakeTorso:GetChildren()) do
				local new_ray = workspace:Raycast(attachment.WorldPosition,attachment.WorldCFrame.LookVector,ray_params)
				if attachment.Name == "True" then
					rays_should_have_hit += 1
					if new_ray then
						print("W")
						rays_hit += 1
					end
				elseif attachment.Name == "False" then
					rays_should_not_have_hit += 1
					if not new_ray then
						rays_not_hit += 1
					end
				end
			end
			
			local precent = (rays_hit+rays_not_hit)/(rays_should_have_hit+rays_should_not_have_hit)
			
			if precent > min_accuracy then
				print(child.Name.." CONFIDENCE:"..tostring(math.round(precent*100)).."%")
			end
			
			fake_accessory:Destroy()
		end
	end
end

I create a “fake accessory” using MeshPart, which allows me to check if it’s a certain shape.
Obviously, knowing that not all Chest accessories are the same shape, we use a “minimum confidence” variable, which I found that a 0.8/80% works good for both 1.0 and 3.0 Chests. Granted, I’ll have to make a large scale test to check how much of the accessories it detects later.

2 Likes

I made this thing in response to this post like an hour ago based off some other avatar related shenanigans i was doing a while ago:

local blacklistcreators = {"."}--Defaults filter everything.
local blacklistnames = {"."}
local blacklistdescriptors = {"."}
local function maincheck(info)
	local val = false
	local splitname = string.split(info["Name"],"%s%p")
	for r = 1, #splitname do
		for t = 1, #blacklistnames do
			if string.match(splitname[r],blacklistnames[t]) then
				val = true
			end
		end
	end
	for t = 1, #blacklistcreators do
		if string.match(info["Creator"]["Name"],blacklistcreators[t]) then
			val = true
		end
	end
	local splitdescription = string.split(info["Description"],"%s%p")
	for r = 1, #splitdescription do
		for t = 1, #blacklistdescriptors do
			if string.match(splitdescription[r],blacklistdescriptors[t]) then
				val = true
			end
		end
	end
	return val
end
local plydesc = script.Parent:WaitForChild("Humanoid"):WaitForChild("HumanoidDescription")
if tonumber(plydesc.Torso) and tonumber(plydesc.Torso) ~= 0 and maincheck(game:GetService("MarketplaceService"):GetProductInfo(tonumber(plydesc.Torso))) == true then
	plydesc.Torso = "0"
end
if tonumber(plydesc.Pants) and tonumber(plydesc.Pants) ~= 0 and maincheck(game:GetService("MarketplaceService"):GetProductInfo(tonumber(plydesc.Pants))) == true then
	plydesc.Pants = "14862393678" -- This id is just a random image i uploaded for a custom reflection cubemaps test.
end
if tonumber(plydesc.Shirt) and tonumber(plydesc.Shirt) ~= 0 and maincheck(game:GetService("MarketplaceService"):GetProductInfo(tonumber(plydesc.Shirt))) == true then
	plydesc.Shirt = "14858194613" -- same as other one
end
task.wait(0.05)--Extra wait to make sure the AccessoryDescriptions have loaded in.
local extradescs = plydesc:GetChildren()
for i = 1, #extradescs do
	if extradescs[i].ClassName == "AccessoryDescription" and maincheck(game:GetService("MarketplaceService"):GetProductInfo(tonumber(extradescs[i].AssetId))) == true then
		extradescs[i]:Destroy()
	end
end
script.Parent.Humanoid:ApplyDescriptionReset(plydesc)

Works with layered clothing, 2d clothing, accessories and torsos doesnt do anything with the shape though, You put it in StarterCharacterScripts as a script(RunContext: server or Legacy).

3 Likes

Might be a bit too many attachments, but this is the system that I’ve decided on.
I use a singular raycast per attachment that is parallel to the torso that are in the shape of a chest.
I am not sure how many false positives this system may give with the “is air” and “is filled” system.
MUST BE AIR:
image
MUST BE FILLED:
image
BOTH:
image

3 Likes

Here’s the final result of a slightly bigger test I did with a few different kinds of front accessories.
RESULTS:


ACCESSORIES USED:

As you can see, the system works surprisingly well once tweaked to work as necessary.
And it doesn’t limit you from only doing side checks eithers, since it uses the direction of the attachment! Of course, you still have to consider the performance impact, although I doubt that doing one check every time a character changes should cost too much. Especially since this is only done on Front, Back and Unknown accessories.

4 Likes

if you guys are so bothered about this. probs the best thing to do would be to use Pythonanywhere to create our own API, this would allow for 2 interaction - 1: submit asset id fro blacklisting, and 2 check where an item id is blacklisted.
I def could def put this together for you for free, but hostings costs would cost about $5 a month.
so basically when a player join you get all the asset ides for their stuff send them to pythonanywhere server and it tell you if someone has marked them to be blacklisted.

2 Likes

Don’t know if anyone’s said this yet but the best way to make sure this doesn’t happen is to put a custom character creator in your game. A lot of people don’t like doing this for obvious reasons but unfortunately it’s the only way to totally control what people wear in your game.

If you don’t want to go full nuclear, you can have a script check a user’s hats and only remove items that are not uploaded by Roblox. However since everyone wears UGC now it’s likely to cause a lot of confusion and upset your players.

1 Like

I’ve decided that I’d probably prefer this to be community driven.
To be more exact, players are able to submit inappropriate UGC items and using some sort of online hosted API the suggestions are sent to a select few moderators and they may either accept them or decline them, making so that we both avoid having false-positives using other methods and that we are able to blacklist a lot more inappropriate UGC items than just Chests.
If anyone is interested in helping with this I’d be glad to take suggestions, but ultimately, this is the approach I want to take. If roblox won’t moderate it’s platform, as developers, I feel like we should do something about it instead.

1 Like

to be honest, the simplest method/s would be to let players decide if they want to see front/back accessories or just disable front/back accessories entirely

i doubt anyone would want to actively moderate some roblox melon reports

1 Like

dont even bother having moderators, just let people submit items and then return the number of times they have been submitted. so if you want super good standards block any items that return a value of 1 or greater and then if you want less moderation pick items that are >2 etc

Hmm I think I might have a solution. When a front accessory is submitted you could load it (preferably on the client of who uploaded it to make it less laggy) somewhere in the game and create 3 raycast, 2 of which should start a couple studs in front of each melon. The third raycast should also be a couple studs infront of the accessory but below and in the middle of the other 2 raycast (the ray casts should face towards the accessory). Then check the distance it took for the ray casts to hit a part on the accessory, if the difference between the 2 raycast and the 3rd is greater that let’s say 2 studs you can deem the accessory inappropriate.

lol this is madness, I applaud your dedication :saluting_face:

I think this is an awesome idea personally and I would even pay for a service like this if it works. It’s unfortunate that WE are the ones who have to be responsible and clean up Roblox’s mess but I’m running out of feasible options to deal with this.

1 Like

just give players the ability to hide other’s accesories for themself at that point, no need to make a whole database

No, I refuse to.
Like I said, I have a very personal stance against these types of UGCs.
Also. I did not spend almost a week learning about Rest API, hosting and other stuff to stop now.
I WILL do it and NOBODY can stop me.

1 Like

What if people just don’t bother reporting ugcs

There are already enough people bothered to do so.
Even then, I can always just look through the UGC’s myself and sort of scrape the inappropriate stuff by hand.
I will put an end to those degens by hand if I must.
I’ll keep y’all updated on the progress btw.

Honestly? The most efficient way is hand filtering. Make a big list of all the IDs, adding them in as you go. It’s how people blacklisted audios when boomboxes were around, and how people blacklisted large accessories from games where it may be a disruption.

I’ve made a system that uses the Roblox Creator Store to it’s advantage for storing the Ids of inappropriate accessories, no API needed!

2 Likes