Text scrolling/ dialogue sounds, per word

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Message
Author
DragoonHP
Miko-Class Veteran
Posts: 758
Joined: Tue Jun 22, 2010 12:54 am
Completed: Christmas
IRC Nick: DragoonHP
Location: Zion Island, Solario
Contact:

Re: Text scrolling/ dialogue sounds, per word

#16 Post by DragoonHP »

I tested it out three times after posting the last time, and it's in complete sync for me. And as far as I can see, there is nothing in the code which will make it go out of sync.

I will probablly test it out on a different system just to be sure or maybe OP might help me in testing it. :p
Ah well, it's not a priority in any case.

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Text scrolling/ dialogue sounds, per word

#17 Post by xela »

It shouldn't really be system related so the only thing I can think of that's different and that might matter is the file:

https://www.dropbox.com/s/ye38m6kkhnrrxcr/beep.mp3?dl=0
Like what we're doing? Support us at:
Image

DragoonHP
Miko-Class Veteran
Posts: 758
Joined: Tue Jun 22, 2010 12:54 am
Completed: Christmas
IRC Nick: DragoonHP
Location: Zion Island, Solario
Contact:

Re: Text scrolling/ dialogue sounds, per word

#18 Post by DragoonHP »

Perfect sync. This one actually finishes playing off before the next letter is shown :p

EDIT: After repeated testing (I can only hear beeps now), I think there is like a 0.1 sec lag though between the last letter rendering and the sound playing.

DragoonHP
Miko-Class Veteran
Posts: 758
Joined: Tue Jun 22, 2010 12:54 am
Completed: Christmas
IRC Nick: DragoonHP
Location: Zion Island, Solario
Contact:

Re: Text scrolling/ dialogue sounds, per word

#19 Post by DragoonHP »

So finally managed to repeat the bug xela mentioned. It happened for speed > 5

The only change required:

Code: Select all

                    s = re.sub(r"{.+?} ", "", s) # Instead of capturning "{something}" we had to capture "{something} "
Full code:

Code: Select all

init python:
    def check_for_tags(s):
       
        if "{fast}" in s:
            s = s.split("{fast}")
            s = s[-1]
       
        if "{w" in s:
            s = s.replace("{w", " |##")
       
        if "[p" in s:
            s = s.replace("{p", " |##")
       
        s = s.replace("}", "} ")
       
        return s
   
    def beepy_voice(event, interact=True, **kwargs):
        global _last_beeped_text
       
        if not interact:
            return
           
        if event == "show_done":
            # Using _last_raw_what makes the callback compatible with extend character.
            # Fair warning: _last_raw_what is undocumented and subject to change.
            s = _last_raw_what
            speed = float(_preferences.text_cps)
           
            if s and speed:
                import re
               
                intervals = []
                padding = 0
               
                if not _last_beeped_text:
                    if "{fast}" in s or "{w" in s or "{p" in s:
                        s = check_for_tags(s)
                       
                    s = re.sub(r"{.+?} ", "", s) #Instead of capturning "{something}" we had to capture "{something} "
                   
                    # Whenever we encounter a click-to-continue tag, split the string.
                    _last_beeped_text = s.split("|##}")
               
                words = _last_beeped_text.pop(0).split()

                for w in words:
                    # If number of seconds is provided, add it to interval.
                    if "|##=" in w:
                        try:
                            padding += int(w[4:-1])
                        except ValueError:
                            padding += float(w[4:-1])
                        continue
                       
                    if w == "," or w == ".":
                        intervals[-1] += 1
                        continue
                       
                    intervals.append((len(w)+1+padding)/speed) # We add 1 to account for spaces...
                   
                renpy.show_screen("silly_timers", intervals, "Button_1.ogg")
               
        elif event == "slow_done":
            renpy.hide_screen("silly_timers")

define _last_beeped_text = []
default x = Character("X", callback=beepy_voice)

screen silly_timers(intervals, sfx):
    default play_time = 0.001 # We play the very first sound asap.
   
    for i in intervals:
        timer play_time action Play("sound", sfx)
        $ play_time += i

label start:
    x "M, Meow, Meoooooow, Meooooooooooooooooooooow, {fast}..., {color=#F00}fs{w}mfeofmfo{/color}, didsnfsdnfdisf, nsdfnds nfsdicd."
    x "M, Meow, Meo00000w, Meo00000000000000000000w"

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Text scrolling/ dialogue sounds, per word

