-
-
Notifications
You must be signed in to change notification settings - Fork 493
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
Support for skippable cutscenes #1513
Conversation
…ate_wrapper=on ..; make) so it fixed a few errors I made
This seems very thoughtfully designed, I'm hoping it gets implemented soon |
@Semphriss I think cutscenes should also be skippable with 'enter' and the 'jump key' since these are usually used for menus and might be more intuitive than 'escape'. |
What I'm afraid of is the player accidentally pressing the action button at the beginning of a cutscene, which might happen, for example, if the cutscene happends when activating a switch, or when carrying an object, where there is a risk the player releases the key too late, or spams it, which might unintentionally result in skipping the cutscene. I'd recommend using a key that is unlikely to be used in-game to avoid such problems, hence why I originally picked the escape button. |
I suggest displaying “Press Esc to skip” if any other key is pressed. |
…he screen. FIXME: The text is sometimes not displayed when testing a level from the editor.
…nto skippable_cutscenes
* Skippable cutscenes support. * Fixed the wrapper.cpp file.I rebuilt it the proper way (cmake -DGenerate_wrapper=on ..; make) so it fixed a few errors I made * Removed unnecessary property (added while testing methods for skippable cutscenes) * Skippable cutscenes now display a message in the top-left corner of the screen. FIXME: The text is sometimes not displayed when testing a level from the editor. * Fixed a problem with the cutscene skip message sometimes not showing * Fixed coding style * Improved code quality and removed unnecessary comment Co-authored-by: Semphris <semphris@protonmail.com>
From now on, you can skip cutscenes!
Read the info for : Players • Level designers • Programmers
Info for players
If you're playing a level with a cutscene, hit escape, and the cutscene will instantly finish! Speedrunners and impatient players, this is for you!
(Applicable only to levels implementing the functionality - won't work yet for older levels! ;) If you want, you can edit these levels and submit your changes.)
Info for level designers
If your levels contain cutscenes, you can say goodbye to watching them every time you test your levels - now you can make them skippable by using these to simple functions!
How can my level support skippable cutscenes?
In your Squirrel scripts, simply add
start_cutscene()
at the beginning of your cutscene, and at the end, addend_cutscene()
. Simple as that! Now, you can skip your cutscene simply by hitting the escape button on your keyboard :)Will this break my level?
It shouldn't - all the code that happens in your script will be executed, and it will all happen in order - it just will do everything instantly instead of waiting :)
Still, it is always a good idea to try to skip cutscenes to make sure your level doesn't break. If you encounter a problem, let me know! :)
Good practices with cutscenes
There are certain types of cutscenes that shouldn't be made skippable. For example, cutscenes where the amount of time elapsed is critically important (for example, a door closing very slowly and relying on the fact that Tux can't move while it closes) shouldn't be made skippable to avoid letting the player pass under the door if the skip the cutscene and run fast enough. It is however a good idea to keep these cutscenes as short as possible.
Very recommended : At the end of each cutscene, try to "reset" time-based actions as much as possible. For example, if you use smooth fade-ins or fade-outs, add a final fade-in of 0 seconds to make sure the level is visible and clear once the cutscene is over. If your cutscene ends with, say, a final fade-in of 2 seconds, you space the final fade-in and the "reset calls" with
wait(2)
. Make sure thatend_cutscene()
is called with those reset calls. (Before or after, doesn't matter)Example :
Or :
Info for programmers
How it works
(Requires understanding the info for level designers)
TL;DR It basically cancels all calls to
wait(float)
betweenstart_cutscene()
andend_cutscene()
.Details :
start_cutscene()
is called, it stores a variable in the Level object to remember that a cutscene started. (The variable is in the level, so that if an unskilled level designer callsstart_cutscene()
but never callsend_cutscene()
, the erronous state won't spread to other levels.)wait(float)
withwait(0)
. The call towait
is not completely ignored in case some scripts are coded likewhile (true) {wait(0.5), ...}
, so that they won't freeze the game. Note : Only calls towait
that were executed afterstart_cutscene()
(and beforeend_cutscene()
) will be skipped. That is, if there is another script using waits but not cutscene functions, they will not be fast-forwarded.end_cutscene()
is called, either after skipping the cutscene or displaying it normally, both variables are reset and all calls towait(float)
will work as expected.Backwards compatibility
The addition is effectless on current levels. To use the system of skippable cutscenes, a level must make use of
start_cutscene()
andend_cutscene()
.I tried to make the integration as seamless and simple as possible, so it won't for example, skip some important code. Still, it is good to always test each cutscene to make sure there aren't any bugs, visual artifacts, or other unwanted side effects.
Such side effects will most likely take the form of effects taking time to finish after the cutscene was skipped. For example :
When skipping, notice how the
fade_in
is still running. This happens becausefade_in
is non-blocking and still executed after the cutscene is over.The "skip-the-cutscene" case scenario cancels calls to
wait
, so the code will be executed like this :Notice how
fade_in
andend_cutscene
are called at the same time.fade_in
will still do something afterend_cutscene
has been called.This :
...won't work either, as
wait
is ignored when skipping a cutscene.The solution is this :
One final call to
fade_in
with a time of 0. This will make sure that once the cutscene is finished, all effects are in the state they are expected to be.The "skip-the-cutscene" case scenario will execute it like this :
Effect.fade_in(0);
will be effective immediately, correcting the problem.Bug prevention
I made the system as resilient as I could against poor level designers. Wrongful calls (
start_cutscene()
twice in a row,start_cutscene()
not paired with a correspondingend_cutscene()
, orphanedend_cutscene()
(without astart_cutscene()
), etc.) will not result in undefined behavior, but will rather display a warning in the console and attempt to recover safely. Plus, the variables are stored inside the Level object, so that errors arising from a given level won't spread across the game or affect another level.