Dynamic font select (language translation)

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.
Post Reply
Message
Author
Exiscoming
Regular
Posts: 132
Joined: Tue Apr 29, 2014 5:37 pm
Contact:

Dynamic font select (language translation)

#1 Post by Exiscoming »

For my next game, I've been hoping to implement a language that you can learn while playing the game. Right now, this is how I do it.
For the foreign language, I use a new font called Glagolitsa. Which looks like this:
Image
I define a bunch of variables with the words the player can learn:

Code: Select all

default this = "{font=fonts/gla.ttf}this{/font}"
default is = "{font=fonts/gla.ttf}is{/font}"
default a = "{font=fonts/gla.ttf}a{/font}"
default test = "{font=fonts/gla.ttf}test{/font}"
And then, when the player encounters the foreign language ingame, I do this:

Code: Select all

"Bob" "[this] [is] [a] [test]."	# Written in full unreadable foreign
### Learn words ###
$ this = "this"
$ is = "is"
$ a = "a"
$ test = "test"
##################
"Bob" "[this] [is] [a] [test]."	# Now completely read-able for player.
The question is... Is there an easier / more efficient way to do this?

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Dynamic font select (language translation)

#2 Post by hell_oh_world »

How about using a custom text tag?

Code: Select all

default lang = 0 # 0 means normal, 1 means foreign

init python:
    def lang_tag(tag, argument, contents):
        if store.lang == 1:
            font = "fonts/gla.ttf"
            start = [(renpy.TEXT_TAG, u"font={}".format(font))]
            end = [(renpy.TEXT_TAG, u"/font")]
            return  start + contents + end

        return contents

    config.custom_text_tags["lang"] = lang_tag

label start:
  call some_label
  "Changing language now..."
  $ lang = 1
  call some_label
  
label some_label:
  "{lang}This is a text.{/lang}"
  "{lang}And another text...{/lang}"
  return
I think this also works too without all this fuss...

Code: Select all

default font = "fonts/your_normal_font.ttf"

label start:
  call some_label
  "Changing language now..."
  $ font = "fonts/gla.ttf"
  call some_label
  "Reverting it backnow..."
  $ font = "fonts/your_normal_font.ttf"
  call some_label
  
label some_label:
  "{font=[font]}This is a text.{/font}"
  "{font=[font]}And another text...{/font}"
  return

Exiscoming
Regular
Posts: 132
Joined: Tue Apr 29, 2014 5:37 pm
Contact:

Re: Dynamic font select (language translation)

#3 Post by Exiscoming »

Hey there, thanks for the suggestion!
So the problem with changing the font would be that the player cannot read what is being said.
The idea is that the player can learn words while playing the game, so when reading something, it would be

Code: Select all

default hello = "*****"
label some_label:
	$ hello = "hello"		# Learning the word 'hello' here.
	"Alien" "****** **** [hello] ****"   # Using * for the words you haven't learned yet.
I'm just wondering if there'd be an easier way than turning every word into a variable.
"[Hello] [this] [is] [a] [sentence]."

strayerror
Regular
Posts: 159
Joined: Fri Jan 04, 2019 3:44 pm
Contact:

Re: Dynamic font select (language translation)

#4 Post by strayerror »

Here is an example if you want it to affect all dialogue in your game, it filters all the text, splits it to words and obfuscates/changes the font of the unknown words. In this example it's changing the text to red, but you can easily alter the tags being applied, just take care to note the double {{ and }} nescessary due to using the format method.

Words can be "learnt" by adding them to the global learnt set.

If you only want this logic applied to certain lines or areas of text then this approach could be married to custom text tag concept suggested by hell_oh_world, however that would require a more complex function in order to correctly deal with the already parsed text tags. Very doable, but I wouldn't say trivial. A middle ground might be limiting it to the speech of certain characters, which I believe should be possible, but can't recall off the top of my head how to do so.

Hope this helps! :)

