Is there a way to skip text after a time without clicking in Ren'Py?

Crab-Walk

XD
Game Developer
Jul 28, 2017
29
34
i want to make "animated" text, and im wondering if its possible to skip text without the player clicking.

thanks :)
 
  • Like
Reactions: boomurded

icesun

Be nice! Until it's time to not be nice...
Former Staff
Nov 2, 2018
904
2,411
i want to make "animated" text, and im wondering if its possible to skip text without the player clicking.

thanks :)
I'm no coder, I've just watched the beginning of a Ren'Py tutorial once, remembered the pause function and just googled something and found this:


renpy_delay.png

Is that what you're looking for?
 

Epadder

Programmer
Game Developer
Oct 25, 2016
568
1,064
I'm sort of confused as to what you want to do... :unsure:

In preferences there is already a way for someone to adjust the speed of displayed text and 'auto' mode which will advance after a delay, which is also adjustable.

I guess is there is a very specific part of the game that you want finer control of, you can use and pause... :whistle:
 

RedGlow

Well-Known Member
Aug 5, 2016
1,650
2,302
you can use auto clicker. A simple mouse program you can set it the way you want. For example, if you want it to press left click every 10 seconds, then set it and activate with hot key (f6 default). I use it to skip texts for unity games. Very usefull program.
"OP Auto Clicker 2.1" this is what i use.
 

smix8

Newbie
Sep 14, 2016
48
286
I assume since we are in the Dev Help Section you mean with RenPy code ..?
Depends what you need or plan to do ... create intro? Just hide the text without player clicking or turn it fast forward?

You can use inside a label
Code:
label start:
    show text "My awesome text" with dissolve
    with Pause(seconds)
to create a typical intro style text

If you mean to customize dialogue text lines with timed dismiss you can use the Ren'Py tags / / .. there are similar tags if you need control over text speed as well.

If you mean text shown with/on a RenPy screen you could also use a screen timer to hide the screen with the text again

Code:
screen my_awesome_screen_with_text:
    timer 3.0 action Hide('my_awesome_screen_with_text', dissolve)
    text "My awesome text"

label start:
    call screen my_awesome_screen_with_text with dissolve
or if a lot of changing text maybe show the screen and use a variable for the text inside. Give the text a RenPy "at" with a simple fadein/out transformation using the statement to make the text change more fluent.
Code:
default awesome_text = "my_awesome_text1"

my_awesome_tranimation:  
    on update:
        alpha 0.0
        linear 0.5 alpha 1.0
    on hide:
        alpha 1.0
        linear 0.5 alpha 0.0 
    on show:
        alpha 0.0
        linear 0.5 alpha 1.0
        
screen my_awesome_screen_with_text:
        text "[awesome_text ]" at my_awesome_tranimation
Geeeee ... so many options!
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
On top of all the your other options are {w}, {p} and straight up pause.
Edit: bahh, I hadn't noticed that smix8 had already mentioned them.

Details here:

... and an example of different types of "putting text on the screen, with and without user interaction"...
Edit2: Added spinning text graphic to my example program. It's technically what I think you're asking about... but it's horrible. Just sayin'.

Python:
label splashscreen:

    # This text will be shown in the center of the screen, against a black background.

    scene black
    scene bg_author_logo with dissolve
    pause(2.0)

    scene black with dissolve
    pause(0.5)

    show text "Author's Publisher Presents ..." with dissolve
    pause(1.0)

    hide text with dissolve
    pause(0.5)

    show text "Name of Author's Game" with dissolve
    pause(2.0)

    hide text with dissolve
    pause(0.5)

    return

