I like to abstract away code into global utility functions in shared using a script that runs in ReplicatedFirst for the client, or using ModuleScript for the server.
All my animations are handled on the client. For example, a spell has an animation, and when the player activates the spell tool, the server sets the Enabled property of the spell to false (until the cooldown elapses and the server sets it back to true). The client then listens for this using script.Parent:GetPropertyChangedSignal("Enabled") and plays the animation.
For a while I just had a shared.Animation() which sets the animation ID of some global animation object to the target value, loads it, plays the track, then returns the track object. However I am not sure if reusing the same Animation object for many different animations is good practice or not.
you could install an ‘animation loader’ which will return a table of all your loaded animation tracks so you can just do animtable.spell_cast_01:Play() and animtable.spell_cast_01:Stop() and wrap this in shared or _G.
i’m not sure what the issue is with re-using animations. once your character dies, those are gone anyways. maybe you could elaborate on that. if you want to save memory simply create the instances & tracks ONLY on the client.
also your approach of playing animations via server boolean is a very unviable one. just play them on the client directly, after input and performing sanity checks. bad choice for UX.
My question is why is this unviable? The server disables the tool when the cooldown takes effect. Instead of sending a client event or something to indicate the the spell has cast successfully, I can listen for an event that is going to be replicated anyway.
If there is any delay with the server, there will be a delay in UX. You mention spells, so I assume this is combat-related, or something that is real-time and faster paced and/or reliant on user feedback. Which if it is, could make for bad UX if the user has a higher ping, or the server network is slowed down.
Imagine I click, and I have to wait .3 seconds or more before an animation plays.
No real point in making these things server authoritative, they can still be bypassed if the client listens for it. I mean it’s funny don’t you think. Client listens for server value so he can change client-related things.