#20 Post by xela »

Yeap, that's far better, if there are any "special" cases remaining, they should be added by the users. This can be used to make near perfectly synced mouth movements and/or sounds.
Like what we're doing? Support us at:
Image

DragoonHP
Miko-Class Veteran
Posts: 758
Joined: Tue Jun 22, 2010 12:54 am
Completed: Christmas
IRC Nick: DragoonHP
Location: Zion Island, Solario
Contact:

Re: Text scrolling/ dialogue sounds, per word

#21 Post by DragoonHP »

Found a bug.

Code: Select all

                    if w == "," or w == ".":
                        intervals[-1] += 1/speed # Previously, we always added a second in this case
                        continue
So the final code should be

Code: Select all

init python:
    def check_for_tags(s):
       
        if "{fast}" in s:
            s = s.split("{fast}")
            s = s[-1]
       
        if "{w" in s:
            s = s.replace("{w", " |##")
       
        if "[p" in s:
            s = s.replace("{p", " |##")
       
        s = s.replace("}", "} ")
       
        return s
   
    def beepy_voice(event, interact=True, **kwargs):
        global _last_beeped_text
       
        if not interact:
            return
           
        if event == "show_done":
            # Using _last_raw_what makes the callback compatible with extend character.
            # Fair warning: _last_raw_what is undocumented and subject to change.
            s = _last_raw_what
            speed = float(_preferences.text_cps)
           
            if s and speed:
                import re
               
                intervals = []
                padding = 0
               
                if not _last_beeped_text:
                    if "{fast}" in s or "{w" in s or "{p" in s:
                        s = check_for_tags(s)
                       
                    s = re.sub(r"{.+?} ", "", s) #Instead of capturning "{something}" we had to capture "{something} "
                   
                    # Whenever we encounter a click-to-continue tag, split the string.
                    _last_beeped_text = s.split("|##}")
               
                words = _last_beeped_text.pop(0).split()

                for w in words:
                        
                    if w == "," or w == ".":
                        intervals[-1] += 1/speed
                        continue

                    # If number of seconds is provided, add it to interval.
                    if "|##=" in w:
                        padding += float(w[4:-1])
                        continue
                       
                    intervals.append((len(w)+1+padding)/speed) # We add 1 to account for spaces...
                   
                renpy.show_screen("silly_timers", intervals, "Button_1.ogg")
               
        elif event == "slow_done":
            renpy.hide_screen("silly_timers")

define _last_beeped_text = []
default x = Character("X", callback=beepy_voice)

screen silly_timers(intervals, sfx):
    default play_time = 0.001 # We play the very first sound asap.
   
    for i in intervals:
        timer play_time action Play("sound", sfx)
        $ play_time += i

label start:
    x "M, Meow, Meoooooow, Meooooooooooooooooooooow, {fast}..., {color=#F00}fs{w}mfeofmfo{/color}, didsnfsdnfdisf, nsdfnds nfsdicd."
    x "M, Meow, Meo00000w, Meo00000000000000000000w"

User avatar
Kinmoku
Miko-Class Veteran
Posts: 591
Joined: Mon Aug 11, 2014 9:39 am
Completed: One Night Stand
Projects: VIDEOVERSE
Tumblr: gamesbykinmoku
itch: kinmoku
Location: Germany
Contact:

Re: Text scrolling/ dialogue sounds, per word

#22 Post by Kinmoku »

Wow guys, this is really amazing! I'm going to try and implement it into my game once I finish what I'm working on :)

TamaYoshi
Newbie
Posts: 16
Joined: Sun Jul 17, 2016 12:41 pm
Contact:

Re: Text scrolling/ dialogue sounds, per word

#23 Post by TamaYoshi »

Hello, I bump this thread a bit because I tried this approach as well, and I changed some things.

Code: Select all

if "[p" in s:
            s = s.replace("{p", " |##")

should really be

if "{p" in s:
            s = s.replace("{p", " |##")
A problem I had was that this line yielded None

Code: Select all

