Ren'Py Disable the "advance" function so users don't skip slideshow

ChaosOpen

Well-Known Member
Game Developer
Sep 26, 2019
1,013
2,133
I like to use a series of images with a long(~1 second) dissolve between each which makes a quasi slideshow to demonstrate movement such as walking down a hall or such. It is simple to set up and figure out but makes a decent illusion of movement as long the the images link up. It's very simple in concept, the the result can be quite pretty depending on when and how it is used.
In renpy, it looks like this:
scene emily_1_16 with Dissolve(1.1)
scene emily_1_15 with Dissolve(1.1)
scene emily_1_14 with Dissolve(1.1)
scene emily_1_25 with Dissolve(1.1)
scene emily_1_10 with Dissolve(1.1)
scene emily_1_11 with Dissolve(1.1)
scene emily_1_12 with Dissolve(1.1)
scene emily_1_13 with Dissolve(1.1)

However, after playtesting, I noticed that some people would click right though it. In other words, even though the images are playing, clicking the mountain twice would skip all of the images and bring you directly to where the text is. they would get to the first frame then if the words didn't instantly appear they would click again, completely missing the effect.
I tried using $ renpy.pause() in response and it looked bad as the whole effect was predicated on each image immediately transitioning into the next in one continuous chain. Some will sit and wait for an uncomfortable amount of time before they finally figure out they need to click again.

What I want to know is if there is a way to pause the user input during that section so that they watch it without having to ruin the effect?
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
Yes. But you shouldn't do it.

Firstly, there's how you're doing the slide show... you would be better to let RenPy handle stuff for you...

Python:
image anim_emily_1_10:
    "emily_1_16" with dissolve
    pause 0.75
    "emily_1_15" with dissolve
    pause 0.75
    "emily_1_14" with dissolve
    pause 0.75
    "emily_1_25" with dissolve
    pause 0.75
    "emily_1_10" with dissolve
    pause 0.75
    "emily_1_11" with dissolve
    pause 0.75
    "emily_1_12" with dissolve
    pause 0.75
    "emily_1_13" with dissolve

# later....

    scene anim_emily_1_10
    pause 9.5

-or-

    scene anim_emily_1_10 with Pause(9.5)

Now the answer to your question is...

Python:
    scene anim_emily_1_10
    $ renpy.pause(9.5, hard=True)

The forces the player to wait for whole pause to complete. And if you implement it that way, nobody will thank you and some people will hate it.

As a content creator... I get it... you want the player to see the thing you spent all that time rendering.
But some players will just want to skip through it... and you're stopping them.

As someone who spends some of my time testing games, I will say that hard pauses are the bane of my life. I'm busily fast forwarding through some part of a game I've seen dozens of times and suddenly I'm stopped in my tracks to wait for a hard pause.

Give the player the choice... even if that choice is to bypass the thing you REALLY, REALLY want them to see.

To quote ...
In general, using hard pauses is rude. When the user clicks to advance the game, it's an explicit request - the user wishes the game to advance. To override that request is to assume you understand what the player wants more than the player does.
tl;dr - Don't use renpy.pause with hard=True.

The other solution I would put forward as an alternative is to build the single displayable animation as I've described above and then have 2 to 5 lines of dialogue after it before the next scene statement.

Python:
    scene anim_emily_1_10
    pause 3.0
    "a line of dialogue."
    "another line of dialogue."
    "a reply from whomever."
    "something else that was said."

    scene something_else with dissolve

By having a smaller pause, the animation will start to play full screen, without the textbox at the bottom of the screen. After 3 seconds (or whatever you choose), the dialogue will start to be shown - but the animation will continue to be shown in the background. Assuming the player takes over 6 seconds (plus the 3 from the pause) to read the dialogue before the next scene - they will see the whole slideshow.

This is always my preferred solution, as it lets the player continue - but they still likely see the whole thing. The pause at the beginning prepares them that an animation is being show.
 
Last edited:

ChaosOpen

