Best way to run custom animations?

I’m looking to run some custom animations, (aka a table of CFrame values), and update a Motor6D’s Transform property for each limb on a character.

I already know how to acomplish this, but I feel like it could be optimized even more.

Keep in mind that these are NOT ROBLOX animations. You cannot just do Humanoid:Play()

I would like some input on the following:

  1. Heartbeat? RenderStep? BindToRenderStep (and if so, of what bind type)? Just a wait() loop?
  2. Best way to handle animation priorities on a joint by joint basis?
  3. How could I implement some sort of LOD quality system for distance, but using as efficient as possible?
  4. Iterate through a table? Or something else?
    a. If through a table, do I store a function as each value in the table, or a table with the info needed for the render loop to do the equivalent of such a function?

Again, I’m heavily focusing on performance because of my ultimate goal to be able to try and have at least 100 players in my framework at once.

Remember, I am asking for user input on how I can make this as efficient as possible, with little to no performance drop. I already know how to make this stuff work, just maybe not in the most efficient ways.


Stepped. Stepped runs right before physics.


And this would still be OK if lets say it was handling the animations for 100 different players?

I want performance to be an absolute necessity, however I do not want animations on other clients to look trashy.

It would be just as okay as if you were to use Heartbeat or RenderStepped because all of these signals execute exactly once per frame. The placement in the pipeline is what differs between them. RenderStepped blocks the pipeline and runs before rendering, Heartbeat runs after physics, Stepped runs before physics. Before physics makes most sense for animations in my opinion.

RenderStepped is probably a no-no for this because you lose the benefit of parallelism with rendering that way.


I think it’d be interesting for you to try using RenderStepped (or Heartbeat, its lower-priority counterpart).

I’m imagining it lerping the values every time the event is fired, with the alpha being (current_time - start_time) / animation_length (off the top of my head, this is the right equation).

The upside of this is that the animation is always rendered at the frame rate, and doesn’t run when the frame will get skipped anyway.

However this would mean things like the Motor’s in-built tweening functionality wouldn’t be used, as the current CFrame is completely defined by the script.

In terms of replication, all of these calculations and stuff happen on the client. The server is simply used to ping other clients that x client is running x animation for x amount of seconds.

1 Like

What if I told you that the animations won’t replicate to the server? Would you still choose Stepped and not Heartbeat?

Its a mixamo animation so we already have 60 fps regardless of tweening.

1 Like

Optimisation counts when you’re at 100s of players, though ;))))

1 Like

Yep, thats what the LOD is for. I want players nearby to be good quality animations, however I am willing to sacrafice the looks in order to keep a constant FPS on low end machines.

1 Like

If anyone has some input for #4 and #4.a, that would be greatly appreciated!

You should just use normal animations which would be way more efficient. You can do all calculations for idle, walking, jumping animations on the client and for other animations the player would have to fire a remote event to play. This is how I’m doing it.

Again, I prefer to not use ROBLOX animations. However, if they simply made actually work on the client then I would be much more willing to use them.