If a variable will change while the game is running... use default
.
If a variable will never change while the game is running... use define
.
That's interesting. Any more small things like this? I have yet to fully deepdive in the Renoy documentation but that's coming on real soon. Any other smaller areas in regards to Renpy where going over it with a fine tooth comb will save problems later?
Obviously, yes. But I already included the "repeat offenders" so to speak. The stuff I see on a semi-regular basis.
One other easy traps that tends to crop up are those developers who want to include a "points" based system, without really knowing why. They feel they should be tracking things like "love" or "hate" or "corruption", without thinking through the consequences to their game. For example, a game tracking "love points" for the main love interest... by a particular point within the game, the player could have accumulated 8 points. So our fictional newbie developer codes something like
if tessa_love_points >= 7:
. At first glance it make perfect sense... if our player is effectively on the "love route", then events should be gated only for those players who at committed to that route. Except, you've now made it pretty much mandatory for the player to pick almost every "love" choice up to that point. Moreover, you've probably just made it essential that someone write a walkthrough for your game, since getting anything less than 7 means hardly any content. Balancing a points based system is hard, especially in a more linear game. They can work in open world games, but then it largely becomes about the grind.
Edit: Ah, just noticed it's already covered within the thread. Limited time today, so spent it writing rather than reading.
Another pitfall is the "pick out clothing" trope or similar. Where the MC and the LI inevitably end up in the same clothing shop we've seen literally hundreds of times before to pick out some clothing... for... let's say a party. The player gets to pick between the black sexy dress, the red slutty dress and the blue conservative dress. Again, it makes perfect sense - you give the player agency to pick an outfit they most want to see the LI wearing, and in so doing immerse themselves more into your game. Except... now for almost every scene at party is going to need to be rendered THREE times!!! Once for the red dress, one for the black and one for the blue. Three times the work for very little payoff. Giving the player choices (even meaningless ones) is good... player choices which double or triple your rendering work is bad.
Finally, a bit of code...
Python:
default persistent.saved_mc_name = "Trevor"
default mc_name = "Unknown"
define narrator = Character(None, what_color='#FFFF66')
define mc = Character("[mc_name]", what_prefix="\"", what_suffix="\"")
define mc_t = Character("[mc_name]", what_prefix="(", what_suffix=")", what_italics=True, what_color="#BBBBBB")
define e = Character("Eileen", color="#FF99CC", what_prefix="\"", what_suffix="\"")
label start:
scene black with fade
"*** START ***"
centered "Welcome to [config.name] [config.version]."
$ mc_name = renpy.input("What is your name? {i}(Press ENTER for [persistent.saved_mc_name]){/i}")
$ mc_name = mc_name.strip() or [persistent.saved_mc_name]
$ persistent.saved_mc_name = mc_name
"You are in a comfortable tunnel like hall."
e "Welcome [mc]."
mc "Thanks [e]."
mc_t "Wow, [e] is pretty."
"Waiter" "Could I assist you finding a table?"
"*** THE END ***"
return
Okay, there's a lot going on there, but for the most part I've included everything for a reason.
persistent
is a storage area for variables. It persists between gameplays. Normally, when you start a game all the variables are reset. Persistent variables aren't and will retain whatever value they previously had. It's great for volume levels for example (though RenPy has it's own store for that).
I define a specific
Character()
known as "narrator". This is one of a number of
You must be registered to see the links
that RenPy uses. In this case,
narrator
effectively speaks any line of dialogue not assigned to any other character. I override the default character definition so I can change the spoken text to a light yellow color. It's a small distinctive change that adds a surprising amount of polish for such a small change. The choice of color presumes that "normal" spoken text is white.
Text that contains
" [ ] "
will normally display the value of a variable within the brackets. In my initial code, I use this to allow the player to change the MC's name.
what_prefix
and
what_suffix
add text before and after any spoken dialogue. It means any dialogue appears within your game in the same way that it would be shown in a book, within quotes. Again, a tiny bit of unnecessary polish.
I define TWO almost identical characters for the MC.
mc
and
mc_t
. The second one is for when the MC is thinking. The dialogue is displayed differently than spoken text by changing the color slightly, enclosing the text in parentheses rather than quotes and the line is shown in italics. It's unusual for the player to be able to hear the internal monologue of any other character - but you could do it with other characters too. It's much easier than typing
mc "{i}(She's pretty.){/i}"
. Again, not necessary but the tiny amount of work pays off very quickly when working on a script that has the MC thinking a lot. If your characters whisper a lot - you could create variations on
mc_w
too.
All other speaking characters get the
what_prefix/suffix
treatment. In this example there's only one other character. There'd normally be lots.
Try to add transitions like
with fade
or
with dissolve
to any image you display as a background using
scene
. Fade is good when moving between locations. Dissolve is good practically everywhere else. Omitting transitions is fine, but can feel a bit abrupt - though you tend to only notice it when you've been playing a game that uses
with dissolve
everywhere and then play a game without them.
centered
is another one of those special predefined characters. It writes text across the center of the screen rather than at the bottom. It's really useful for things like "Time passes..." or "Morning." type messages.
The next block is about asking the player to name the MC. You'll see variations on it in most games. Mine is a little bit of an evolution of the normal code, in so much as the name the player picks is stored in a persistent variable. What it means is that when the player next starts a new game, they will be offered the same name as you used last time as the default. A tiny touch, but a nice once.
Again, I'm using text with variable embedded within it to show the values of those variables. Normally, those variables would be numbers or strings... in this case it is a
Character()
which you might think would incompatible. But a nice thing built into RenPy is that character objects used as string display the character's name instead. If you can get into the habit of using the variable rather than typing out character names all the time - you
could expand your game at some point to allow the player to name/rename all or most of the characters rather than just the MC. Though it is something you need to do right for the outset.
(btw, if you do allow the player to name other characters - especially at the start of the game - show a picture of the character and explain their relationship to you as you prompt the player for a name. Ideally list all the "types" of nameable characters first too. Nothing worse than naming your sister only to find out that you have a younger sister to name too).
The "Waiter" is another way of naming a character that is often overlooked. Typically a temporary throwaway character like a waiter, policeman or shop assistant. Instead of using a variable (Character), just use a string. There's no formatting and it's not ideal - but equally it's a simple alternative to defining another
Character()
that will never be used again. Honestly, I wouldn't do it this way - but it's so often overlooked as an option, I thought I'd include it.
And that's pretty much it. By adding a few optional parameters to each character definition, you can make the context of what the text being shown to the player much more obvious.