Well-Known Member
Game Developer
Sep 26, 2019
1,013
2,133
The image itself shouldn't be in focus for more than a fraction of a second, so possibly $ renpy.pause(0.1, hard=True)

And I doubt people will be *too* upset that they skipped them, as I will often use them in make-out scenes as well, and an over-developed mouse finger will lead you to a scene which goes: sees characters lean in for kiss >*doubleclick* > characters have finished kiss > upset because they thought I copped out with the kiss animation.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
The image itself shouldn't be in focus for more than a fraction of a second [...]

Erm... Your initial example was a series of scene emily_1_16 with Dissolve(1.1). That's 1.1 seconds per transition, for a total of around 8.8 seconds. That's hardly "fractions of a second". It's what I based my 9.5 seconds around (0.5 seconds per normal dissolve + 0.75 seconds between images).

If the timing is different, that's fine.

And I doubt people will be *too* upset that they skipped them [...]

To quote the great James Dalton: "Opinions vary".

[...] and an over-developed mouse finger will lead you to a scene which goes: sees characters lean in for kiss >*doubleclick* > characters have finished kiss > upset because they thought I copped out with the kiss animation.

And for anyone who is mindless clicking, there's always the [back] button.

Please, just humor me. Try moving the next scene statement a few lines downward, build the image statement how I described and try using the scene/pause combo I recommended. I recognize that the hard pause seems the simpler solution, but just try the alternative before dismissing it out of hand.

Other than that... I tried.
 
Last edited:
  • Like
Reactions: Cryptist
Apr 24, 2020
192
257
The image itself shouldn't be in focus for more than a fraction of a second, so possibly $ renpy.pause(0.1, hard=True)

And I doubt people will be *too* upset that they skipped them, as I will often use them in make-out scenes as well, and an over-developed mouse finger will lead you to a scene which goes: sees characters lean in for kiss >*doubleclick* > characters have finished kiss > upset because they thought I copped out with the kiss animation.
If your players are already skipping stuff then I would consider it upsetting to be forced to pause.

I'm just worried that you consider a 8.8 second forced pause to not be intrusive, because I'm betting that you will start using those forced delays in every other scene you want your players to watch.

A 0.5 second pause might not sound like much, but it's one of the most infuriating things I've found in the code of another game. I thought the scene transition was just being slow, but it turned out that the developer intentionally placed it in a transition the players would have to watch hundreds of times.

We all create our things with love and care, and I would hate if a first time player just skips through everything. I'm just worried that you are trying to fix the behavior of your most dedicated fans whom are willing to play your game more than once.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
If your players are already skipping stuff then I would consider it upsetting to be forced to pause.

I think he's more concerned with the accidental click or potential double-click.

If I had to guess, his current plan is 0.1 seconds hard pauses between the original lines that included with Dissolve(1.1). Something to halt the progress of the player between each transition, without forcing the player to wait more than 0.1 seconds.

Obviously I still prefer my "build , show ATL image with pause (using scene), put at least 1 line of dialogue before the next scene statement so that the animation continues to be played, despite the player advancing". But then I would, wouldn't I? It's RenPy... there is no single "right" answer.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,363
15,277
I like to use a series of images with a long(~1 second) dissolve between each [...]
It's the worse possible way. There's an option in Ren'py to skip the transition, and your whole animation rely solely on transition. What mean that there's players who'll not even have to click to not see your animation.


The image itself shouldn't be in focus for more than a fraction of a second, so possibly $ renpy.pause(0.1, hard=True)
Solving a design error by adding a second design error is never the right solution.
When 79flavors explain you how to use the feature especially created for what you are trying to do, you shouldn't discard it this easily. Especially if it's to continue using transitions totally out of their purpose.
It's like wanting absolutely to do The Mans with a bicycle, when someone offer you a sport car. Not only you'll loose a lot of times trying to make your bicycle to go at least as fast as a LMP2, but you'll also never have the guaranty that it will not explode to your face before the end of the 24 hours. Two things that will not happen if you just accept the offer made to you by someone who know and nicely try to teach you.


