Okay, so I've been figuring the ConditionSwitch functionality in Ren'Py out for a bit, and after some discussions on the Ren'Py forums I've decided to write this little tutorial. It really is pretty easy functionality, but there are a few pitfalls and I hope this helps someone at some point.
Resources:The Ren'Py project and script file are attached to this post. Download either one and look through it, it's got working code in there that you can expand on.
What is ConditionSwitch?This is best answered with an example. Suppose I'm putting some sort of fighting system in my game, be it a standard RPG-style fighting game or something more real-time. Either way, it's easy to imagine that I want the picture display of an enemy or the player's character to change when he gets damage. At first he'd be healthy, but the more damaged he gets, the worse the picture should look.
JohnIn this example we'll call our hapless target John. He will have three pictures. Apologies for the crappy quality of the pictures, but I needed something quick to use in the project. They're a little large, but I think the general idea comes across.
Picture 1 – undamaged – more then 50% hit points

John is doing fine. He is not hurt at all. It's just a fleshwound. Come back, coward! I can still bite!
Picture 2 – hurt – between 50% and 10% of hit points

John is hurt. He's not doing very well and could use a potion or some such.
Picture 3 – very hurt – Less then 10% of hit points

John is near death. Poor John.
The 'wrong' way to do itAs you can see, in this example we're giving John hit points. We're defining a variable for this: current_hp. At the beginning of the fight, it is set as follows:
Code:
$ current_hp = 100
(Yes, we could've worked with maximum_hp as well, but to keep it simple we're only using this one)
Now there are two ways of displaying a different picture for John when he gets progressively more hurt. With or without ConditionSwitch. To illustrated the difference, let's go with the 'wrong' way first: without ConditionSwitch. You'd code something like the following in Ren'Py.
Code:
image john = “john.png”
image john hurt = “john_hurt.png”
image john_very_hurt = “john_very_hurt.png”
Then, during combat, you'd have to check at the end of every damage step to see if the picture has to change:
Code:
if (current_hp < 10):
show john_very_hurt
elif (current_hp < 50):
show john_hurt
Or something to that effect.
The ConditionSwitch way to do itAll the above together works, in theory. However, it means we have to run the check for John’s hitpoints whenever he gets damage. Also, if we have multiple images of John getting more damaged, one at 80%, one at 60%, one at 40%, etcetera, then this gets a bit more complicated. It’s much more elegant to use the ConditionSwitch function in Ren’Py. It doesn’t take away the need to check if certain conditions are true, but it will take the work of switching out of your hands. How does it work? The wiki page is here:
http://www.renpy.org/wiki/renpy/doc/reference/functions/ConditionSwitchAnd gives us the following example:
Code:
image bg waterfront = ConditionSwitch(
"time_of_day == 'day'", "waterfront_day.jpg",
"time_of_day == 'night'", "waterfront_night.jpg",
)
You’ll see that it’s formatted in different lines. Each line is a unique combination of a condition (the first argument between quotes) and the image that has to be shown if the condition is true (the second argument between quotes). While an image is shown on the screen, Ren'Py will evaluate if the first condition is true. If it is, it'll show the picture coupled with the condition. If it's not true, it will move to the second condition and check it, etctera, etcetera.
Let’s take the example of John and his constant fighting. Really, I worry about John. We are going to add a total of three different lines to the ConditionSwitch of John.
Line 1
Code:
“current_hp < 10”, john_very_hurt.png”
This will show John when he´s on less then 10% of her hp.
Line 2:
Code:
“current_hp/max_hp<0.5”, “john_ hurt.png”
This will show John when he´s between 10% and 50% of her hp.
Line 3:
Code:
"True", “john.png”
Which seems like a bit of an odd line, at first. However, we do need it so that if the first and second line aren't true, the ConditionSwitch functionality can fall back on this line which, because we described the condition as "True", is always true. So if line 1 and 2 aren't True, John will always be shown as the basic John.png picture. You have to add the final "True" condition so the ConditionSwitch knows which image to show as a default. If you don’t, you’ll get the following error:
Code:
While running game code:
File "game\script.rpy", line 26, in script
Exception: Switch could not choose a displayable.
The above lines gives us:
Code:
image john = ConditionSwitch (
"current_hp < 10","john_very_hurt.png",
"current_hp < 50","john_hurt.png",
"True", "john.png"
)
And there you have it, simple as that. You can make your conditions longer and more complicated, but the basic premise remains the same. Check out the Ren'Py script or project linked above if you want to play around with the code. Feel free to ask me questions!
Troubleshooting - Commas after picture namesTry not to forget the commas at the end of the lines (the ones after declaring the picture names)! It’s an easy thing to forget and then your code won't work. Doing this...
Code:
image john = ConditionSwitch (
"current_hp < 10","john_very_hurt.png" <--- NO COMMA
"current_hp < 50","john_hurt.png" <--- NO COMMA
"True", "john.png"
)
... will give you errors such as this:
Code:
While running game code:
File "game\script.rpy", line 26, in script
NameError: name 'john_hurt' is not defined
Troubleshooting - Condition orderAs already described, the order is important. If you put the lines in in a different order, like so...
Code:
image john = ConditionSwitch (
"current_hp < 50","john_hurt.png",
"current_hp < 10","john_very_hurt.png",
"True", "john.png"
)
... you will never show 'john_very_hurt.png'. Checks go up to down. With this order, because 'current_hp < 50' is both true for 45 hitpoints and 5 hitpoints, your 'current_hp < 10' will never be checked and the linked picture will never be shown.