label start:

    # For best way to see this, I'd suggest setting "Text Speed" to be pretty low in your preferences.

    "This is the first line, RenPy will wait for the player to click to continue."

    "This is the second line.{w} The second half of the sentence won't appear until the player clicks."
    # {w} is pretty much "wait"... until player clicks

    "This is the third line.{w=2} This part will automatically be displayed, after a short pause."
    # {w=n} is almost the same as {w}, except it advances after a time, not a player click.

    "This is the fourth line.{nw}"
    # {nw} at the end means "no wait"... it will automatically advance... often too quickly to see...

    "This is the fifth line, immediately after the fourth line without the user pressing anything."

    "This is the sixth line.{p=2}And oddly enough, this is the seventh."
    # {p} is almost the same as {w} (wait), except it's (paragraph)...
    # it puts a newline into the text too and the text after it appears 1 line below.
    # Like {w} and {w=n}, {p} will do the paragraph logic after a player clicks. {p=n} instead pauses by time.

    "This is the eighth line.\nThis is the nineth.{p=2}And this is the tenth, after a short pause."
    # Honestly, no reason why "\n" should be in this example... except it's similarity to {p}.
    # "\n" is also newline, but without a pause or player click.

    # Animated text? ... Jeez, well if you absolutely have to....
    "This line will have an animated spiny thing here :"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : (finished)  {fast}"
    # The {fast} makes everything before it appear immediately, even if text speed is set really low.
    # The {w=0.05} slows down the redisplay of each line, so there's a better sense of movement.
    # But it's the {nw} that really makes this happen.

    # Personally, I'd be more tempted to create an animate gif or something. Then use the {image=} tag to put it inline.
    "This line will have an animated spiny thing here : {image=spiny.gif}"
    # Maybe comment out this line, because lack of "spiny.gif" causes the program to crash.

    "### END OF EXAMPLE ###"

    return
I'd suggest just cutting and pasting this code into a test RenPy project and seeing how each line behaves.
 

RanliLabz

Creating SpaceCorps XXX
Donor
Game Developer
Mar 5, 2018
2,402
6,310
On top of all the your other options are {w}, {p} and straight up pause.
Edit: bahh, I hadn't noticed that smix8 had already mentioned them.

Details here:

... and an example of different types of "putting text on the screen, with and without user interaction"...
Edit2: Added spinning text graphic to my example program. It's technically what I think you're asking about... but it's horrible. Just sayin'.

Python:
label splashscreen:

    # This text will be shown in the center of the screen, against a black background.

    scene black
    scene bg_author_logo with dissolve
    pause(2.0)

    scene black with dissolve
    pause(0.5)

    show text "Author's Publisher Presents ..." with dissolve
    pause(1.0)

    hide text with dissolve
    pause(0.5)

    show text "Name of Author's Game" with dissolve
    pause(2.0)

    hide text with dissolve
    pause(0.5)

    return

label start:

    # For best way to see this, I'd suggest setting "Text Speed" to be pretty low in your preferences.

    "This is the first line, RenPy will wait for the player to click to continue."

    "This is the second line.{w} The second half of the sentence won't appear until the player clicks."
    # {w} is pretty much "wait"... until player clicks

    "This is the third line.{w=2} This part will automatically be displayed, after a short pause."
    # {w=n} is almost the same as {w}, except it advances after a time, not a player click.

    "This is the fourth line.{nw}"
    # {nw} at the end means "no wait"... it will automatically advance... often too quickly to see...

    "This is the fifth line, immediately after the fourth line without the user pressing anything."

    "This is the sixth line.{p=2}And oddly enough, this is the seventh."
    # {p} is almost the same as {w} (wait), except it's (paragraph)...
    # it puts a newline into the text too and the text after it appears 1 line below.
    # Like {w} and {w=n}, {p} will do the paragraph logic after a player clicks. {p=n} instead pauses by time.

    "This is the eighth line.\nThis is the nineth.{p=2}And this is the tenth, after a short pause."
    # Honestly, no reason why "\n" should be in this example... except it's similarity to {p}.
    # "\n" is also newline, but without a pause or player click.

    # Animated text? ... Jeez, well if you absolutely have to....
    "This line will have an animated spiny thing here :"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : \\  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : |  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : /  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : -  {fast}{w=0.05}{nw}"
    "This line will have an animated spiny thing here : (finished)  {fast}"
    # The {fast} makes everything before it appear immediately, even if text speed is set really low.
    # The {w=0.05} slows down the redisplay of each line, so there's a better sense of movement.
    # But it's the {nw} that really makes this happen.

    # Personally, I'd be more tempted to create an animate gif or something. Then use the {image=} tag to put it inline.
    "This line will have an animated spiny thing here : {image=spiny.gif}"
    # Maybe comment out this line, because lack of "spiny.gif" causes the program to crash.

    "### END OF EXAMPLE ###"

    return
I'd suggest just cutting and pasting this code into a test RenPy project and seeing how each line behaves.
Very interesting... I wish I'd found this post before I got two years into my game [:LOL: God, I'm bad at coding]