As someone who spends some of my time testing games, I will say that hard pauses are the bane of my life. I'm busily fast forwarding through some part of a game I've seen dozens of times and suddenly I'm stopped in my tracks to wait for a hard pause.
You don't have something like that yet ?
Code:
init 1000 python:

    def AONsoftPause( *args, **kwargs ):
        if "hard" in kwargs: kwargs["hard"] = False
        AONoriginalPause( *args, **kwargs )

    AONoriginalPause = renpy.pause
    renpy.pause = AONsoftPause
 
  • Like
Reactions: 79flavors

ChaosOpen

Well-Known Member
Game Developer
Sep 26, 2019
1,013
2,133
So, if I use this image ALT image, can I only use the default Dissolve timers?
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
So, if I use this image ALT image, can I only use the default Dissolve timers?

No. You can use any transition you can use elsewhere.
Although you also still need a pause between each image within the ATL to give the Dissolve() time to do it's thing. This is only about the timing within the ATL block, the game needs a separate pause to wait for the ATL to complete (or partially complete).

Using your own image names, I'd expect something like:

Python:
image anim_emily_1_16:
    "emily_1_16" with Dissolve(1.1)
    pause 1.1
    "emily_1_15" with Dissolve(1.1)
    pause 1.1
    "emily_1_14" with Dissolve(1.1)
    pause 1.1
    "emily_1_25" with Dissolve(1.1)
    pause 1.1
    "emily_1_10" with Dissolve(1.1)
    pause 1.1
    "emily_1_11" with Dissolve(1.1)
    pause 1.1
    "emily_1_12" with Dissolve(1.1)
    pause 1.1
    "emily_1_13" with Dissolve(1.1)
    pause 1.1

label start:

    scene black with fade
    "*** THE START ***"

    scene anim_emily_1_16 with Pause(8.8):
    mc "Oh, that was wonderful."

    scene black with fade
    "*** THE END ***"
    return

In this case, the animation will be shown fullscreen for 8x 1.1 seconds.
If however, the player clicks (or accidentally clicks), things will advance to the main character saying "Oh, that was wonderful", with the animation still playing in the background (unless it had finished already). Until the player clicks again and the "THE END" line in shown after a fade to black.

If there were more than one line of dialogue before the next scene, the animation would continue through all those lines. Only the next scene statement will stop it. (Especially handy for animations/ATL using to cause the animation to loop).

Personally, despite the animation being 8.8 seconds long, I'd be tempted to use with Pause(4) or with Pause(6) and then at least one line of dialogue. So the game continues on to the line of dialogue while the animation is still active. That one is very much personal preference though, for me it offers the best of both worlds... a long animation with the option for the player to continue reading the game text.
 
Last edited:
  • Like
Reactions: anne O'nymous

ChaosOpen

Well-Known Member
Game Developer
Sep 26, 2019
1,013
2,133
Sorry it took so long to explain that, I didn't quite understand it, I thought you guys were like "never use transitions for such a thing" and my first response was "if it looks stupid, but it works, it ain't stupid." So, I hope you can understand the pushback. Here are the series of images in case you guys were wondering why I thought it was worth watching an 9 second animation. The character is lost and looking down both ends of the hallway, and for swinging the camera along the length of a hallway, 8.8 seconds is a long time.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
No worries. It's your game - so you can make any choices you like.
I'm here to offer advice, not beat you into submission.

Though it's a fine line when hard pauses are involved. Where some beating may be justified.
 

ChaosOpen

Well-Known Member
Game Developer
Sep 26, 2019
1,013
2,133
Nothing can ever be easy can it?

EDIT: Found it, I put "with pause" instead of "with Pause"

Untitled2.png
Untitled.jpg
 
Last edited:

TDoddery

Member
Apr 28, 2020
170
160
I'm guilty of using hard pause but only because someone complained my game had no animations when obviously they had just clicked through before they even noticed an animation was there.

