Ren'py MC Name script

CloudX

Member
Oct 14, 2017
235
85
So I was doing this
$ y = renpy.input ("Your Name?")
if y == "":
"Enter a name!"

but after that the game continues without a name!
what do I have to do that ppl get sent back to the
$ y = renpy.input ("Your Name?")
command without it doing that even if someone types a name ? :)
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,585
2,229
The most common mistake, is to use variables like y as both the Character() object and the character name variable.

The way dialogue normally works in RenPy games is that there is a screen called screen say():. RenPy does a lot of shit in the background - but the heart of it is that if you create a character object and a line of text dialogue linked to that character... RenPy will show it in the say window in the way you'll have already see dozens of games already do it.... The character name is displayed above and the to left... and the actual dialogue is shown across the bottom below the name.

At the very simplest level, that would looks like this:

Python:
define e = Character("Eileen")

label start:

    "*** START ***"

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."

   "*** THE END ***"

   return

The "Start" and the "THE END" lines of dialogue are "spoken" by the system (actually a predefined character called "narrator" that everyone takes for granted as he/she has a blank name).

And "Hello [...]" is spoken by the Character() named "Eileen".

As an added bonus, I also included [e]... which is RenPy for "Replace the bit within the square brackets by the value of the variable named there. In this case, it swaps "[e]" for "Eileen".

This is the point where most devs now want the player to be able to rename their main character.
The answer is to have a variable to store the new name, and a way of putting that variable into the Character object.
With that in place, we only need a bit of extra code to ask the player to type in the new name.

That will end up looking something like:

Python:
define e = Character("Eileen")
define mc = Character("[mc_name]")

default mc_name = "Unnamed"

label start:

    "*** START ***"

    $ mc_name = renpy.input("What is your name? {i}(Press ENTER for 'Colin'){/i}")
    $ mc_name = mc_name.strip() or "Colin"

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."

    mc "Hello [e], my name is [mc]... and I'm going to enjoy seeing that."

   "*** THE END ***"

   return

In this case, by making creating the Character() mc using the text "[mc_name]". It basically causes RenPy to put the value of that variable in that place.