speed = float(_preferences.text_cps)
And I had to hard-code the value. I'm not sure why.
At any rate, I coded a variant of the code that beeps for each character, instead of each word. The algorithm is essentially the same, ignoring tags, commas, dots and spaces.

I also extracted the callback in another generic function, to facilitate changing the sfx...

Code: Select all

    def beepy_voice_zelda(event, interact=True, **kwargs):
        beepy_voice_internal( event, interact, "LTTP_Text_Letter.wav")

    def check_for_tags(s):
       
        # {fast} short-circuits the gradual talk, printing it "now"
        # Anything before a {fast} must therefor be removed
        if "{fast}" in s:
            s = s.split("{fast}")
            s = s[-1]
       
        # These will be used for padding (they give a time during which the text will stop)
        if "{w" in s:
            s = s.replace("{w", " |##")
       
        if "{p" in s:
            s = s.replace("{p", " |##")
       
        s = s.replace("}", "} ")
       
        return s
   
    def beepy_voice_internal(event, interact, sfx):
        global _last_beeped_text

        if not interact:
            return
        
        if event == "show_done":
            # Using _last_raw_what makes the callback compatible with extend character.
            # Fair warning: _last_raw_what is undocumented and subject to change.
            s = _last_raw_what
            speed = float(_preferences.text_cps)
            
            sfx = beepy_voice_theSfx
            
            if s and speed:
                import re
               
                intervals = []
                padding = 0
                
                if not _last_beeped_text:
                    if "{fast}" in s or "{w" in s or "{p" in s:
                        s = check_for_tags(s)
                       
                    s = re.sub(r"{.+?} ", "", s) #Instead of capturning "{something}" we had to capture "{something} "
                   
                    # Whenever we encounter a click-to-continue tag, split the string.
                    _last_beeped_text = s.split("|##}")
               
                #words = _last_beeped_text.pop(0).split() # We don't use words anymore!!!
                characters = _last_beeped_text.pop(0) 

                i = 0
                while i < len( characters ):
                    # If number of seconds is provided, add it to interval.
                    if characters[i:].startswith( "|##=" ) :
                        
                        i += 4
                        sizeOfNumber = 0;
                        while characters[i + sizeOfNumber] in "0123456789,." :
                            sizeOfNumber += 1;
                        try:
                            padding += int(characters[i:i + sizeOfNumber])
                        except ValueError:
                            padding += float(characters[i:i + sizeOfNumber])
                            
                        i += sizeOfNumber
                        continue
                        
                    if characters[i] in ",. ":
                        if ( intervals ) : # not empty
                            intervals[-1] += 1/speed
                        else:
                            padding += 1
                        i += 1;
                        continue
                       
                    intervals.append((1+padding)/speed)
                    padding = 0;
                    i += 1;
                renpy.show_screen("silly_timers", intervals, sfx)
                
        elif event == "slow_done":
            renpy.hide_screen("silly_timers")

define _last_beeped_text = []

screen silly_timers(intervals, sfx):
    default play_time = 0.001 # We play the very first sound asap.
   
    for i in intervals:
        timer play_time action Play("sound", sfx)
        $ play_time += i

User avatar
Kinmoku
Miko-Class Veteran
Posts: 591
Joined: Mon Aug 11, 2014 9:39 am
Completed: One Night Stand
Projects: VIDEOVERSE
Tumblr: gamesbykinmoku
itch: kinmoku
Location: Germany
Contact:

Re: Text scrolling/ dialogue sounds, per word

#24 Post by Kinmoku »

DragoonHP wrote:Found a bug.

Code: Select all

                    if w == "," or w == ".":
                        intervals[-1] += 1/speed # Previously, we always added a second in this case
                        continue
So the final code should be

Code: Select all