So I try to use a hard paus just short enough to prevent a click-happy player accidentally missing the fact there is an animation, but not long enough to be too annoying for a " yeah ok animation I'm gonna skip it" type player.

I would also imagine there's a way to code a half-way-house whereby the hard pause only happens first time around and skipping can ignore it thereafter.

In Dev mode that seems to happen by default.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,363
15,277
[...] "if it looks stupid, but it works, it ain't stupid."
The problem I have with such approach is that it's something that can be done only by advanced users. This simply because you need a lot of knowledge to know that it effectively works. You can't limit your "it works" to your own configuration and way to use it, you need to understand the implied mechanism(s) in order to anticipate the reaction of your trick when done with another configuration or way to use it.

Take your animation by using Dissolve transition, by example. You thought that it works, but it's not the case since a simple click in "skip transitions" on the preference menu is enough to break all the animations in your game ; a player that want to skip the transitions will just see the last image of them.
It's the same for the pause statement. For a long time I said "don't use renpy.pause, there's pause for that". Until the day I discovered that the said pause partly rely on the Pause transition ; what imply that if a player skip the transition, he will also skip all your pauses.

There's around there, games that use:
Code:
    show screen whatever
    pause
because their authors don't know about call screen, that they should have used. It seem to be a trick that works whatever how stupid it looks. But there's two issues. Firstly if the author didn't used the modal screen property, a click outside of a button will make the game advance by itself. Secondly, and like your animations made with Dissolve, if the player decide to skip the transitions, the pause will be automatically skipped. In both case, not only the game will continue to advance after the supposed navigation screen, but due to Ren'py implicit label branching, it will also have a totally erratic behavior.
Those authors think that they found a stupid trick that works, while in fact they just haven't effectively tested their broken way to do something.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
EDIT: Found it, I put "with pause" instead of "with Pause"

The way I always think about it is that if you need to put a parameter in the () after it, it needs a capital letter.
So with dissolve is lowercase, and with Dissolve(1.1) is Capitalized.
 
  • Like
Reactions: obsessionau

obsessionau

Member
Game Developer
Sep 27, 2018
268
368
"if it looks stupid, but it works, it ain't stupid."
This is an interesting debate I will chime into. :)

I see it as the difference between "knowledge" and "understanding". I have knowledge of many Ren'Py/Python commands and I can use them to do what I want it to do - but I often code in a inefficient way. Unfortunately I don't understand how many of these commands interact with and affect other elements. This can create far reaching problems later on down the track when you get a error in something that is written correctly, however does not work with what you already have.

However I code 3-4 weeks a year so I don't bother to learn it so deep as I will forget it by the time I use it again. Which brings us back to that statement "if it's stupid but works, it ain't stupid". Yes it is stupid not to totally understand a command before you use it. But there are often other factors involved that other people don't understand that make your decision "appear" stupid. But as they don't understand my dilema and that it works for me, it ain't stupid.
 

ChaosOpen

Well-Known Member
Game Developer
Sep 26, 2019
1,013
2,133
The problem I have with such approach is that it's something that can be done only by advanced users. This simply because you need a lot of knowledge to know that it effectively works. You can't limit your "it works" to your own configuration and way to use it, you need to understand the implied mechanism(s) in order to anticipate the reaction of your trick when done with another configuration or way to use it.

Take your animation by using Dissolve transition, by example. You thought that it works, but it's not the case since a simple click in "skip transitions" on the preference menu is enough to break all the animations in your game ; a player that want to skip the transitions will just see the last image of them.
It's the same for the pause statement. For a long time I said "don't use renpy.pause, there's pause for that". Until the day I discovered that the said pause partly rely on the Pause transition ; what imply that if a player skip the transition, he will also skip all your pauses.

There's around there, games that use:
Code:
    show screen whatever
    pause
because their authors don't know about call screen, that they should have used. It seem to be a trick that works whatever how stupid it looks. But there's two issues. Firstly if the author didn't used the modal screen property, a click outside of a button will make the game advance by itself. Secondly, and like your animations made with Dissolve, if the player decide to skip the transitions, the pause will be automatically skipped. In both case, not only the game will continue to advance after the supposed navigation screen, but due to Ren'py implicit label branching, it will also have a totally erratic behavior.
Those authors think that they found a stupid trick that works, while in fact they just haven't effectively tested their broken way to do something.
It's not a matter of "knowing a better way and doing it wrong out of spite." I wanted to simulate movement from a series of still images, only way I knew how to do that was to use a long dissolve, I then proceeded to run into a problem, that is where you guys came in, and I did apply your teachings. I got some advice, some criticism, and tried my best to defend why I did it that way at the time when I was asked why I used the dissolve command rather than anything else.

As for call screen I have seen it but am not sure as to its use despite wanting to put a screen such as what is seen in games such as: "Eroge! ~Sex and Games Make Sexy Games~"
114441.jpg

in which you are continuously taken back to a main "hub" where you select a girl by clicking on an imagebutton. Because what I have looks like ass:

Untitled3.png

Though, how does one place the images with any degree of accuracy beyond guess-and-check?
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
There's always a better way to do things in RenPy.

There's always things you would do different/better next time around. Which isn't to say it wasn't "good enough" this time around.

The biggest pitfalls are those things you think are working as intended, but aren't. But you can't know what you don't know - so don't sweat it. If you're happy with your solution, that's enough for right now in most cases.

As for call screen -vs- show screen...
  • show screen displays a predefined screen onto the game UI, then the game immediately continues.
  • call screen does more or less the same, except the game effectively stops and waits for the player to click on something that triggers an action before it executes that action. Depending on the action, the game may continue on the next line, or jump somewhere else.
 
  • Like
Reactions: anne O'nymous

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,363
15,277
It's not a matter of "knowing a better way and doing it wrong out of spite."
Good, because it's not what I said.


I wanted to simulate movement from a series of still images, only way I knew how to do that was to use a long dissolve, [...]
Why not start by opening the documentation that come with Ren'py, and is located in the same directory than the executable, then look at the index to see if there weren't an entry regarding animations ? Just to see if there isn't another way that you can learn ?

I have nothing against helping others, apparently I earned a badge by doing it. I also have nothing against basic questions, and don't think that there's stupid questions. But there's one thing I care for, it's the advantage that Ren'py give to the scene.
Being both relatively easy to use, even for people with no initial knowledge, robust and powerful, it's a wonderful engine that permit to anyone to give a try into game making. But the fact is that, after more or less 2 years of really intense use of this engine, it start to follow the steps of RPG maker ; being hated by the community because too many game authors prefer to pass one day inventing a solution that will end being broke, to half an hour reading the documentation.
This precisely because they think that "if it works, it's not stupid". And this not because it's stupid, but because in reality it don't works. But like few people will effectively give feedback, and most people will just go their way when they found a bug, most of them will never realize it ; simply wondering why their game don't have a little more success than that. And in your particular case it's worse, because people who skip transitions wouldn't even realize that there's a bug. They would just see the last image of your animation and, unless they found a message talking about this animation, just think that the game is expected to be like that.

I don't care how much of a mess their code can be. I don't care what solution they used to do this or that. But I care when people start to see the "RENPY" tag, and their first thought is "yet another broken game, I pass". I care because behind the game there's a guy, or a girl, that wore his/her ass out, passing all his/her free time doing this game, and this person deserve a better treatment from the community ; this whatever the quality of the game (s)he's making. Be noted that you are one of them, your creation is one of those games that deserve a better treatment.

So I'm probably a little harsh, sorry about that, but I'm a passionate person, and when I've something to say, I say it with the intensity of this passion. Especially when it's something I care for, like it's the case here.



The biggest pitfalls are those things you think are working as intended, but aren't. But you can't know what you don't know - so don't sweat it.
Despite what I said above, this is also my thought. I have nothing against you personally Vitalsigns , nor against your solution. I'm just tired of the way Ren'py games and their authors are treated.