Until the player picks a name, the default name will be "Unnamed" (it's an obvious eyecatcher if you screw up and use it without the player entering a "real" name).

Finally, there's the renpy.input() command. Which replaces "Unnamed" with whatever the player types in.
The line after that is just to make sure the player actually typed something. If they entered nothing, then it uses "Colin" instead.

Some people would write it as :

Python:
    $ mc_name = renpy.input("What is your name? {i}(Press ENTER for 'Colin'){/i}")
    $ mc_name = mc_name.strip()
    if mc_name == "":
        $ mc_name = "Colin"

Which does exactly the same thing... and is somewhat easier to follow when you are just starting out.
Except... it's the sort of two line of code you just copy/paste from somewhere else anyway, rather than writing out from scratch every time... so I'd prefer to copy 2 lines of code rather than 4 lines of code. Especially when they do exactly the same thing and I at least understand both solutions.


The BAD way...

As I said right at the top... the most common mistake is not to create a separate variable for the character name.

I see this sort of code all the time:

Python:
define e = Character("Eileen")
define mc = Character("Colin")

label start:

    "*** START ***"

    $ mc = renpy.input("What is your name? {i}(Press ENTER for 'Colin'){/i}")
    $ mc = mc.strip()
    if mc == "":
        $ mc= "Colin"

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."

    mc "Hello [e], my name is [mc]... and I'm going to enjoy seeing that."

   "*** THE END ***"

   return

And what's worse... it sort of works.
But as soon as the code executes $ mc = mc.strip(), the original mc definition (a Character() object) is thrown away and replaced with a simple text string called mc.

RenPy is flexible enough to allow this to happen, but all the formatting and customization that might have been included in the Character() definition is lost.
People normally finally notice is when they change the color of character's name... but then can't understand why the color they assigned to the MC isn't being shown... and instead, it's just shown using the default blue text color.

TL;DR ... keep the Character() and the character name separate.


In a perfect world...

I tend to want to make use of all that Character() customization. Specifically, I like it when RenPy automatically puts double quotes around spoken text and parenthesis around thoughts. I also like non-character text (narration) to appear in yellow instead of white. Finally, I also like thoughts to be shown in italics.

I do this by creating two Character() definitions for any character that will both "speak" and "think" and call the "thinking" character {name}_t. Then use parameters what_prefix and what_suffix to add those double quotes or brackets to the dialogue normally displayed.
Because I'm actually using string data that include double quotes, I instead use single quotes for strings.

I'd end up with something like this:
Python:
define narrator = Character('', what_color='#FFFF66')

define mc = Character('[mc_name]', color='#FFFFFF', what_prefix='"', what_suffix='"')
define mc_t = Character('[mc_name]', color='#FFFFFF', what_prefix='{i}(', what_suffix='){/i}', what_color='#999999')

define e = Character(_("Emily"), color="#04B486", what_prefix='"', what_suffix='"')
define k = Character(_("Karen"), color="#04B486", what_prefix='"', what_suffix='"')
define c = Character(_("Claire"), color="#04B486", what_prefix='"', what_suffix='"')

default mc_name = _("Unnamed")

If the MC is talking, I'd use mc "talking."
If the MC is thinking, I'd use mc_t "thinking."

The use of _( ) might be new to you too. It's just a way of telling RenPy "Include this in translations files too". Makes it easier for those modders who like to offer foreign language translation of popular games. Most of the text within games is automatically flagged for translation - but some parts of the code need to be told explicitly using _().

... which is way more than you asked for... but should give you a much clearer insight as to how everything holds together.
 
Last edited:

CloudX

Member
Oct 14, 2017
235
85
The most common mistake, is to use variables like y as both the Character() object and the character name variable.

The way dialogue normally works in RenPy games is that there is a screen called screen say():. RenPy does a lot of shit in the background - but the heart of it is that if you create a character object and a line of text dialogue linked to that character... RenPy will show it in the say window in the way you'll have already see dozens of games already do it.... The character name is displayed above and the to left... and the actual dialogue is shown across the bottom below the name.

At the very simplest level, that would looks like this:

Python:
define e = Character("Eileen")

label start:

    "*** START ***"

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."

   "*** THE END ***"

   return

The "Start" and the "THE END" lines of dialogue are "spoken" by the system (actually a predefined character called "narrator" that everyone takes for granted as he/she has a blank name).

And "Hello [...]" is spoken by the Character() named "Eileen".

As an added bonus, I also included [e]... which is RenPy for "Replace the bit within the square brackets by the value of the variable named there. In this case, it swaps "[e]" for "Eileen".

This is the point where most devs now want the player to be able to rename their main character.
The answer is to have a variable to store the new name, and a way of putting that variable into the Character object.
With that in place, we only need a bit of extra code to ask the player to type in the new name.

That will end up looking something like:

Python:
define e = Character("Eileen")
define mc = Character("[mc_name]")

default mc_name = "Unnamed"

label start:

    "*** START ***"

    $ mc_name = renpy.input("What is your name? {i}(Press ENTER for 'Colin'){/i}")
    $ mc_name = mc_name.strip() or "Colin"

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."

    mc "Hello [e], my name is [mc]... and I'm going to enjoy seeing that."

   "*** THE END ***"

   return

In this case, by making creating the Character() mc using the text "[mc_name]". It basically causes RenPy to put the value of that variable in that place.

Until the player picks a name, the default name will be "Unnamed" (it's an obvious eyecatcher if you screw up and use it without the player entering a "real" name).

Finally, there's the renpy.input() command. Which replaces "Unnamed" with whatever the player types in.
The line after that is just to make sure the player actually typed something. If they entered nothing, then it uses "Colin" instead.

Some people would write it as :

Python:
    $ mc_name = renpy.input("What is your name? {i}(Press ENTER for 'Colin'){/i}")
    $ mc_name = mc_name.strip()
    if mc_name == "":
        $ mc_name = "Colin"

Which does exactly the same thing... and is somewhat easier to follow when you are just starting out.
Except... it's the sort of two line of code you just copy/paste from somewhere else anyway, rather than writing out from scratch every time... so I'd prefer to copy 2 lines of code rather than 4 lines of code. Especially when they do exactly the same thing and I at least understand both solutions.


The BAD way...

As I said right at the top... the most common mistake is not to create a separate variable for the character name.

I see this sort of code all the time:

Python:
define e = Character("Eileen")
define mc = Character("Colin")

label start:

    "*** START ***"

    $ mc = renpy.input("What is your name? {i}(Press ENTER for 'Colin'){/i}")
    $ mc = mc.strip()
    if mc == "":
        $ mc= "Colin"

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."

    mc "Hello [e], my name is [mc]... and I'm going to enjoy seeing that."

   "*** THE END ***"

   return

And what's worse... it sort of works.
But as soon as the code executes $ mc = mc.strip(), the original mc definition (a Character() object) is thrown away and replaced with a simple text string called mc.

RenPy is flexible enough to allow this to happen, but all the formatting and customization that might have been included in the Character() definition is lost.
People normally finally notice is when they change the color of character's name... but then can't understand why the color they assigned to the MC isn't being shown... and instead, it's just shown using the default blue text color.

TL;DR ... keep the Character() and the character name separate.


In a perfect world...

I tend to want to make use of all that Character() customization. Specifically, I like it when RenPy automatically puts double quotes around spoken text and parenthesis around thoughts. I also like non-character text (narration) to appear in yellow instead of white. Finally, I also like thoughts to be shown in italics.

I do this by creating two Character() definitions for any character that will both "speak" and "think" and call the "thinking" character {name}_t. Then use parameters what_prefix and what_suffix to add those double quotes or brackets to the dialogue normally displayed.
Because I'm actually using string data that include double quotes, I instead use single quotes for strings.

I'd end up with something like this:
Python:
define narrator = Character('', what_color='#FFFF66')

define mc = Character('[mc_name]', color='#FFFFFF', what_prefix='"', what_suffix='"')
define mc_t = Character('[mc_name]', color='#FFFFFF', what_prefix='{i}(', what_suffix='){/i}', what_color='#999999')

define e = Character(_("Emily"), color="#04B486", what_prefix='"', what_suffix='"')
define k = Character(_("Karen"), color="#04B486", what_prefix='"', what_suffix='"')
define c = Character(_("Claire"), color="#04B486", what_prefix='"', what_suffix='"')

default mc_name = _("Unnamed")

If the MC is talking, I'd use mc "talking."
If the MC is thinking, I'd use mc_t "thinking."

The use of _( ) might be new to you too. It's just a way of telling RenPy "Include this in translations files too". Makes it easier for those modders who like to offer foreign language translation of popular games. Most of the text within games is automatically flagged for translation - but some parts of the code need to be told explicitly using _().

... which is way more than you asked for... but should give you a much clearer insight as to how everything holds together.
omg thank you so much!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,391
15,307
That will end up looking something like:

Python:
define e = Character("Eileen")
define mc = Character("[mc_name]")

default mc_name = "Unnamed"

label start:

    "*** START ***"

    $ mc_name = renpy.input("What is your name? {i}(Press ENTER for 'Colin'){/i}")
    $ mc_name = mc_name.strip() or "Colin"

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."

    mc "Hello [e], my name is [mc]... and I'm going to enjoy seeing that."

   "*** THE END ***"

   return

Alternative way, that fit more his initial approach:
Python:
define mc = Character("[mc_name]")

default mc_name = ""

label start:

    while mc_name == "":
        $ mc_name = renpy.input("What is your name?")
        if mc_name == "":
            "You need to enter a name."

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."
    [...]
 
  • Like
Reactions: CloudX

CloudX

Member
Oct 14, 2017
235
85
Alternative way, that fit more his initial approach:
Python:
define mc = Character("[mc_name]")

default mc_name = ""

label start:

    while mc_name == "":
        $ mc_name = renpy.input("What is your name?")
        if mc_name == "":
            "You need to enter a name."

    e "Hello and welcome to my game, my name is [e] - and I'll be taking my clothes off later."
    [...]
Could you help me again maybe?
I was having trouble with showing a cutscene and idk what to do!

$ renpy.movie_cutscene("Lizzie Animation 1 (1).webm")

I was doing that step by step from some forums and videos but it does not find the "Lizzie Animation 1 (1).webm" file
 

MissFortune

I Was Once, Possibly, Maybe, Perhaps… A Harem King
Respected User
Game Developer
Aug 17, 2019
4,934
8,054
Could you help me again maybe?
I was having trouble with showing a cutscene and idk what to do!

$ renpy.movie_cutscene("Lizzie Animation 1 (1).webm")

I was doing that step by step from some forums and videos but it does not find the "Lizzie Animation 1 (1).webm" file
You might have an easier time with this (not the cleanest, I'm sure, but it does the trick for a beginner, which it sounds like you are):

Code:
image lizani = Movie(play="images/lizani1.webm", loop=True or False)
This is probably easiest to put at the top of the page you're coding on. Keeps it organized and you know where to find it. Choose either true or false for loop (do you want the animation to loop or not? That's all it does). Then when you get to the point in the script/game you want to insert the animation with, put something like this:

Code:
scene lizani with dissolve
So, now you can more or less use it as you would a static render in Ren'py. Dissolve, of course, is only for example here. I'd think other's would work much of the same. Dissolve is just what I use. I'm sure anne O'nymous has something better, though.
 

CloudX

Member
Oct 14, 2017
235
85
You might have an easier time with this (not the cleanest, I'm sure, but it does the trick for a beginner, which it sounds like you are):

Code:
image lizani = Movie(play="images/lizani1.webm", loop=True or False)
This is probably easiest to put at the top of the page you're coding on. Keeps it organized and you know where to find it. Choose either true or false for loop (do you want the animation to loop or not? That's all it does). Then when you get to the point in the script/game you want to insert the animation with, put something like this:

Code:
scene lizani with dissolve
So, now you can more or less use it as you would a static render in Ren'py. Dissolve, of course, is only for example here. I'd think other's would work much of the same. Dissolve is just what I use. I'm sure anne O'nymous has something better, though.
Don't really get it tbh.
I don't get why you are able to change the name of the file it's called Lizzie Animation 1 (1).webm and not images/lizani1.webm so do u want me to change the file name to that? :)
 

CloudX

Member
Oct 14, 2017
235
85
nvm i found the problem! i was making folder to sort the animation and pictures better but the animation NEED to be in the image folder with no sub folder apparently? But idk why bc for images it works just fine!
 

MissFortune

I Was Once, Possibly, Maybe, Perhaps… A Harem King
Respected User
Game Developer
Aug 17, 2019
4,934
8,054
Don't really get it tbh.
I don't get why you are able to change the name of the file it's called Lizzie Animation 1 (1).webm and not images/lizani1.webm so do u want me to change the file name to that? :)
At the end of the day, it's all your choice on how you want to name things. I just did it that way because it was quicker. You could just as easily do it the way you had it.

