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.