-
-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Manual "step" and multiple Shifty instances #109
Comments
Hi @4ian, thanks for opening this issue! I've seen GDevelop before; it's a seriously cool project and I'd love to help with integrating Shifty into it! I can see that there's already quite a bit of disussion and exploration on your end and I haven't had a chance to get fully caught up, but this is a really cool use case for Shifty so you can count on me to help update it to suit your needs. :)
Yep! Shifty is designed to support an arbitrary number of instances so this shouldn't be an issue.
This is interesting. To meet your needs, it's possible that There may be a bit more that I haven't considered, but based on what you've described in this issue I think the minimal change needed in Shifty is to expose the internal Does this all sound correct to you? I should have some time this weekend to at least start on some of these changes if you can confirm that I've got this right! EDIT: I forgot that I deprecated the |
Hey Jeremy,
Thanks for answering so quickly!
From what I read a "tick" function would be perfect :)
I opted to keep the public API smaller until a need to expose it arised.
Sure, totally make sense :)
I think you'll be able to achieve what you need by doing tweenableInstance.setScheduleFunction(()
=> {}) and externally calling the public tick/processTweens function as
discussed above.
Yeah that would work I think!
I'm only unsure about pausing all tweens/starting them again between scenes
(that why I was hoping to be able to create multiple instances, so that I
can just not tick the Shifty instance of scene that are not running).
Hooking in the scene start/pause to pause tweens could be possible but a
bit more complex as we would need to store the list of tweens to stop and
restart.
But a tick function will surely be a good start. With tweenable.now it
should work, I was planning to redefine it already and was missing the
ability to call processTweens.
So yeah that sounds all right! :) Thanks again for the quick response! 👍
…On Sat, 23 Feb 2019, 18:52 Jeremy Kahn ***@***.*** wrote:
Hi @4ian <https://github.com/4ian>, thanks for opening this issue! I've
seen GDevelop before; it's a seriously cool project and I'd love to help
with integrating Shifty into it! I can see that there's already quite a bit
of disussion and exploration on your end
<4ian/GDevelop#922> and I haven't had a chance to
get fully caught up, but this is a really cool use case for Shifty so you
can count on me to help update it to suit your needs. :)
Can we instantiate multiple instances of Shifty?
Yep! Shifty is designed to support an arbitrary number of instances so
this shouldn't be an issue. processTweens
<https://github.com/jeremyckahn/shifty/blob/2cfe0815b7dcc45cd20197dc741e5361b205fbee/src/tweenable.js#L76>
is an internal implementation detail that processes all tweens globally in
order to optimize for performance, but it maintains individual tween state.
So, tween A could be paused while tween B is running. If that's not
working then that's a bug in Shifty and I will prioritize a fix.
Can we get rid of the default requestAnimationFrame, and instead call
manually the function processTweens? I've seen it's exported in
tweenable.js, but not part of the public API?
processTweens wasn't exported because it's fairly low-level and wasn't
sure if there was a use case for it. I opted to keep the public API smaller
until a need to expose it arised. I suppose that this is that need. :) It
should be a pretty simple change and I'd be happy to make it, but I'd
prefer the public name to be something like tick so it's a bit more
generic semantically.
I've seen Tweenable.setScheduleFunction and Tweenable.now too.
Tweenable.now could be redefined to return the time of the game engine (so
that tweens are following any time scaling/pausing applied to the game),
but I'm not sure about setScheduleFunction. We would need an inversed
control here: instead of Shifty calling the schedule function, we want to
call the processTweens from the game engine at regular interval (if needed
for better results, we can take care of calling it at regular intervals
instead of a variable time delta) (but not sure it will change anything).
This is interesting. To meet your needs, it's *possible* that
scheduleUpdate
<https://github.com/jeremyckahn/shifty/blob/2cfe0815b7dcc45cd20197dc741e5361b205fbee/src/tweenable.js#L133>
will need to be changed, but I don't think that will be necessary. I think
you'll be able to achieve what you need by doing tweenableInstance.setScheduleFunction(()
=> {}) and externally calling the public tick/processTweens function as
discussed above.
There may be a bit more that I haven't considered, but based on what
you've described in this issue I think the minimal change needed in Shifty
is to expose the internal processTweens functionality. From there,
GDevelop can set Tweenable.now
<https://jeremyckahn.github.io/shifty/doc/shifty.Tweenable.html#.now> and
call tweenableInstance.setScheduleFunction(() => {}) for each instance.
If you'd prefer to statically define the schedule function (similar to
Tweenable.now) I'm open to adding an API for that, but I'd like to know
that it would helpful for you before doing that.
Does this all sound correct to you? I should have some time this weekend
to at least start on some of these changes if you can confirm that I've got
this right!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#109 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABOIgjzw5EN3GXJlRbEA7U6z5w6FSUDoks5vQY31gaJpZM4bOAxm>
.
|
I think this is going to be an issue with the proposed approach. While overriding the control of tick scheduling shouldn't cause any issues, the tweens' individual timelines won't automatically "shift" to account for what seems like global "pause" logic. In other words, Shifty tweens are scheduled around real time. If a tween's Off the top of my head, I can think of two solutions to this problem:
I may be overcomplicating this a bit. In any case, I'll start on exposing the |
@4ian This is now in the Let me know how this goes for you! If it helps to solve your problem I will merge this branch and make a new release of Shifty. |
Also please keep in mind that you will need to run |
I thought about this all some more and I think I might have slightly misinterpreted one of your earlier questions:
While Shifty does support an arbitrary number of I'm thinking that it might be appropriate for Shifty to provide proper scene management utilities. Something similar to Rekapi, but lighter weight and generic enough to address the needs of GDevelop and similar use cases. Basically, something small to control the playback states of groups of tweens, perhaps like so: import { tween, Scene } from 'shifty';
const sceneA = new Scene(
// Tween 1
tween({
from: { x: 0 },
to: { x: 10 },
duration: 1000
}),
// Tween 2
tween({
from: { x: 50 },
to: { x: 100 },
delay: 500,
duration: 1000
})
);
const sceneB = new Scene(
// Tween 3
tween({
from: { x: 25 },
to: { x: 100 },
duration: 1000
}),
// Tween 4
tween({
from: { x: 100 },
to: { x: 50 },
duration: 1500
})
);
// Pauses tweens 1 and 2 while 3 and 4 play
sceneA.pause(); I don't want this to get into sophisticated sequence management, as that's exactly what Rekapi exists to do. But I think GDevelop is going to need something like this to manage paused background tweens. I'm willing to develop something like this in Shifty to be used by GDevelop, but this is a relatively large new feature so it would take me a bit of time implement properly. I'm also open to PRs if you need this sooner rather than later and would prefer to have Shifty provide this functionality instead of doing it in GDevelop. @4ian Would you prefer that Shifty provide scene management, or have GDevelop take care of it? |
Awesome! I'll pull this and build the dist files :)
Yes you right, I think we will need this.
That would work I guess, as we could have all tweens in a scene being played while other are paused. Maybe I'm totally wrong, but what about allowing to have more than one Shifty instance? Not sure what kind of refactoring would be needed or if it's even a good idea but that would provide a perfect, 100% bullet proof isolation of tweens: in a scene A, we would create a Shifty instance, creating tweens on it, then in scene B we would have a totally separate Shifty instance, and tweens created using this instance. GDevelop will call But if you think scenes are doable, we can go with this solution. Note that if you think everything is becoming too complicated, maybe we can switch to Rekapi. But having a lightweight tween library like Shifty is really cool, especially if we can guarantee the isolation of tweens :) |
My concern with the "instancing" approach is that it would require significant modification of the batched processing system that was introduced in the 2.5.0 release. That release introduced a singular, internal linked list of all tweens that is processed upon every tick. I don't think that supporting what you are describing would introduce significant performance penalties, but it would complicate the code quite a bit — more than I feel comfortable with for such a specific use case. While no-compromises performance is a top priority of this library, another high priority is for the API and code to be relatively readable and understandable... least of which for myself as the maintainer! 😅 To give this decision a bit of context, Greensock provides the absolute best performance of any animation library, and in performance stress tests it outperforms Shifty (though the difference is insignificant in even the most contrived scenarios). However, the code itself is (necessarily) a bit obtuse, and I don't want Shifty's code to become unapproachable or unmaintainable in the name of supporting uncommon use cases. Assuming for a moment that we change Shifty to support multiple instances of the internal linked list, actually taking advantage of it reveals a bit of a leaky abstraction. It would necessitate a fairly deep understanding of the internal mechanics of the library which I feel should be avoided by users. It seems that the need here is to manage different sets of tweens independently, and I feel that a higher-level "Scene" API is the most straightforward way to achieve that.
I think that Rekapi would do everything you're looking for without the need for modification or API contortions. However, I think it would also necessitate quite a bit of rework to 4ian/GDevelop#922, so I don't want just throw this work over the wall to you and @Wend1go et al. Also Rekapi can't reach quite the level of animation performance as Shifty because it is quite a bit more abstracted, and performance is critical in a game engine. I feel that a lightweight "Scene" API on top of Shifty is the most pragmatic solution here, either in GDevelop or provided by Shifty. I'm going to open a new issue for Shifty to start speccing out how this might work. Please don't feel compelled to wait for or use my solution, but I think this is at least interesting enough to start exploring. I'll leave this issue open until you give the 👍 to the changes in the |
This seems to be working, and this is a pretty innocuous change, so I just merged and released it: https://github.com/jeremyckahn/shifty/releases/tag/v2.7.0 New API docs: https://jeremyckahn.github.io/shifty/doc/shifty.html#.processTweens @4ian I hope this helps! Let me know if GDevelop needs anything else. 🙂 |
Huge thanks for adding this so quickly. Can confirm this works properly in GDevelop!
I see, I've see this linked list while initially browsing the source code, so I understand this might get tricky.
Yeah sure, I was more hoping for something that would "just" be a factory function for the whole module, so that no global are used and we can freely create new "Shifty.js". But understand this might be an issue in terms of simplicity/performance (and would only be useful in the case you're manually calling processTweens, like GDevelop is doing). Scene API draft looks good so far! Will comment more on the other issue :) |
Hi there!
Thanks for this nice library! Looks really cool and @Wend1go is looking at adding support for it in GDevelop.
As it's a game engine, I have a few questions to see how we can best integrate the game engine and Shifty:
processTweens
? I've seen it's exported in tweenable.js, but not part of the public API?Tweenable.setScheduleFunction
andTweenable.now
too. Tweenable.now could be redefined to return the time of the game engine (so that tweens are following any time scaling/pausing applied to the game), but I'm not sure aboutsetScheduleFunction
. We would need an inversed control here: instead of Shifty calling the schedule function, we want to call the processTweens from the game engine at regular interval (if needed for better results, we can take care of calling it at regular intervals instead of a variable time delta) (but not sure it will change anything).Thanks for any precision :) The integration of Shifty is being done here: 4ian/GDevelop#922
The text was updated successfully, but these errors were encountered: