ID:2202787
 
Resolved
A new animation flag, ANIMATION_RELATIVE, has been added. With it most numeric vars, and also transform and color, can be specified as changes relative to the current value rather than as absolute changes. Additionally, animation of multiple vars has been changed to make better use of mutable appearances for faster operation and avoiding appearance churn.
Applies to:DM Language
BYOND Version:511.1367 - 511.1369
Operating System:Windows 10 Home 64-bit
Web Browser:Chrome 52.0.2743.116
Status: Resolved (511.1374)

This issue has been resolved.
Descriptive Problem Summary:
I have two separate animations that get drawn in separate instances that can frequently be ran parallel together. One flashes a color over the player's icon with atom.color a few times, and the other animation makes the player "hop" a little bit when dashing by animating their pixel_z up 8 pixels and then back to 0.

The problem is that dashing while the flashing color animation is looping will cause the player's icon to get shifted up and get stuck like that without jumping back down. Dashing a few more times will usually bring the icon back into place, but more often it will just cause the player icon to glitch around sporatically and lock the player icon in certain directions when everything else behaves as though the player is facing the proper direction. When the ANIMATE_PARALLEL flag is removed the animations run perfectly(although the dashing cancels the color flash, which is undesired).

Numbered Steps to Reproduce Problem:
1. have a looped animation that flashes your mob's color between blue and null every few ticks.
2. while the above is applied to the mob's icon, have another animation that adjusts the pixel_z(or pixel_y) of the mob up 8px and then back down to 0 but only once. (see code below)
3. do step #2 while moving around.
4. after a couple times, the mob icon will glitch out and get stuck floating 8px north of where it should be with the direction being locked in the wrong way.

Expected Results:
Both animations to run simultaneously without being wonky.

Actual Results:
Both animations run simultaneously but the animation for shifting the mob's pixel_x upwards won't bring the mob back down and leaves the mob facing north for some reason.

Does the problem occur:
Every time? Or how often? everytime.
In other games? N/A
In other user accounts? Dev partner with same build says it doesn't happen for him.
On other computers? Evidently not.

When does the problem NOT occur?
When the ANIMATE_PARALLEL flag isn't set in any animate() calls.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? Builds prior to beta 511.1367

Workarounds:
Just deal with animations that interrupt eachother.
I'll need a test project for this. Oddly, 511.1367 did nothing to change parallel animations at all.
I've never been able to get it to work in the first place.

I mentioned this a while back to Lummox, but never got around to uploading an example.
Kumo, I'm still waiting on a test case for this.
In all honesty, I don't really know how to make a test case for this. ANIMATE_PARALLEL just doesn't work when having multiple atom.color and transformation animations simultaneously. (the ANIMATE_PARALLEL flag doesn't work at all to my knowledge though).

Sorry I'm no help, but this is why i generally try to avoid making bug reports.
Alright, I see the problem. ANIMATE_PARALLEL DOES work, but it doesn't work quite as one would expect.

Basically, what's happening is the second animation to take effect overrides the outcome of the first animation when the same variable is in use for both.

animate(ref,pixel_z=-10,time=10)
animate(ref,pixel_z=10,time=10,flags=ANIMATE_PARALLEL)


Notice that the object only effectively does the second animation?

What Kumo is talking about, is that because animate() effectively assigns the end value of a parallel animation's inputs, multiple simultaneous color/transform animations won't effectively work because the second animation straight overrides any value affected by the first because there's no way to specify that the animation should be relative to the current value rather than simply setting the current value.

In other words, there's no way to scale an atom up and down in one animation while rotating it in a separate animation, which is the whole reason parallel animations were wanted in the first place --to allow us to animate the same thing multiple times in stages without instantly undoing the other animation that was currently playing.
In response to Ter13
Ter13 wrote:
Alright, I see the problem. ANIMATE_PARALLEL DOES work, but it doesn't work quite as one would expect.

Basically, what's happening is the second animation to take effect overrides the outcome of the first animation when the same variable is in use for both.

> animate(ref,pixel_z=-10,time=10)
> animate(ref,pixel_z=10,time=10,flags=ANIMATE_PARALLEL)
>


Notice that the object only effectively does the second animation?

What Kumo is talking about, is that because animate() effectively assigns the end value of a parallel animation's inputs, multiple simultaneous color/transform animations won't effectively work because the second animation straight overrides any value affected by the first because there's no way to specify that the animation should be relative to the current value rather than simply setting the current value.

In other words, there's no way to scale an atom up and down in one animation while rotating it in a separate animation.

As usual, Ter lifts the perpetual veil of fog.
So is this not an issue or is there any way to make it viable for my uses?
TBH I think your use-case is something that a developer would reasonably want to do, and something that frankly should be handled.

I guess the trouble is that our problem with the way ANIMATE_PARALLEL works is not so much that it's a bug, but rather it's a dissatisfaction with the implementation.

So more to the point of getting this one addressed, it might be better to request an ANIMATE_RELATIVE flag, which will affect the way coordinate and matrix animation steps are calculated on the client. Rather than specifying the endpoint of the animation, it specifies the offset from the current value for the endpoint of the animation.
I support the idea of ANIMATE_RELATIVE. Although it does seem like it should be easy enough to calculate the endpoint from the current point.

For instance if one animation does a translating transform and the second parallel one does a rotation, the correct transformation for #2 should be based on the endpoint of #1.

var/matrix/M = matrix(100,0,MATRIX_TRANSLATE)
animate(src, transform=M, time=50)
M.Turn(90)
animate(src, transform=M, time=50, flags=ANIMATE_PARALLEL)

However, I think there's still a very legit case to be made for ANIMATE_RELATIVE anyway for the fact that it would avoid these kinds of calculations (or rather, simply internalize them).
But what if you don't know the current endpoint? Like if the animations are in different functions, you'd either need to store the endpoint and pass it around or recalculate it again.
In response to MisterPerson
The last endpoint is always the current appearance.
Just to get some clarity on this, are we in agreement that ANIMATE_PARALLEL isn't broken but that a relative flag would be a good idea anyway? Or is there in fact some kind of bug that I still need to look into?
Knowing how animate_parallel works now, I don't think there's a bug here.
Lummox JR resolved issue with message:
A new animation flag, ANIMATION_RELATIVE, has been added. With it most numeric vars, and also transform and color, can be specified as changes relative to the current value rather than as absolute changes. Additionally, animation of multiple vars has been changed to make better use of mutable appearances for faster operation and avoiding appearance churn.
\o/