I was wondering if you knew how to skip text after a music track without the player clicking? e.g. so that when the first track ends the text box disappears and the second track and textbox kick in?
Code:
label start:
    scene background with Dissolve(1)
    play music "<from 0 to 180>sound/Troy_Holder_-_18_-_Lacrimosa_Mozart.mp3" noloop
    "Variation on Mozart's 'Lacrimosa'\nTroy Holder"

    scene black with Dissolve(1)
    play music "sound/piano_concerto_21.mp3" noloop
    "Piano Concerto No.21 in C major\nWolfgang Amadeus Mozart"
From your previous post, I know I could do this:
Code:
label start:
    scene background with Dissolve(1)
    play music "<from 0 to 180>sound/Troy_Holder_-_18_-_Lacrimosa_Mozart.mp3" noloop
    "Variation on Mozart's 'Lacrimosa'\nTroy Holder{w=179}{nw}"

    scene black with Dissolve(1)
    play music "sound/piano_concerto_21.mp3" noloop
    "Piano Concerto No.21 in C major\nWolfgang Amadeus Mozart{w=158}{nw}"
But that requires me to add the track length each time, and I have a lot of tracks to add! If you have any idea of how to avoid that, your assistance would be much appreciated!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
I was wondering if you knew how to skip text after a music track without the player clicking?
The problem is that there isn't, natively, a way to force a say statement to end ; Ren'py keep the hand until the player click, or the waiting delay end if the auto-forward mode is activated.

But it's possible to create your own following the logic. The principle being to get the duration of the music with , then use to compute the time left, and wait for this time before you effectively stop the interaction and pass to what's following this said statement.
This said, it would probably be something dirty ; working, but dirty, since it should probably imply a hack of renpy.character.DialogueTextTags.

Something like this should probably do it:
Python:
init python:
    def DTT__init__( self, s ):
        corrected = ""
        pauseDelay = None

        i = iter(renpy.character.TAG_RE.split(s))
        while True:

            try:
                corrected += i.next()

                quoted = i.next()
                i.next()
                tag = i.next()
                i.next()

                # Replace "mine" by the name you want to give to the tag.
                if tag == "mine":
                    # Replace "music" by the channel where the sound is played
                    pauseDelay = renpy.music.get_pos(channel="music")
                    if not pauseDelay is None:
                        # Replace "music" by the channel where the sound is played
                        pauseDelay = renpy.music.get_duration(channel="music") - pauseDelay
                else:
                    corrected += quoted

            except StopIteration:
                break
        self.OLD__init__( corrected )
        if not pauseDelay is None:
            self.pause_delay = pauseDelay

    if hasattr( renpy.character.DialogueTextTags, "OLD__init__" ) is False:
        setattr( renpy.character.DialogueTextTags, "OLD__init__", renpy.character.DialogueTextTags.__init__ )
        setattr( renpy.character.DialogueTextTags, "__init__", DTT__init__ )

    # Replace "mine" by the name you want to give to the tag.
    renpy.character.TAG_RE = renpy.re.compile(r'(\{\{)|(\{(mine|p|w|nw|fast)(?:\=([^}]*))?\})', renpy.re.S)
Then, if it works, you just use like this :
Code:
label whatever:
    play music SomeMusic
    "blablabla"
    "bliblibli {mine}"
