A very specific issue with roblox emotes that bothers me

I work on a game that uses the regular Roblox-given Animate script, and nearly everything about it isn’t changed (exception being a humanoid RigType check to support both r15 and r6)

I implemented a complex custom emote system that plays animations and has events like particles and sounds that go off on specific frames for these animations, as well as autonomous AnimationTrack syncing to nearby players that are also playing the emote. Since this emote system has joinable emotes and special effects, it locally works with every single player’s character, and Animator.

I don’t know if many people have tried this before, but to those who have, I’m sure they have been made familiar with how the Animator instance works when it’s replicated on the server. The player’s character loads and plays an animation, and the server automatically replicates the animation to all other clients. This poses an annoying issue for my emote system, because since each local client loads and plays animations for each character, animations from the local client and the other player’s local client begin to weirdly blend together, resulting in a visual bug that worsens with the other player’s ping.

I wanted a clear-cut solution, so I went to the drawing board for ways to keep this from happening, and I came up with 2 solutions:

  • Make the system listen for animation tracks instead of playing them on it’s own
  • Delete the Animator instance on the server, create a local Animator instance and localize ALL animations

Making the system listen via Animator.AnimationPlayed works for when the server replicates animations to the client, but it’s unreliable. The AnimationTrack that is received from AnimationPlayed is completely stripped of any metadata, and with the way my system works, I’d need to make serious revisions to make this functional. Not to mention, syncing and special effects would become impossible as the system wouldn’t know what emote animations the other client has loaded, and thus wouldn’t be able to preload the special effects, let alone be able to identify emote animations that are passed through AnimationPlayed with just the AnimationId.
This leaves us with the second option, complete client replication. I accomplished this by making an Animator handling module that loads and plays server-loaded animations through network events with just their animation Id, and sends network events for local client animations. I modified the default Animate script to work with this system, and it can be tested here. The local client handles the Animate script for all characters in the game, so there’s no need for any server replication.

Everything about this makes it the perfect solution for what I’m trying to accomplish, until I tried getting it to support Roblox marketplace emotes. As of this post, marketplace emotes don’t have much documentation as to how they’re played. In fact, I found after a lot of digging that the only way to get the sanitized animation id from an emote marketplace id is through Humanoid: PlayEmoteAndGetAnimTrackById, but the security for this method is set to RobloxScriptSecurity, so only core Roblox scripts can use it. Stumped, I attempted to simply use Humanoid:PlayEmote. But when trying this, I get the error “You can only play emotes for the LocalPlayer”. Meaning that despite still being able to play emotes, the local player cannot communicate with any other client to also play these animations without fail.


The only reason the wave worked is because it is locally loaded and played on both clients without need for a network call.
image

As of this post, there is no written documentation or forum post or api that can support or help what I’m trying to do, is there any way around this?

2 Likes