Simple UGC Emote Disabler

With the rollout of UGC emotes, I’ve noticed that some are buggy, exploitable, or simply unwanted. While emotes are an important feature on Roblox, there doesn’t appear to be a built in way to currently disable UGC emotes This workaround filters them out, allowing only offical Roblox emotes to be used.

Eg: TikTok - Make Your Day

To handle this, I wrote a quick and simple function that blocks emotes that aren’t uploaded by Roblox, optionally replacing them with a blank placeholder, and caches emotes owned by Roblox to limit #GetProductInfo Calls.

With this patchy solution, there are some weird edge cases - some emotes are not considered Assets and will return 400 on #GetProductInfo. Eg: Charli xcx - Apple Dance

Emote Disabled Example:

Function:

local Players = game:GetService("Players")
local Market = game:GetService("MarketplaceService")

local ShouldEmotesBeCached = true
local ReplaceWithBlankEmote = true
local Cache = {}

local function BlockUGCEmotes(Character: Model)
	local Humanoid = Character:FindFirstChildOfClass("Humanoid")
	if not Humanoid then return end

	local OwnedEmotes = Humanoid.HumanoidDescription:GetEmotes()
	local RobloxEmotes = {}

	Humanoid.HumanoidDescription:AddEmote("Emote Disabled", 1)
	for _, Emote in Character.Humanoid.HumanoidDescription:GetEquippedEmotes() do
		local Success, E = pcall(function()
			local EmoteId = OwnedEmotes[Emote.Name][1]

			if ShouldEmotesBeCached and table.find(Cache, EmoteId) then

				table.insert(RobloxEmotes, {Slot = Emote.Slot, Name = Emote.Name})
				return
			end

			local MarketInfo = Market:GetProductInfo(tonumber(EmoteId), Enum.InfoType.Asset)
			if MarketInfo.Creator.Id == 1 then
				if ShouldEmotesBeCached then 
					table.insert(Cache, EmoteId) 
				end

				table.insert(RobloxEmotes, {Slot = Emote.Slot, Name = Emote.Name})
				return
			end

			warn("UGC Emote removed.")
			Humanoid.HumanoidDescription:RemoveEmote(Emote.Name)
			if ReplaceWithBlankEmote  then
				table.insert(RobloxEmotes, {Slot = Emote.Slot, Name = "Emote Disabled"})
			end
		end)
		-- There are some weird edge cases - Eg: "Charli xcx - Apple Dance"
		if not Success then
			table.insert(RobloxEmotes, {Slot = Emote.Slot, Name = Emote.Name})
		end
	end

	Humanoid.HumanoidDescription:SetEquippedEmotes(RobloxEmotes)
end
Simple Implementation
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player: Player)

	BlockUGCEmotes(Player.Character or Player.CharacterAdded:Wait())
	Player.CharacterAdded:Connect(BlockUGCEmotes)
end)

Warning

  • This is a patchy workaround until Roblox improves UGC emote moderation.
  • Will not block “edge case” emotes that fail GetProductInfo calls.
  • If Roblox later introduces official filtering, this script may be unnecessary.
23 Likes

This is super useful! Judging from the fact that even official roblox emotes cause speed/wall glitches, I can imagine UGC emotes could be worse (although I honestly haven’t checked). This could be super useful for fighting games or smth like that

Also, when I click on this link link it doesnt work so maybe thats the issue (although you def know more about this than me so what do I know)

3 Likes

The emote page loads for me but doesn’t render any information like other emotes do

2 Likes

This is very useful, though I would certainly have to agree that Roblox should introduce some kind of official filtering that would set it to only allow Roblox official emotes to be used.

I am very interested to see what Roblox’s response to this whole emote abuse issue will be.

2 Likes