Code:
image lizanimation1 = Movie(play="images/Lizzie Animation 1 (1).webm", loop=True or False)
Then just drop the "lizanimation1" after the 'image' into the script like above.

Code:
scene lizanimation1 with dissolve
Edit:

nvm i found the problem! i was making folder to sort the animation and pictures better but the animation NEED to be in the image folder with no sub folder apparently? But idk why bc for images it works just fine!
If you're using the above code, you'll want to pay attention to path you have listed. "images/Lizzie Animation 1 (1).webm". Ren'py is looking in the images folder for the animation file. If you want to separate folders for animations, you could create another folder inside your images folder and call it 'anis' or 'animations', your choice.

Which would looking something like this: images/animations/Lizzie Animation 1 (1).webm". That way, Ren'py knows to look into the images folder for your animations folder, and then look for the said animation.
 
  • Like
Reactions: CloudX

CloudX

Member
Oct 14, 2017
235
85
You might have an easier time with this (not the cleanest, I'm sure, but it does the trick for a beginner, which it sounds like you are):

Code:
image lizani = Movie(play="images/lizani1.webm", loop=True or False)
This is probably easiest to put at the top of the page you're coding on. Keeps it organized and you know where to find it. Choose either true or false for loop (do you want the animation to loop or not? That's all it does). Then when you get to the point in the script/game you want to insert the animation with, put something like this:

Code:
scene lizani with dissolve
So, now you can more or less use it as you would a static render in Ren'py. Dissolve, of course, is only for example here. I'd think other's would work much of the same. Dissolve is just what I use. I'm sure anne O'nymous has something better, though.
Is there a way to use $ renpy.movie_cutscene("LizAni 1 (1).webm") this command (it's working now) and loop it?
 

CloudX

Member
Oct 14, 2017
235
85
At the end of the day, it's all your choice on how you want to name things. I just did it that way because it was quicker. You could just as easily do it the way you had it.

Code:
image lizanimation1 = Movie(play="images/Lizzie Animation 1 (1).webm", loop=True or False)
Then just drop the "lizanimation1" after the 'image' into the script like above.

Code:
scene lizanimation1 with dissolve
Edit:



If you're using the above code, you'll want to pay attention to path you have listed. "images/Lizzie Animation 1 (1).webm". Ren'py is looking in the images folder for the animation file. If you want to separate folders for animations, you could create another folder inside your images folder and call it 'anis' or 'animations', your choice.

Which would looking something like this: images/animations/Lizzie Animation 1 (1).webm". That way, Ren'py knows to look into the images folder for your animations folder, and then look for the said animation.
also THANK U SM for helping me!
 

MissFortune

I Was Once, Possibly, Maybe, Perhaps… A Harem King
Respected User
Game Developer
Aug 17, 2019
4,934
8,054
Is there a way to use $ renpy.movie_cutscene("LizAni 1 (1).webm") this command (it's working now) and loop it?
Can't say it'll work as I don't use it personally, and from what I can tell is likely a few years old, but got this from the Ren'py forums.

Code:
$ renpy.movie_cutscene("filename.webm", delay=insert value, loops=insert # of loops/-1 for indefinite looping)
 
  • Like
Reactions: CloudX

CloudX

Member
Oct 14, 2017
235
85
Can't say it'll work as I don't use it personally, and from what I can tell is likely a few years old, but got this from the Ren'py forums.

Code:
$ renpy.movie_cutscene("filename.webm", delay=insert value, loops=insert # of loops/-1 for indefinite looping)
alright thanks <3
 

LightmanP

Well-Known Member
Modder
Game Developer
Oct 5, 2020
1,673
15,527
All of this stuff is clearly described in the related , I suggest you get acquainted with it and the overall documentation.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,391
15,307
[...] but the animation NEED to be in the image folder with no sub folder apparently? But idk why bc for images it works just fine!
Because you don't use the images and the animations in the same way.
Image are referred to by their alias in Ren'py ; an alias that, by default, correspond to the name of the file. But animations are referred to by using their location relatively to the "game" folder.
 
  • Like
Reactions: CloudX