This said, I gave a code that should works (have tested it without sound since I don't have something short enough right under the hand), but I don't recommend to use it.

As it, the player can still pass manually to the next statement with a click, but it can surely by corrected with the help of renpy.ui.saybehavior. No, the real problem is that you have no control over the time needed by the player to reach the last dialog line (the one with the new tag). Therefore, the music could have already stopped, what would fallback to the default behavior (click to continue), or, worse, the music can be near to its end, and don't let enough time to the player to read the whole dialog line.

While the {w} and {nw} text tag are interesting because they introduce more dynamism into the dialog, by making them advance by themselves, they have a big default. Either you'll wait too much, and the players who are at ease with English will have finished to read and will click, what will break the effect. Or at the opposite, you don't wait long enough, and the players who have difficulties to read English will not have finished to read the dialog line.
And obviously, the problem would be the same with this new text tag.



All this being said, the audio part is far to be what I know the most. So I perhaps missed something better linked to the audio voicing. From my point of view, if there's a more suitable solution, it probably fall there.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
I was wondering if you knew how to skip text after a music track without the player clicking? e.g. so that when the first track ends the text box disappears and the second track and textbox kick in?

Edit: DON'T DO IT. The more I think about it, the more I think you're going to just upset the players who are so used to RenPy behaving a certain way while playing. You're going to end up advancing too quickly or much too slowly - and users will wonder why the game timing feels off. This feels like one of those things like hard pauses in games, where you COULD do it - but really you never should.

Anyway, this was what I wrote first...



My first reaction was pause.

Basically, add pauses which are the same length as the music track after the dialogue and force the game to drop straight into that pause with a "no wait" tag. It would really only work if there was a single line of text though. If you had multiple lines, you'd need something more complex. But that falls fowl of you "I don't want to do that, because I have LOTS of music tracks".

Something like:

Python:
label somewhere:

   play music "mymusic1.mp3" loop False

   "A line of dialogue{nw}"      # use "no wait" tag to immediately continue
    pause 7.5                    # assuming music track is 7.5 seconds long.

    play music "mymusic2.mp3"    # playing one track will immediate end the previous track if it is still playing.
                                 # (i.e. if the player clicked to advance before the pause ended).

I did just briefly have a look at the documentation for the audio control . It looks like bad things could happen if the music channel is muted, and since you can't really predict whether players will switch off the music... it looks like a bit of a mine field.

Depending on the effect you are trying to achieve, you might want to look at , which will queue up a new music track for when the current music track ends. It won't sync up with your dialogue, but it will at least allow the first music track to finish before moving on to the second.

Personally, I think I would stick to the same solution pretty much every other game in history has used... Play the music on a loop and use when you finally want the music to stop.

It is probably worth remembering that by default, the music channel will loop sounds and the sound channel won't. Both can be overridden if needed.
 
Last edited:
  • Like
Reactions: RanliLabz

RanliLabz

Creating SpaceCorps XXX
Donor
Game Developer
Mar 5, 2018
2,402
6,310
The problem is that there isn't, natively, a way to force a say statement to end ; Ren'py keep the hand until the player click, or the waiting delay end if the auto-forward mode is activated.

But it's possible to create your own following the logic. The principle being to get the duration of the music with , then use to compute the time left, and wait for this time before you effectively stop the interaction and pass to what's following this said statement.
This said, it would probably be something dirty ; working, but dirty, since it should probably imply a hack of renpy.character.DialogueTextTags.

Something like this should probably do it:
Python:
init python:
    def DTT__init__( self, s ):
        corrected = ""
        pauseDelay = None

        i = iter(renpy.character.TAG_RE.split(s))
        while True:

            try:
                corrected += i.next()

                quoted = i.next()
                i.next()
                tag = i.next()
                i.next()

                # Replace "mine" by the name you want to give to the tag.
                if tag == "mine":
                    # Replace "music" by the channel where the sound is played
                    pauseDelay = renpy.music.get_pos(channel="music")
                    if not pauseDelay is None:
                        # Replace "music" by the channel where the sound is played
                        pauseDelay = renpy.music.get_duration(channel="music") - pauseDelay
                else:
                    corrected += quoted

            except StopIteration:
                break
        self.OLD__init__( corrected )
        if not pauseDelay is None:
            self.pause_delay = pauseDelay

    if hasattr( renpy.character.DialogueTextTags, "OLD__init__" ) is False:
        setattr( renpy.character.DialogueTextTags, "OLD__init__", renpy.character.DialogueTextTags.__init__ )
        setattr( renpy.character.DialogueTextTags, "__init__", DTT__init__ )

    # Replace "mine" by the name you want to give to the tag.
    renpy.character.TAG_RE = renpy.re.compile(r'(\{\{)|(\{(mine|p|w|nw|fast)(?:\=([^}]*))?\})', renpy.re.S)
Then, if it works, you just use like this :
Code:
label whatever:
    play music SomeMusic
    "blablabla"
    "bliblibli {mine}"
This said, I gave a code that should works (have tested it without sound since I don't have something short enough right under the hand), but I don't recommend to use it.

As it, the player can still pass manually to the next statement with a click, but it can surely by corrected with the help of renpy.ui.saybehavior. No, the real problem is that you have no control over the time needed by the player to reach the last dialog line (the one with the new tag). Therefore, the music could have already stopped, what would fallback to the default behavior (click to continue), or, worse, the music can be near to its end, and don't let enough time to the player to read the whole dialog line.

While the {w} and {nw} text tag are interesting because they introduce more dynamism into the dialog, by making them advance by themselves, they have a big default. Either you'll wait too much, and the players who are at ease with English will have finished to read and will click, what will break the effect. Or at the opposite, you don't wait long enough, and the players who have difficulties to read English will not have finished to read the dialog line.
And obviously, the problem would be the same with this new text tag.



All this being said, the audio part is far to be what I know the most. So I perhaps missed something better linked to the audio voicing. From my point of view, if there's a more suitable solution, it probably fall there.
Lol - much of that was greek to me [I don't know much python]. Unfortunately, it resulted in the following:
Screenshot (5).png
I suspect that I may be out of my depth here - and may simply go the {nw} way [meaning a couple of hours spent adding in track durations!] The assistance is hugely appreciated, though - and you clearly know your code! As for me... well, this is what happens when arts and humanities types try their hand at something technical :LOL:
Edit: DON'T DO IT. The more I think about it, the more I think you're going to just upset the players who are so used to RenPy behaving a certain way while playing. You're going to end up advancing too quickly or much too slowly - and users will wonder why the game timing feels off. This feels like one of those things like hard pauses in games, where you COULD do it - but really you never should.

Anyway, this was what I wrote first...



My first reaction was pause.

Basically, add pauses which are the same length as the music track after the dialogue and force the game to drop straight into that pause with a "no wait" tag. It would really only work if there was a single line of text though. If you had multiple lines, you'd need something more complex. But that falls fowl of you "I don't want to do that, because I have LOTS of music tracks".

Something like:

Python:
label somewhere:

   play music "mymusic1.mp3" loop False

   "A line of dialogue{nw}"      # use "no wait" tag to immediately continue
    pause 7.5                    # assuming music track is 7.5 seconds long.

    play music "mymusic2.mp3"    # playing one track will immediate end the previous track if it is still playing.
                                 # (i.e. if the player clicked to advance before the pause ended).

I did just briefly have a look at the documentation for the audio control . It looks like bad things could happen if the music channel is muted, and since you can't really predict whether players will switch off the music... it looks like a bit of a mine field.

Depending on the effect you are trying to achieve, you might want to look at , which will queue up a new music track for when the current music track ends. It won't sync up with your dialogue, but it will at least allow the first music track to finish before moving on to the second.

Personally, I think I would stick to the same solution pretty much every other game in history has used... Play the music on a loop and use when you finally want the music to stop.

It is probably worth remembering that by default, the music channel will loop sounds and the sound channel won't. Both can be overridden if needed.
You're absolutely right that I wouldn't do this as standard in the main game [though I may use the {nw} to improve a couple of animated sequences with music]. It's for a optional extra I'm doing as a Christmas prezzie for the Patrons, and the only dialogue required is the song-track names [long story short - licensing conditions to get some good quality free music in exchange for a plug].

Thanks for the additional, help - I think I'll go the {nw} way after all. Deep down, I always knew I'd end up doing that... I was just hoping against hope for a magical solution that didn't involve me learning how code works :LOL:
 
  • Like
Reactions: 79flavors

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
Unfortunately, it resulted in the following:
View attachment 941331
Hmm. "On my computer it works" :D
But as I implied I haven't fully tested it, so there probably some case I missed. I suspect that it was (totally) stupid to put the tag in the middle of the string in my test, and that it's what I missed ;)


You're absolutely right that I wouldn't do this as standard in the main game [though I may use the {nw} to improve a couple of animated sequences with music].
Put a {w=x} before it then, to not make the dialog line disappear immediately after being shown. With "x" being "0.2 * number of words in the sentence".
The average reading speed being of 250 words per minute, so 0.1438 second per word, 0.2, or 0.25, should works for most of the readers. But be aware that some would need more time and will probably be a little frustrated.

This being said, it made me wonder if... And it happen that yes, you can do what I said above, without relying on a hack:

It's totally not clear while reading the documentation, but {w} can works with a variable as value. It's just that {w=variable} don't works, it's {w=[variable]} that will ; I suspect a side effect from the text interpolation.
Therefore it can be done with something like :
Python:
init python:

    # Arguments:
    # - Channel where the music/sound is played.
    # - Minimal duration of the pause, in case there isn't enough
    # sound left.
    def musicLeft( channel, minimal ):
      
        #  When there's no music, get_duration return /0.0/, as expected for
        # a function returning a float, but get_pos return /None/... So you need
        # to have a ternary syntax for the assignation.
        duration = 0.0 if renpy.music.get_pos(channel=channel) is None else renpy.music.get_duration(channel=channel) - renpy.music.get_pos(channel=channel)
        # Then finally return the duration, or the minimal pause duration if higher.
        return max( duration, minimal )

label whatever:
    play music someMusic
    # Get the delay, with a minimal wait of 0.2 * 3 words in the dialog line.
    $ delay = musicLeft( "music", 0.2 * 3)
    #  And use the value you get as wait delay, before Ren'py finally
    # proceed the /nw/ and pass to the next statement.
    "Listen to this {w=[delay]}{nw}"
 

RanliLabz

Creating SpaceCorps XXX
Donor
Game Developer
Mar 5, 2018
2,402
6,310
Hmm. "On my computer it works" :D
But as I implied I haven't fully tested it, so there probably some case I missed. I suspect that it was (totally) stupid to put the tag in the middle of the string in my test, and that it's what I missed ;)




Put a {w=x} before it then, to not make the dialog line disappear immediately after being shown. With "x" being "0.2 * number of words in the sentence".
The average reading speed being of 250 words per minute, so 0.1438 second per word, 0.2, or 0.25, should works for most of the readers. But be aware that some would need more time and will probably be a little frustrated.

This being said, it made me wonder if... And it happen that yes, you can do what I said above, without relying on a hack:

It's totally not clear while reading the documentation, but {w} can works with a variable as value. It's just that {w=variable} don't works, it's {w=[variable]} that will ; I suspect a side effect from the text interpolation.
Therefore it can be done with something like :
Python:
init python:

    # Arguments:
    # - Channel where the music/sound is played.
    # - Minimal duration of the pause, in case there isn't enough
    # sound left.
    def musicLeft( channel, minimal ):
     
        #  When there's no music, get_duration return /0.0/, as expected for
        # a function returning a float, but get_pos return /None/... So you need
        # to have a ternary syntax for the assignation.
        duration = 0.0 if renpy.music.get_pos(channel=channel) is None else renpy.music.get_duration(channel=channel) - renpy.music.get_pos(channel=channel)
        # Then finally return the duration, or the minimal pause duration if higher.
        return max( duration, minimal )

label whatever:
    play music someMusic
    # Get the delay, with a minimal wait of 0.2 * 3 words in the dialog line.
    $ delay = musicLeft( "music", 0.2 * 3)
    #  And use the value you get as wait delay, before Ren'py finally
    # proceed the /nw/ and pass to the next statement.
    "Listen to this {w=[delay]}{nw}"
Looks like an interesting solution... although I already did it the laborious way [it works, if less elegantly than the ways you've suggested]. At some point, I'll have to try and find time to do a course in Python so I can follow what you're saying rather than just copy-pasting stuff :LOL: Thanks again, AON!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
At some point, I'll have to try and find time to do a course in Python so I can follow what you're saying rather than just copy-pasting stuff :LOL:
And you'll discover that you don't necessarily understand this much more because I rarely follow Python's logic :D


More seriously, my first (and stupid) attempt was nothing really complicated (when you've decades of experience like me ;) ), so here's your first logic course.

But firstly, don't worry you don't really understand. I don't expect a reader with few experience to understand, I don't teach here, I present a way to approach a problem and solve it. Even if you don't understand, it will stay in your mind and influence you in the future. It will also make it easier to understand the next time you'll see a code doing the same kind of things, or a discussion talking about it.
And for now, it's what matter.

You don't have permission to view the spoiler content. Log in or register now.



Thanks again, AON!
You're welcome
 

Josephkink_2H

Member
Aug 15, 2020
262
71
I can't skip Seen Text in my game. Please tell me if this look right to you:

#vbox:
frame:
style_group "pref"
has vbox

label _("Skip")
textbutton _("Seen Messages") action Preference("skip", "seen")
textbutton _("All Messages") action Preference("skip", "all")

frame:
style_group "pref"
has vbox

textbutton _("Begin Skipping") action Preference("begin skipping")

frame:
style_group "pref"
has vbox

label _("After Choices")
textbutton _("Stop Skipping") action Preference("after choices", "stop")
textbutton _("Keep Skipping") action Preference("after choices", "skip")
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
I can't skip Seen Text in my game.
Hmm.
Start a game, advance few dialog lines, then restart the game. Even there you can't skip seen text ?


Please tell me if this look right to you:
It's not the best way to do it ; using "toggle" as value to switch from one state to the other, would be better. But both the labels and values are correct.
 

Josephkink_2H

Member
Aug 15, 2020
262
71
Hmm.
Start a game, advance few dialog lines, then restart the game. Even there you can't skip seen text ?
Yeah, I can't get it to skip. Plus when Rollback with my mousewheel, it sometimes jumps to a few screens ago-like was said, I'm working with a script that might have been flawed, but I added a mod to it that was not fully compatible. Add to the mix the coding like this isn't my profession and you got a high possibility of mishaps. I studied HTML in school and deal with it a little now and know enough to know that any little change I make without knowing the effects in-game could cause havoc with the game itself.

I've scoured the Internet and found some good resources for the script/screens in the game. I've also downloaded the original game to compare/contrast with changes I make, but without knowing the effects of certain things, it's a lot of trial and error. What can I do to minimize that so I can play the game while skipping the parts I've already seen?

It's not the best way to do it ; using "toggle" as value to switch from one state to the other, would be better. But both the labels and values are correct.
I got rid of the Begin Skipping Button
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
Yeah, I can't get it to skip.
It's really strange.
I would have understood if it was because of the rebuilt RPYC files, but then the control method I gave should have worked. Therefore, either I'm missing something, or the skip feature have been tweaked.


Plus when Rollback with my mousewheel, it sometimes jumps to a few screens ago-like [...]
This is, relatively speaking, normal. The rollback don't rely on the code lines, but on the interaction. Therefore sometimes it skip more than expected, because everything happened during a single interaction.
Plus there's way to control the rollback, forcing it to count a whole block as a single interaction, or to go back to a given point.


I'm working with a script that might have been flawed, but I added a mod to it that was not fully compatible. Add to the mix the coding like this isn't my profession and you got a high possibility of mishaps.
This can apply to the rollback problem, because there's a small dose of magic involved, but not to the skip one. You can't really interfere with the skip feature without knowing it.


What can I do to minimize that so I can play the game while skipping the parts I've already seen?
Without knowing the effective cause, no one can answer this. As I said, the test I made you do eliminated the only natural explanation. So the solution is to revert what they did, what obviously can't be done without first knowing what they did.

What game is it ?
 

Josephkink_2H

Member
Aug 15, 2020
262
71
It's really strange.
I would have understood if it was because of the rebuilt RPYC files, but then the control method I gave should have worked. Therefore, either I'm missing something, or the skip feature have been tweaked.




This is, relatively speaking, normal. The rollback don't rely on the code lines, but on the interaction. Therefore sometimes it skip more than expected, because everything happened during a single interaction.
Plus there's way to control the rollback, forcing it to count a whole block as a single interaction, or to go back to a given point.




This can apply to the rollback problem, because there's a small dose of magic involved, but not to the skip one. You can't really interfere with the skip feature without knowing it.




Without knowing the effective cause, no one can answer this. As I said, the test I made you do eliminated the only natural explanation. So the solution is to revert what they did, what obviously can't be done without first knowing what they did.

What game is it ?
The game is Babysitter by T4boo and, for some reason, he included all the screens in the script. So I have access to Say, Input, Nav, Prefs, etc.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
The game is Babysitter by T4boo and,
Hmm. The one without the trailing "s" are you sure (T4boo also have a game named "babysitters" ? I don't know for the mods, but just tried it, and the skip feature works perfectly. There's small parts where the skip is a little messed because they aren't effective dialog/interaction, but when the game fallback to "normal Ren'py", it skip as expected.
What mess with the skip feature is located somewhere else :/


for some reason, he included all the screens in the script. So I have access to Say, Input, Nav, Prefs, etc.
It's normal, it's the same with all Ren'py games.