init python:
    def check_for_tags(s):
       
        if "{fast}" in s:
            s = s.split("{fast}")
            s = s[-1]
       
        if "{w" in s:
            s = s.replace("{w", " |##")
       
        if "[p" in s:
            s = s.replace("{p", " |##")
       
        s = s.replace("}", "} ")
       
        return s
   
    def beepy_voice(event, interact=True, **kwargs):
        global _last_beeped_text
       
        if not interact:
            return
           
        if event == "show_done":
            # Using _last_raw_what makes the callback compatible with extend character.
            # Fair warning: _last_raw_what is undocumented and subject to change.
            s = _last_raw_what
            speed = float(_preferences.text_cps)
           
            if s and speed:
                import re
               
                intervals = []
                padding = 0
               
                if not _last_beeped_text:
                    if "{fast}" in s or "{w" in s or "{p" in s:
                        s = check_for_tags(s)
                       
                    s = re.sub(r"{.+?} ", "", s) #Instead of capturning "{something}" we had to capture "{something} "
                   
                    # Whenever we encounter a click-to-continue tag, split the string.
                    _last_beeped_text = s.split("|##}")
               
                words = _last_beeped_text.pop(0).split()

                for w in words:
                        
                    if w == "," or w == ".":
                        intervals[-1] += 1/speed
                        continue

                    # If number of seconds is provided, add it to interval.
                    if "|##=" in w:
                        padding += float(w[4:-1])
                        continue
                       
                    intervals.append((len(w)+1+padding)/speed) # We add 1 to account for spaces...
                   
                renpy.show_screen("silly_timers", intervals, "Button_1.ogg")
               
        elif event == "slow_done":
            renpy.hide_screen("silly_timers")

define _last_beeped_text = []
default x = Character("X", callback=beepy_voice)

screen silly_timers(intervals, sfx):
    default play_time = 0.001 # We play the very first sound asap.
   
    for i in intervals:
        timer play_time action Play("sound", sfx)
        $ play_time += i

label start:
    x "M, Meow, Meoooooow, Meooooooooooooooooooooow, {fast}..., {color=#F00}fs{w}mfeofmfo{/color}, didsnfsdnfdisf, nsdfnds nfsdicd."
    x "M, Meow, Meo00000w, Meo00000000000000000000w"

I tried putting this in but the sound keeps repeating once the text has finished. Am I missing something? I used this exact code in a new project.

Otherwise, when the text rolls out, it works fantastic! It inspires me to make a typewriter VN :)

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Text scrolling/ dialogue sounds, per word

#25 Post by xela »

Nope, it still works for me... you can improve this a lot by adding sounds of different duration depending on length of the text fragment and you can do a damn near perfect lip-syncing using this method if you can handle UDDs.

You make have overwritten default setting for sound channel in your project or are using a sound file of a long duration. Maybe some other weird thing... but it is still working for me under 6.11.
Like what we're doing? Support us at:
Image

nagoya29
Newbie
Posts: 5
Joined: Sat Sep 07, 2019 11:15 pm
Contact:

Re: Text scrolling/ dialogue sounds, per word

#26 Post by nagoya29 »

TamaYoshi wrote: Fri Sep 02, 2016 8:11 am Hello, I bump this thread a bit because I tried this approach as well, and I changed some things.

Code: Select all

if "[p" in s:
            s = s.replace("{p", " |##")

should really be

if "{p" in s:
            s = s.replace("{p", " |##")
A problem I had was that this line yielded None

Code: Select all

speed = float(_preferences.text_cps)
And I had to hard-code the value. I'm not sure why.
At any rate, I coded a variant of the code that beeps for each character, instead of each word. The algorithm is essentially the same, ignoring tags, commas, dots and spaces.

I also extracted the callback in another generic function, to facilitate changing the sfx...