Code: Select all

default learnt = set()

init python hide:
    import re

    word = re.compile(r'(\w+)')
    unknown = '{{color=f00}}{}{{/color}}'

    def say_menu_text_filter(text):
        return ''.join(t if t.lower() in learnt else unknown.format(t)
                       for t in word.split(text))

    config.say_menu_text_filter = say_menu_text_filter

label start:
    scene
    'This is the first line of the test.'
    $ learnt.update(('this', 'test'))
    'This is the second line of the test.'
    $ learnt.update(('of', 'the'))
    'This is the third line of the test.'
    $ learnt.add('is')
    'This is the fourth line of the test.'
    $ learnt.add('line')
    'This is the fifth line of the test.'
    return
n.b. This will mark any non-word characters as "unknown", but it should be easy enough to resolve that if it's a problem.

Exiscoming
Regular
Posts: 132
Joined: Tue Apr 29, 2014 5:37 pm
Contact:

Re: Dynamic font select (language translation)

#5 Post by Exiscoming »

Thank you! I'm going to try this out first thing in the morning! :D

Exiscoming
Regular
Posts: 132
Joined: Tue Apr 29, 2014 5:37 pm
Contact:

Re: Dynamic font select (language translation)

#6 Post by Exiscoming »

All right, I think this is above my level of coding expertise. Thanks for the suggestions guys, but I think I might re-work this part of the game to make it less complex.

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Dynamic font select (language translation)

#7 Post by hell_oh_world »

I actually reworked my code a bit before based on your reply...
Exiscoming wrote: Fri Aug 20, 2021 10:39 am Hey there, thanks for the suggestion!
So the problem with changing the font would be that the player cannot read what is being said.
The idea is that the player can learn words while playing the game, so when reading something, it would be

Code: Select all

default hello = "*****"
label some_label:
	$ hello = "hello"		# Learning the word 'hello' here.
	"Alien" "****** **** [hello] ****"   # Using * for the words you haven't learned yet.
I'm just wondering if there'd be an easier way than turning every word into a variable.
"[Hello] [this] [is] [a] [sentence]."
But I didn't bother to post it since I already saw strayerror's answer.
Here it is, you can try to look if this suits your need.

Code: Select all

default learned_phrases = set()
define unlearned_phrase_font = "fonts/gla.ttf"

init python:
    def cover(lst, index, left, right=None):
        li, ri = index, index + 1
        lst.insert(ri, right or left)
        lst.insert(li, left)

    def learn_tag(tag, argument, contents):
        contents = list(contents)
        font = store.unlearned_phrase_font
        start = (renpy.TEXT_TAG, u"font={}".format(font))
        end = (renpy.TEXT_TAG, u"/font")
        
        i = 0
        while i < len(contents):
            t, v = contents[i]
            if t == renpy.TEXT_TEXT:
                phrase = v
                if phrase not in store.learned_phrases:
                    cover(contents, i, start, end)
                    i += 2
                    
            i += 1

        return contents

    config.custom_text_tags["learn"] = learn_tag

label start:
  call some_label
  "Learning the word 'Hello'..."
  $ learned_phrases.add("Hello")
  call some_label
  "Learning the word 'World'..."
  $ learned_phrases.add("World")
  call some_label
  
label some_label:
  "{learn}Hello{/learn} {learn}World{/learn}"
  return
Sidenote:
Just change config.custom_text_tags[x] (where x is the preferred tag name) to whatever name you're comfortable with, then you can use that name as the tag.

Exiscoming
Regular
Posts: 132
Joined: Tue Apr 29, 2014 5:37 pm
Contact:

Re: Dynamic font select (language translation)

#8 Post by Exiscoming »

Oh I'm glad I checked back here! Thank you for the updated code. It works flawlessly. I'll be using this in my game. Thank you for taking the time to help me out. Both of you.

Post Reply

Who is online

Users browsing this forum: No registered users