Oh, I see. That makes sense now that I think about it. I’ll look up what task library is, and see how I can implement that.
After doing some research, it seems that
task.defer() would be what I need, but nothing seems to be telling me what a “Resumption Cycle” is. Do you know what it is? I just need to know if it’s something I need to worry about in my script, as I plan on deferring the function permanently.
From my understanding, they are special points in the schedule where functions connected to
task.defer will run.
So, everything except those will stop?
I mean everything except these things will no longer be running. Is that right?
What’s an AFAIK event?
Please read the following post:
I did, and I didn’t understand a thing in it.
Where all event handlers will run in the future. Deferred SignalBehavior will become the default in the future, meaning that all code handling signals will be ran at those points. task.defer will push a function or thread to be resumed at the next invocation point from the current one. “Invocation points” defines a place where event handlers can be executed; “resumption cycle” is a collection of those (AFAIK).
Not what you’re looking for; “deferring permanently” is the same as not running the code at all. You need to think about the structuring of your code itself. Specifically the pattern you’re looking for looks like it can still be done in sequence. Tackle the root problem: why did you want coroutines? What are you running that needs coroutines and why does it not work without them?
It didn’t work without coroutines because the scripts yield when calling the functions, but I need the script to be running multiple things at once.
Also, about the defer thing, I see the basic idea of what you mean. In that case, how would I pause and reset a function in the middle of it running?
You should still consider the structure of your code.
As it stands, the cause for your yields are your while and repeat loops. Indeed, outside of a coroutine they would yield subsequent code, but you should ask yourself if you actually need loops here or if you can do this in an event-based manner where the events of something are controlling the flow of logic here instead of running them all independently.
It’s a little hard to read the code as-is but I can tell that you could easily all of these coroutines together or at least create a proper modular system that allows you to iterate through scripts that are each responsible for handling a scene. For skipping, it’d just be cleaning up the resources and stopping animations then resetting the camera. It’s roughly similar to what I do for my own experience.
You don’t. Defer pushes the time in which your function is executed. No function can be “paused and reset” while it’s executing. You can do it very roughly but it’d still require you to have points where you exit the scope and an outside instruction to call the function again.
I’m not really sure what you mean by
Could you maybe explain? Do you mean firing a bindable event to other scripts?
Also, I’m pretty sure I need the loops, as the way I’ve gone about creating the cutscenes is by placing all of the information that they have inside of a group, and cycling through said information.
Roughly. I meant something like this:
You could have signals in these modules that get fired based on the state of the current scene and then iterate through them as you go (e.g. when Scene1.Finished fires, move to Scene2). When skip is called, then you end the current scene without moving to the next one.
If you follow through with an event-based solution, you would not need the loops, hence why I’m keen on telling you to review your code structure and whether or not it actually needs loops or if you can design an event-based system to handle your cutscene. My personal mantra is that loops should only be an absolute last resort to a problem, not a first; and that’s assuming the system in question can be accomplished without loops. Cutscenes can be fully event-based.
The thing is, I’m not separating anything by scenes. Everything is contained in these loops, and each one controls a different part of the cutscene.
cutscene controls the main logic as well as the camera,
dialogue controls the dialogue,
animations controls the animations, and
blackout controls making the entire screen black, great for transitions. All of the information for these things are stored inside of a model inside of the cutscenes, separated into folders for everything except the camera positions, which are stored inside of a model. That is why I need to use the loops.
Also, the cutscenes are all handled in a localscript, as different players may be experiencing the cutscene at different times.
Scenes is just a heavy example as well as an assumption of mine but event-based structuring is still applicable here - it’s applicable in 90% of systems you will ever make or want to make. The crux of my response is not to focus in on my proposed solutions but rather what I’m getting at which is that you need to take a look at the structuring of your code.
None of this needs to be pseudothreaded; you can have events that advance every “step” of your cutscene, thus running a new dialogue/animation/transition as needed, then connect functions to those steps that will trigger one or more of those actions. As for your skip button, its responsibility would be to just end the cycle of events. Subsequently connected ones would not need to do anything because if those steps aren’t reached the relevant events wouldn’t be fired to begin with.
I come at this from exactly the same way I do my cutscenes which are also client-sided. We have animations for different NPCs as well as a dummy object that represents the camera. The camera’s animation sets use keyframe markers which primarily control how certain things during the cutscene should be triggered be it dialogue, transitions or marking when the overall cutscene should end.
You do not need to use loops.
I don’t understand, how would I cycle through all of the camera positions without loops?
Event-based system. Connect to those events to determine when the camera’s position should be changed or just use an animation to control the camera positioning. It’s either that or you have a single controllable variable that you can increment and as it increments you activate a new action in your scene. One to control them all, not four different coroutines running independently.
Reviewing your structuring, be it your code or the way you’ve set up your cutscene resources, is incredibly pivotal to fixing the root problem here.
For reference, again, my own cutscene:
Everything is run via animations, including the camera. This allows us to make use of keyframe markers to create an event-driven solution to cutscenes. We connect effects to happen based on those markers, as per the third quoted excerpt.
So, I would just have a separate script for every cutscene?
You don’t have to. Are you referring to all those scripts under Effects? Refer to the above post I made, the third quoted excerpt. Our cutscene module calls a function common amongst all these ModuleScripts, monitor, which tracks a model and a loaded animation. Then just before we play the animation we hook certain functions to occur when each marker of the animation is reached.
Example: if a “FadeOut” marker exists on any point of the camera’s animation, we apply a fade to our target item (in this case it’s for music).
You can still keep your current setup of using only a single script to control the way your cutscene works as well as your folder of resources relevant to the cutscene, but your best bet is to find a way to make your system event-driven so you don’t have to deal with all the headaches of loops/unable to yield a coroutine outside of itself/how to string all this together.
Okay, I must be some sort of idiot, I still have no idea how I’m meant to go about this. Is what you’re saying that a module script called from a local script that edits something in the explorer will still only edit on the client? (I know that’s not all you’re saying but that’s all that I could get from that.)