Code: Select all

    def beepy_voice_zelda(event, interact=True, **kwargs):
        beepy_voice_internal( event, interact, "LTTP_Text_Letter.wav")

    def check_for_tags(s):
       
        # {fast} short-circuits the gradual talk, printing it "now"
        # Anything before a {fast} must therefor be removed
        if "{fast}" in s:
            s = s.split("{fast}")
            s = s[-1]
       
        # These will be used for padding (they give a time during which the text will stop)
        if "{w" in s:
            s = s.replace("{w", " |##")
       
        if "{p" in s:
            s = s.replace("{p", " |##")
       
        s = s.replace("}", "} ")
       
        return s
   
    def beepy_voice_internal(event, interact, sfx):
        global _last_beeped_text

        if not interact:
            return
        
        if event == "show_done":
            # Using _last_raw_what makes the callback compatible with extend character.
            # Fair warning: _last_raw_what is undocumented and subject to change.
            s = _last_raw_what
            speed = float(_preferences.text_cps)
            
            sfx = beepy_voice_theSfx
            
            if s and speed:
                import re
               
                intervals = []
                padding = 0
                
                if not _last_beeped_text:
                    if "{fast}" in s or "{w" in s or "{p" in s:
                        s = check_for_tags(s)
                       
                    s = re.sub(r"{.+?} ", "", s) #Instead of capturning "{something}" we had to capture "{something} "
                   
                    # Whenever we encounter a click-to-continue tag, split the string.
                    _last_beeped_text = s.split("|##}")
               
                #words = _last_beeped_text.pop(0).split() # We don't use words anymore!!!
                characters = _last_beeped_text.pop(0) 

                i = 0
                while i < len( characters ):
                    # If number of seconds is provided, add it to interval.
                    if characters[i:].startswith( "|##=" ) :
                        
                        i += 4
                        sizeOfNumber = 0;
                        while characters[i + sizeOfNumber] in "0123456789,." :
                            sizeOfNumber += 1;
                        try:
                            padding += int(characters[i:i + sizeOfNumber])
                        except ValueError:
                            padding += float(characters[i:i + sizeOfNumber])
                            
                        i += sizeOfNumber
                        continue
                        
                    if characters[i] in ",. ":
                        if ( intervals ) : # not empty
                            intervals[-1] += 1/speed
                        else:
                            padding += 1
                        i += 1;
                        continue
                       
                    intervals.append((1+padding)/speed)
                    padding = 0;
                    i += 1;
                renpy.show_screen("silly_timers", intervals, sfx)
                
        elif event == "slow_done":
            renpy.hide_screen("silly_timers")

define _last_beeped_text = []

screen silly_timers(intervals, sfx):
    default play_time = 0.001 # We play the very first sound asap.
   
    for i in intervals:
        timer play_time action Play("sound", sfx)
        $ play_time += i

hello I came across this and realised it was exactly what i have been looking for! So i tried it but an error pops up saying sfx = beepy_voice_theSfx is not defined? Am doing something wrong? I did replace the wav with my own ogg, is there anything else I have to replace? I'm sorry if this is a really noob question lol im still a newbie, thanks alot!

Snek
Newbie
Posts: 4
Joined: Wed Apr 22, 2020 6:38 am
Contact:

Re: Text scrolling/ dialogue sounds, per word

#27 Post by Snek »

Sorry for necro, but I've found this code and sadly, on 7.3.5, it doesn't seem to work well..

On slowest speed, it only plays the first ever character of each word, and is completely out of sync. I have standard CPS set to 20 in options.rpy, and text speed is set to lowest possible. Can someone help? I am not sure what I am doing wrong :c

This is my script.rpy. Sorry, I am very new to all this.

Code: Select all

# The script of the game goes in this file.
init python:
    def check_for_tags(s):
       
        if "{fast}" in s:
            s = s.split("{fast}")
            s = s[-1]
       
        if "{w" in s:
            s = s.replace("{w", " |##")
       
        if "[p" in s:
            s = s.replace("{p", " |##")
       
        s = s.replace("}", "} ")
       
        return s
   
    def beepy_voice(event, interact=True, **kwargs):
        global _last_beeped_text
       
        if not interact:
            return
           
        if event == "show_done":
            # Using _last_raw_what makes the callback compatible with extend character.
            # Fair warning: _last_raw_what is undocumented and subject to change.
            s = _last_raw_what
            speed = float(_preferences.text_cps)
           
            if s and speed:
                import re
               
                intervals = []
                padding = 0
               
                if not _last_beeped_text:
                    if "{fast}" in s or "{w" in s or "{p" in s:
                        s = check_for_tags(s)
                       
                    s = re.sub(r"{.+?} ", "", s) #Instead of capturning "{something}" we had to capture "{something} "
                   
                    # Whenever we encounter a click-to-continue tag, split the string.
                    _last_beeped_text = s.split("|##}")
               
                words = _last_beeped_text.pop(0).split()

                for w in words:
                    # If number of seconds is provided, add it to interval.
                    if "|##=" in w:
                        try:
                            padding += int(w[4:-1])
                        except ValueError:
                            padding += float(w[4:-1])
                        continue
                       
                    if w == "," or w == ".":
                        intervals[-1] += 1
                        continue
                       
                    intervals.append((len(w)+1+padding)/speed) # We add 1 to account for spaces...
                   
                renpy.show_screen("silly_timers", intervals, "audio/bleep_male.wav")
               
        elif event == "slow_done":
            renpy.hide_screen("silly_timers")

define _last_beeped_text = []
default x = Character("X", callback=beepy_voice)

screen silly_timers(intervals, sfx):
    default play_time = 0.001 # We play the very first sound asap.
   
    for i in intervals:
        timer play_time action Play("sound", sfx)
        $ play_time += i



# Declare characters used by this game. The color argument colorizes the
# name of the character.
# The game starts here.

define flash = Fade(0.1, 0.0, 0.1, color="#FFFFFF")
image MH = "MarcusH.jpg"
image MS = "MarcusS.jpg"
image kitchen = "kitchen.JPG"

define w = Character('Wolf', color="#FFFFFF", outlines=[(1, "#39637F", 0, 0)], who_size = 30, what_color="#FFFFFF", callback=beepy_voice)
define m = Character('Marcus', color="#FFFFFF", outlines=[(1, "#39637F", 0, 0)], what_color="#FFb448", who_size = 30, callback=beepy_voice)

label start:


    scene kitchen

    # This shows a character sprite. A placeholder is used, but you can
    # replace it by adding a file named "eileen happy.png" to the images
    # directory.

    show MH

    # These display lines of dialogue.


    m "How are you,{w=0.15} Wolf?"
    # speech blip here

    w "Yeah,{w=0.15} I am fine.{w=0.2} I just got done doing some stuff."

    m "ohhh like what?"

    w "Playing a game."
    show MS with flash
    with Shake((0, 0, 0, 0), 1.0, dist=85) 
    m "YOU WHATTT!!!"

    # This ends the game.

    return

User avatar
gas
Miko-Class Veteran
Posts: 842
Joined: Mon Jan 26, 2009 7:21 pm
Contact:

Re: Text scrolling/ dialogue sounds, per word

#28 Post by gas »

Snek wrote: Sat Feb 13, 2021 11:13 pm Sorry for necro, but I've found this code and sadly, on 7.3.5, it doesn't seem to work well.
You did nothing wrong, but since 2016 stuff changed a lot - now text is tied to voicing and auto-voicing tags and not speaking you can now create your own tags... This code will never work anymore.
If you want to debate on a reply I gave to your posts, please QUOTE ME or i'll not be notified about. << now red so probably you'll see it.

10 ? "RENPY"
20 GOTO 10

RUN

Okapi
Newbie
Posts: 7
Joined: Wed Feb 17, 2021 11:02 am
Contact:

Re: Text scrolling/ dialogue sounds, per word

#29 Post by Okapi »

gas wrote: Tue Feb 16, 2021 2:43 am
Snek wrote: Sat Feb 13, 2021 11:13 pm Sorry for necro, but I've found this code and sadly, on 7.3.5, it doesn't seem to work well.
You did nothing wrong, but since 2016 stuff changed a lot - now text is tied to voicing and auto-voicing tags and not speaking you can now create your own tags... This code will never work anymore.
The code actually still works for me on 7.3.5 and on 7.4.2. However, it seems to be causing noticable performance issues (Heavy FPS drops). RenpyTom said, that timers, that play audio files multiple times per second isn't really a supported case. Does anybody have an idea how to fix the code accordingly?

Edit: While the code strains the peroformance a little bit, it wasn't as bad as I thought. It doesn't cause that much performance issues after all
Last edited by Okapi on Thu Mar 25, 2021 4:44 pm, edited 1 time in total.

Snek
Newbie
Posts: 4
Joined: Wed Apr 22, 2020 6:38 am
Contact:

Re: Text scrolling/ dialogue sounds, per word

#30 Post by Snek »

gas wrote: Tue Feb 16, 2021 2:43 am
Snek wrote: Sat Feb 13, 2021 11:13 pm Sorry for necro, but I've found this code and sadly, on 7.3.5, it doesn't seem to work well.
You did nothing wrong, but since 2016 stuff changed a lot - now text is tied to voicing and auto-voicing tags and not speaking you can now create your own tags... This code will never work anymore.
The problem is that it's desynchronising when using per-character bleeping. I wonder, is there a way to synchronise it?

Post Reply

Who is online

Users browsing this forum: Google [Bot], Lucyper