#Renpyhelpdesk
Explore tagged Tumblr posts
Note
How do you define a character whos name starts with the same letter as another?
After the “define” keyword you pick the name of the variable, it doesn’t have to only be one letter. So you’re free to define them like this:
define Sam = Character(’Samantha’)define Seb = Character(′Sebatian’)
Remember, the characters after “define” is what you’re calling the variable, so you can call it anything, even unrelated nicknames related to their personality or history or plot points.
Remember: If your code won’t compile, and you don’t know why; who ya gonna call? The Ren’Py Help Desk!
10 notes
·
View notes
Note
this is probably a dumb question, but how do you do text box things without assigning them to a character? (like narration)
For Ren’Py it’s as easy as just writing a “say” statement without a character attached.
For Example:Sam “Here’s a say statement that’s attached to a character.”
“And this one is said only by the default narrator and will have no name attached.”
There’s one built into Ren’Py who is invoked whenever you write a statement without a character variable in front of it.
I hope this helps! Remember: If your code won't compile, and you don't know why; who ya gonna call? The Ren'Py Help Desk!
#RenPy#Ren'Py#thehelpdesk#Renpyhelpdesk#RenPy: Characters#RenPy: Narrator#RenPy: Say Statement#dialogue#this on is simple but still important#think of all the neglected narrators#whose voices are being silenced without this!
9 notes
·
View notes
Note
Hey!! Thanks for your time. So I was wondering how I would write the code for something where I want the chances of success to be based on a percentage. I'm trying to implement lottery tickets, and I need it to have a 0.09% chance of success. And also, how would I make it so you get a different response for each outcome? Like if you failed to get one, I want your buddy to say "aw that's too bad, maybe next time!" And if not I want everyone to freak out, plus the earnings to be added. Thank you!!
I return from the void now that everyone is migrating back from the land of the South African Muskrat! Yours is a rather involved answer to see all of it below the cut
The answer to your question, at least the percentage part, is a matter of the randint() function in the Python library. In this case, you want something to happen only 1 in so many times. For example, 1 in 10 is a 10% chance. To simulate this in code, you can have the interpreter pick a random(note this isn’t true randomness, but it’s good enough for a video game we aren’t making a cyber security system!) number between 1 and 10. If it comes out to one number and one number only, then you pass the check. This makes it a 10% chance, just like if you rolled a 10 sided die.
For your .09% chance(very rare!), it would be 1 in ~1,100 chance.(.090909...%). So if you have Python pick a number between 1 and 1,100 and check to see if it’s one specific number, then you’ll have your lottery win.
The easiest way to implement this in game is to record the results of the 1 in 1,100 chance inside a function wrapper so that you can call it multiple times and they can check lots of tickets.
init python: def Lottery_Ticket(): ticket_num = renpy.random.randint(1, 1100) return ticket_num
In order to use the randint() function from the random library, you just need to invoke it! It’s a part of Renpy’s library. So you’d type renpy.random.randint(1,1100) like above. :)
Once that is done in your game code itself you’ll put the logic for the winning number. Let’s say it’s 42, for meme reasons.
You could write in your game file:
label check_ticket: $ ticket = Lottery_Ticket() if ticket == 42: jump you_win else: jump you_lose
This simple logic sets the ticket equal to the result of the Lottery_Ticket function. It then checks if the number is exactly the winning number you chose. If so, it takes you to the winning section of your game code, if not, it falls through and says you lose.
Every time they buy a ticket, you can send them to this label, it will re-run the Lottery_Ticket function anew, picking a new random number, and see if they won.
Under your winning code, since you asked, this is where you’d put your characters reacting positively! Note the thing in brackets is the player character’s name as a variable being interpolated by the engine. If you let the player pick their own name, that’s how you’d get it into the script. If they have a set name, just type that instead.
label you_win: e “Oh my God! [PC_Name] you did it! e “It’s like a dream come true!” $ Inv.add(lottery_winnings) $ renpy.notify(”You added“ + str(lottery_winnings) + “ to your wallet!”)
As you see, I’m using to functions. One that comes with Ren’Py calls in the notify screen context through the function. It needs to be a string inside which is why I’ve turned the int representing the lottery winnings into a string here.(This assumes you have a variable called “lottery_winnings” that has a specific integer value! Please initialize one before the start of your game!) (example: $ lottery_winnings = 10000)
The second is me assuming that you have an Inventory class instance with a method called “add” that can add money into a wallet variable. To make something like that:
init python: class Inventory(python_object): def__init__(self, wallet = 0): self.wallet = wallet self.pocket = [] def add(num): self.wallet += num return self.wallet
Then you just need an instance of it:$ Inv = Inventory() (I wrote it with defaults, so you don’t need to pass any arguments to the instance when you make it, though you are welcome to pass an INTEGER to it when you instantiate it so that your character starts with a certain amount of money. :D )
Then you can call the method on the variable to add the earnings to their wallet. :)
There’s also an empty pockets list inside of the inventory you can use to store the string names of objects they also own. For something like that:
$ Inv.pocket.append(”apple”)
This will add a string called “apple” to the pocket list inside the inventory. Which you can use to check if they “own” an object by checking if it is in the list.
if ‘apple’ in Inv.pocket: .......
But that’s more detail for another time.
You need to put the class in an init python block before the game starts so that you can make an instance of it to manipulate later.
For not winning, just have the ‘you_lose’ label have the dialogue you wanted.
label you_lose: e “Aw, that’s too bad. Maybe next time!”
And then continue on with the rest of the game.
I hope everything here is clear and this helps. I know this ask came in ages ago, but I still think answering it will help Ren’Py users in the now. Remember: If your code won’t compile, and you don’t what to do; who you gonna call? The Ren’Py Help Desk!
#RenPy#Ren'Py#thehelpdesk#Renpyhelpdesk#keyword: python#keyword: init python#Python#Python Classes#Inventory Code#function: renpy.notify()#function: renpy.random.randint()#keyword: jump#keyword: label
14 notes
·
View notes
Note
Hello! I'm not sure if this blog is still active, but it's worth a shot. When doing something with multiple endings, how would you do a dating sim with multiple endings for each character, like a Good one and a Bad one?
Heya Isaacie! Better late than never I hope?
I did an initial treatment of the idea of multiple endings here. I’d go about it a little differently now, so I’ll give more detail about architecture for a game below.
The basic substance of your question is “how do I make the game interpret the difference between different states?”. If you’re using variables to keep track of things, all you need to do is have the game test if the player has met certain conditions in order to determine an outcome.
For a game with multiple romance-ables, it might work best to separate the romance paths into different files. Then, at the end of each romance file, have the conditionals for if something is a good or bad end. You can bring the player back into the MAIN file for things that are the same across all runs, and then have the game check to see which character they are romancing to go decide where to go.
This would work something like:Main story line ~> romance path chosen ~> go to character’s romance file ~> romance interaction #1 ~> back to main file ~> romance interaction #2 ~> ect.
In that case, it would be simplest to CALL the new file’s first label, then RETURN at the end of the romance scene after choices are made. This will put you back into the main script right where you last left off to do general same story line things. Then you can call the next label in from the romance file and return back, ect.
If the story never intersects again once a main love interest is chosen(think something like Katawa Shoujo) then you can just continue the story in those romance files. (You’ll probably want to set a variable like Romance_X = True in your files too if it affect the main plotline minimally, but you still want ppl to reference it in dialogue or something!)
At the end of the romance files you need some way to determine if they’ve done “good” or “bad” to see what ending they should get. You can do this by keeping track of how many “affection points” they got and deciding if they have below a certain value they get a “Bad End”.
Example:
label determine_ending: if Leo_love <= 10: jump bad_ending elif Leo_love .... .....
Ect for each scenario. This only works if they can only romance one person at a time. They get locked into a romance path(whether or not the rest of the game has story beats in common between routes) and so only one person needs to be checked.
But what if you wanna let them romance multiple ppl at once and see which one they got the farthest with?
For something like that you’ll need to put the affections in a dictionary, determine which one is the largest and then do the good/bad ending logic above.The logic would look something like this:
init python: John_love = 0 Mike_love = 0 Jimmy_love = 0 Sasha_love = 0(game play where you add affection with variable_name += number amount)(then a python block right before the end of the game)python: affection_dict = {"John": John_love, "Mike": Mike_love, "Jim": Jimmy_love, "Sasha": Sasha_love} love_holder = [] winner = None
for x in affection_dict.values(): love_holder.append(x) love_max = max(love_holder) for x in affection_dict: if affection_dict[x] == love_max: winner = x
Then at the end of your main file you’d type something like this:
if winner == “Sasha”: jump Sasha_endingselif winner == “Mike”: jump Mike_endings ....
Ect for each romanceable. Then you once again determine if they got a good or bad ending with them or not based on affection, which is separate from who they had the most affection with.(they could theoretically have 0, 0, 5, 9 and need a minimum of 10 for any non-bad end, if can even check to see if the max of the list is bigger than 10 and if not just have them giga fail with an ultimate bad end or something. You’d just add a line after love_max = max(love_holder) to say:
if love_max < 10: jump ultra_fail
They won’t even get to the rest of the code to pick the winner because it doesn’t matter lol.)
All that being said, the basic principals are:-have conditions that are failable-figure out what level of failure justifies a bad ending based on how your game plays-test the state of the game based on those conditions-use the result of that state testing to produce an end state result
I know this was long, and a very delayed answer, but I hope this helps you and others! Remember: If your code won’t compile and you don’t know why; who ya gonna call? The Ren’Py Help Desk!
#RenPy#Ren'Py#thehelpdesk#Renpyhelpdesk#multiple endings#keyword: call#keyword: return#keyword: jump#conditionals#keyword: python#keyword: init python#coding design
18 notes
·
View notes
Note
In my game, I only want a certain choice option to display if the player chose a specific answer earlier in the game. I still want the menu to appear whether or not they answered a certain way earlier, but I only want one of the answer options to appear if they answered a certain way. How would I do this?
A simple way to do this is to create a variable set to either True or False at the beginning, most likely False would be easiest for you, and set a menu option to only appear IF this condition is true.So for example:
$ Secret_Heritage = False
This is at the start of the game. Then if they learn the information:
$ Secret_Heritage = True
An idea for your menu:
menu: “I know your secret!” if Secret_Heritage: jump revelation “How do you feel about pinapple on pizza?”: jump pizza_talk
This way it only shows up if they’ve learned the information.
I cover this in more detail in my tutorial about it here!
Remember: if you’re code won’t compile, and you don’t know why; who ya gonna call? The Ren’Py Help Desk!
#RenPy#Ren'Py#thehelpdesk#Renpyhelpdesk#keyword: menu#condtiional: if#Ren'Py: Conditionals#Python#I swear I will answer this question#until the end of my days!#it's the most popular thing to do with your game!
11 notes
·
View notes
Note
Is there a way to change the screen size?
This is a matter of the configuration of Renpy itself. This is commonly changed though and can be accessed through an init python block and the “config” namespace.
To change the resolution of the game you’d just need to type:
init python: config.screen_width = new integer config.screen_height = new integer
This needs to be done before the game’s start label and can be accomplished at the beginning of the renpy.gui file for your game, for example. You could also put it in the main file for your game but uh, try to stay organized please?
That’s all for this one. Remember: If your code won’t compile, and you don’t know why; who ya gonna call? The Ren’Py Help Desk!
#RenPy#Ren'Py#thehelpdesk#Renpyhelpdesk#keyword: init python#configuration#gui#the great return continues
6 notes
·
View notes
Note
For the menu choices appearing and disappearing, does the coding you displayed work through multiple playthroughs? If creating a dating sim, and you want one of the character routes to be available only after the game has been played through at least once, will your tutorial work, or do you have to do something fancier?
Fancier things I’m afraid. In order to have things persist through playthroughs like that, you have to set persistent style variables that, well, persist through games.
It’s gone over here in the Ren’Py documentation, but I’ll do a tutorial on it myself one day because it involves more pure Python functionality.
#RenPy#Ren'Py#thehelpdesk#Renpyhelpdesk#Ren'Py: Persistent#I'll have to explain this some other time#yes it's possible#but you need persistent data
3 notes
·
View notes
Note
hey ren'py help desk! i'd love a patreon, that'd be super cool! i also have a question! How do you code a menu choice to disappear? Let's say you have a menu with 5 choices. If you choose 1 choice, when you return to the same menu it won't show up. How do you that? Thank you!!!!! And good luck with your patreon!!
^^;
One of the first tutorials I made friend. It’s a common question, and one of the fun things to add to your game to make it look more fancy.
If you, or anyone else! still has more questions not answered in this tutorial, please feel free to call back. If not, then yay!
Remember: If your code won’t compile, and you don’t know why; who ya gonna call? The Ren’Py Help Deck!
#RenPy#Ren'Py#thehelpdesk#Renpyhelpdesk#keyword: menu#I get to reference myself this time!#The Great Return continues
5 notes
·
View notes
Text
Tutorials: All Those Empty Pockets
Hello everyone! This is the Ren'PyHelpDesk, coming to you live from your dashboards! I'm your host, codewhisperer, and all around answer genie. Welcome to the ninth tutorial and fourth step by step tutorial. On this lovely occasion, we are going over how to make a simple inventory system! As always, there's more than one way to crack an egg, but here's a basic way to do so. Actual tutorial under the cut.
Ok so, first things first, you're going to need to understand variables, python functionality, and choice menus. If you are unfamiliar with any of that go here or here.
Remember my blustering about "lists"? No? Ok well here's a quick copy paste to remind you.
"That last example is a “list”, an object borrowed from Ren’Py’s underlying Python. It’s an empty set that you can add things into. You can use it for an inventory, or an equip list. Basically it’s really handy when you want to keep track of several different “items”. "
From the Conditionals, Variables, and You tutorial. I promised I was going to come back to them and now is the time. An inventory tutorial is the perfect place to explain what a list is and then utilize it in an example.
Now, lists are implemented in Ren’Py by calling up python functionality with either a block or a dollar sign. When you first make the list, you can place things, items, inside of it, but you can also create it completely empty, like so:
Examples:
- $ inventory = [] - $ inventory = [hat, scarf]
As you can see, each individual item is separated by a comma inside the list. The system does this automatically when you add things on to the list, and you do so yourself when you initialize a list with items already in it.
Ok, that’s all well and good, but how is this going to get me an inventory? Think of the list like a container that holds multiple individual pieces under a single variable. Now, everything you add is accessible in one place and you can perform conditional checks on it.
There are two functions you need to know how to use in order to get the most from this Inventory tutortial though. They are methods that work on lists. The "append" function and the "remove" function. Simply enough they add and remove items from your list. There are other methods you can use found here to get the same effect, but those are the ones we're going to be using.
Like the tutorial before this, where I talked about the insert function, the same naming methods apply. You are performing this function on a specific piece of data. That's why when you call up the function you type it "X.append()", where X is the name of the data you want the function to use.
Last thing we need to cover is a keyword "in". This is from python, and it checks to see if a value is a member of a collective. You'd use this on lists, dictionaries, and other collectives containers of data. It's pretty simple and intuitive to use.
Example: - if "apple" in inventory: - if "bat" not in inventory:
This just checks if a piece of data called "apple" or "bat" is or is not in your collective data set(list) called "inventory". Piece of cake right?
Ok, so now that we've covered the preliminary stuff, here's how you put the pieces together. Let's start a new game. In the game, you have a freshman highschool student called "Lydia" and she just woke up for school. First thing's first though, we need to make some Characters, define some initial conditions, that sort of thing. We can simply set money as a variable that uses numbers, but for the inventory itself, we need to use a list.
Ah yeah here we go. One last thing before we move on. You see that init -2 python block at the top? That contains the old method for creating a new style. I'll be going over styles in a future tutorial, under the intermediate(and above) level of tutorials, but this particular style changes the default text to a bigger italic version.
Now that that's taken care of, let's start off our game.
If you take a look there, we have the Narrator introducing you to generic VN, but we also have something called "inv" being created. In this case "inv" is the variable I've assigned to represent the inventory for this example. You can call you inventory anything you want. "Bag of Holding", "Backpack", even something silly/nonsensical like "sparglebunny". Just make it something you can remember later, though the shorter the better, as you'll see in a moment. Lydia is presented with a dilema upon first awakening. She has overslept and doesn't have enough time for breakfast. A proper breakfast is important though, so what does she do?
Take a look at the menu more closely. Under the "Cherry poptarts" option, you have two things happening in Python. One is changing one of the variables we set at the beginning to "True" the other looks has to do with our "inv" list. I assume the rest of the menu is old hat by now, so let's just focus on that method.
What's happening is I'm calling up a function, append to be precise, to work on the "inv" variable. When you use "append()", first you tell the system *what* the name of the list you are appending is, in this case it's "inv". Then you tell it what you are appending it with, in this case "poptarts". So you type inv.append("poptarts"), with the poptarts in quotation marks to tell it it's a string and not a "type" of data.(You can save a specific set of data or create a new type of data with a particular name, so you have to explain to the system that it's a string and not a data type) If you were to use Shift+D and check the variable viewer under the developer's menu, you'd see that "inv" now looks like "inv = ['poptarts']". Cool right?
Later on, Lydia gets hungry on the bus(if she makes the bus!), and she has a decision to make. Does she scarf the poptarts(if she has them) or does she get off for delicious doughnuts?
Take a look at this picture right here. Here you are using the in keyword. This menu option only appears IF "poptarts" are in your inventory. Something that only happens if it is appended earlier during the first menu. Finally:
Take a look at this picture. It has the remove() method for lists. It refers to data the same way append() does. First the name of the list, and then what you are removing. IF you try to remove something that isn't there, you'll get an error. So be careful about that! In the case of what I've coded, you'll only eat the poptarts, or any of the other food, if it's in your inventory already(because that's the only way to get to those options). A safer way to do this in your game is to always check to see if something is there before removing it.
Example:
-if "apple" in inv: $ inv.remove("apple") else: l "I don't even have that!"
But that's not strictly necessary for this tutorial. If you were to look at the variables after you ate the poptarts, you'd see them gone from the inventory. "inv = []" It's as simple as that! Now, I got a little carried away writing this tutorial, so there's a lot more I haven't shown on this end of things. I use another list method later on in the game to check to see if the player's inventory is empty, and I have a if, elif, else tower similar to the kind you'd use to get multiple endings. Check out the whole game, all 300ish lines of it, and cannabalize any code you want/need to do the stuff you want. You'll find the full code here. You can also read about more Python list methods here, along with some other ways to use lists.
So that's it! I'll be making another post to talk about what comes next. So remember, if your code won't compile and you don't know why? Who ya' gonna call? The Ren'Py help desk!
#Ren'Py#RenPy#thehelpdesk#renpyhelpdesk#Tutorials#RenPy: append#RenPy: remove#keyword: in#keyword: python#RenPy: list
122 notes
·
View notes
Text
Tutorials: How Do I Get Multiple Endings Anyway?
(Hey guys, sorry this was late. I had a very busy morning, so I had to go to bed early. I also did some page renovating, so that these tutorials will be easy to find later! OwO Don't worry though! I'm writing up the next one as we speak and it'll be posted tomorrow morning at 8 as usual. Back to your regularly scheduled programming.)
Hey there everyone, and welcome back to the third installment of Tutorials with the Ren'Pyheldesk! I'm your host, and this is the first step-by-step tutorial I've made. In this tutorial, I'll be going over how to "get" multiple endings in your game.
A note before I start, there is always more than one way to get something done. There's always more than one way to code. This "multiple endings" code assumes the game decides the endings at the very end. It also assumes that the player isn't "locked" into a path, and can chose to mess around freely with the other characters.
None of that has to be true! Say you make something like LLTQ, a stat raiser with multiple endings. The actual end of the game at the end is the same for the most part, but the point isn't raising your stats to see what you get at the coronation, it's creating a combination of stats that will let you live long enough to get there.
Say you make something where the player decides to pursue one person or another at the very beginning. You still have multiple endings, they player just sets down a path and sees it to the end.
Now with that out of the way, here are "the tools" you are going to need to complete this tutorial.
-Menus
-Labels
-Jumps
-Variables
-If Statements
If you need to review any of those, or don't know how they work, go here or here.
All that said, let's get this step-by-step on the road!
The first thing you need to do is decide what kind of game you're making. Romantic Visual Novels with multiple endings and paths are common, but maybe you want to make a stat raising career builder? Whatever type of game you want to make, keep it in mind, that's how you decide what variables you need to keep track of, and how these variables will affect the ending.
In this tutorial, we're going to make a little dating sim. Why? Because I like dating sims, and so do a lot of people. Who doesn't like romance?
When making a dating sim the first thing you need to think about is how many "dates" the Main Character can pursue. 2? 6? 15? Whatever your number, that is how many affection meters you will need. Now, don't get too worried, you don't even have to show the affection meter(though I'll go over how to do that in another tutorial), it just needs to be there.
I think our lovely leading lady/lad having four potential dates is more than enough to handle!
Here's our setting:
It's the summer of their junior year, and they've wandered into the country side with their grandparents. School is getting more and more hectic and tiring and all our leading lady/lad wants to do is relax. Nothing more relaxing than the country! They arrive at their grandparents ranch to find its not as quiet as they remember. There's two new farm hands, a stuffy young math nerd helping your grandpa with the finances, and someone helping grandma run the gift shop. There goes your quiet vacation! But you aren't about to let a bunch of interlopers ruin your last summer before senior year, and besides they are kinda cute...
Yay! It's a dating sim set up. Let's say there's two boy and two girls. We have all the info we need to start coding.
First thing we need to do is pick variable names for each potential love. "boy1" and "girl2" are alright, but I promise after hours of coding, you'll rather see "Jenny_love_meter" than "girl1" and it's a lot easier to keep track of.
So, I think their names should be..."Jenny", "Derek". "Robert", and "Veronica". Yeah that's good.
So what should we name the variables? Well that's easy!
-Jenny_love
-Derek_love
-Robert_love
-Veronica_love
Simple right? So that's done, and that's great and all, but how does this get me multiple endings Ren'Pyhelpdesk? We're getting to that. The last thing you want to add to this simple dating sim is a "Day" counter. Well why? Well because it's a simple way to end the game. As soon as the day counts down to zero, it's game over! I think 30 days is long enough to find magical looooovvveee.
So let's name the day counter:
-Day_counter
If you notice, I'm using the same capitalization conventions for all of my variables. You want to do that, it makes debugging and naming things later easier.
So we have our 4 loves, a ranch, and 30 days. That's great, but how do you implement that? Never fear, pictures are here!
This is what your game should look like right under start. There are all of your variables.
The next part takes thought. At the beginning of every day, the player can choose where to go/who to hang out with. You as a creator need to figure out a way to make sure they met all four people, but once they do and know where they are, the romancing can begin! Let's say spending the whole day with one of the potential love interests nets you 5 affection points. There's thirty days in total, so that means any one person can have 150 points if the player only focuses on them. This also means you need to have 30 individual day interactions planned for each character, and that even if it's day 15, if the player hasn't talked to them before, they don't act like its fifteen days they've talked.
How can you do that? A simple way to do that is to keep a count of each time they talk, and have certain dialogue picked out for their first meeting and then other scenes picked out for each meeting in separate files. What does that mean? More variables.
How about this?:
-Jenny_day_count
-Derek_day_count
-Robert_day_count
-Veronica_day_count
This way, every time you talk to them, the system can keep track of how many times it is, and send you to a separate scene each time. So let's add that to the beginning.
See? Now they are also at the beginning. Now all you need to do is write 30 separate scenes of interaction for each character and you're golden. The player won't necessarily see those scenes, but this way if they focus on a single character, you won't run out of dialogue.
Now this little tale needs some set up, how about this?:
Seems pretty good. I mean in the scheme of things. Don't worry about those short hand character names for dialogue. That's outside of the scope of this tutorial, but I'll explain in a future one. Oh, one more thing though, I added another variable, yes I know, but it's important. See this right here?:
This is a combination label, variable, if statement. A quick explanation of what this does. The menu itself is a "but though must!" moment. If you try to go upstairs, it increments the "wrong_answer" variable and sends you back to the beginning of the label. The first time wrong_answer is set to zero, so you don't see the alternate dialogue, and the next two times you see "I don't know deary,.." The third time you click though, Grandma tells you to suck it up and forces you outside.
This is to take care of the "meet the potential love interests" problem, so now you, Grandma, Grandpa, and the four suitors are all in one place. You introduce yourselves, and Jamie goes back inside to unpack. Our leading Lady/Lad muses about their day and goes to sleep. I'm not going to write the introductions, only the unpacking stuff, before we get to the meat of the "game". Here's the last of the intro though:
After this you just need to program the individual days. Here's how that would work.
I'd make six files for each person with five days in it. At the beginning of each day, the player picks where to go, and then depending on how many times they've gone to hang out with their chosen person, they go to one of those individual files where which scene they get inside is determined. So something like this:
Each of those jumps, except the first one, leads to a label in a new file. Each of those new files has another if statement to determine which scene to show. Like so:
And then place the scene under the label(and any choices you want), and remember to subtract from the day counter at the end of every day
If you copy this format for each day and each person, you'll have unique scenes for each character that depend on how often you've hung out with them. The pastebin link at the end isn't going to have ALL the scenes made for you, but it will have the templates for you to expand it out to 30 days for each person.
Finally, you're at the end! You've hung out all you can, and maybe even fallen in love. How do you determine who the character ends up with?
Remember when I said, 30 days 150 points? Where here is where that comes in.
If the player spends all their time talking to one person they'll have 150 points. So then all you have to do is design an If that says if Jenny_love == 150 then Jenny ending or whatever right? Well what if they spent they time equally between two characters? How do you decide then? They they have 75 points each and it's a tie. What if they spend it between three people(ten days each!) because they didn't know if they would like any of them, and they have 50 points each! What if-
Alright, I'll explain:
150 points is the total "love points" pool. Giving it all or almost all to one player is no problem at all to think about and if one character has 76 points, then none of the other characters can catch up. There would only be 74 points left to split amount them, and even IF all of those points are in one character, it's still not equal. So that's the first set of If statements.
But that's not all! What if it's tied between two people. Then it would both be 75. You should then send it to a tiebreaker label where you can add or subtract more points depending on other choices and dialogue throughout the game, and then it'll decide which love ending to send you to. Or you can have the two people fight over them, or they can have an awesome poly-amorous relationship. Whatever you like.
The important part to remember though is that you need to account for every possible twoway tie iteration. Which is 3! by the way.You remember that factorial lesson from middle school? No? That's ok. I basically mean there's 6 possible two person iterations. Which looks like:
If it's tied three ways 50 each we have four options. JDV, JRV, DVR, JDR. Which looks like this:
And FINALLY, if they've managed to split their days so that they don't spend 10 days with anyone they get the forever friends with all ending, because they just didn't get to know anyone good enough. All that needs is a:
else: jump friends_forever_endings There are still other things to consider, like if a single person has at least 50 points and the rest is spread between the others, or if there's a tie between two people at less than 75, but that's what trial and error is for! You won't learn if I code everything, this is just the basic idea.
Pastebin with the code...you guys are welcome to cannibalize the hell out of that. Completely open don't even have to say where you got it.
So that's it! That's how you code multiple endings and plan it from beginning to end. i hope you guys find this useful, and the next tutorial will be much shorter. Until then, if your code won't compile, and you don't know why? Who ya gonna call? The Ren'Py Help Desk!
119 notes
·
View notes
Text
Tutorial: Menus, Labels, and Jumps
Hey there guys, and welcome to the first tutorial by the Renpyhelpdesk.
Now I know this is really a basic thing to go over, but I've seen a lot of ugly code since I've started Ren'Py and a lot of it is caused by a combination of these three factors:
-Poorly coded menus
-Call when you mean jump or vice versa
-Poorly named labels
You may not believe me now that this stuff is important, but 10k lines into your magnum opus you will thank me. Let's start with labels.
What is a Label?
A label is a specific type of keyword in the code. Think of it like a combination bookmark/chapter title. When you are reading a book, you use both to keep your place. The longer the book, or the more complicated, the more thankful you are of these bookmarks and headers. Imagine trying to read a 500 page novel without any clear chapter titles, even just numbers. Not very pleasant is it?
Well here's the first mistake people make with labels: not using enough of them.
There is no limit to the number of bookmarks you can use, and unlike a real book, the end user isn't going to see it. Going pages and pages without a label, even if you don't change the flow of the code, is going to make it harder to keep up with everything. Sure, the engine reads top to bottom if you don't tell it otherwise, but trying to figure out where a scene ends and another begins or what path/part of the path something is on without a label is a pain in the ass.
This brings me to my second common mistake about labels: really generic names. Do not do that to yourself. Literally do not. If you think trying to code with too few labels is hard, then try looking at code with really generic "scene 1_a" names in them. That tells you nothing about what is going on in that part of your code, nothing about what it's supposed to do. Yeah sure comments are great(seriously comments are life savers), but if your code is now 500 lines long and you have try to remember "what's scene 3_1_b" as compared to "ninjasarrive" I promise you will love yourself for "ninjasarrive" later. Remember these things are chapter titles/bookmarks. The more descriptive the better.
On that note, here are some things you need to keep in mind about label names.
-No spaces. If you want a space use an underscore
-keep in mind capitalization "school" is different than "School" to the interpreter.
-remember that there is an indent after the label. Everything in that label's block is indented. It doesn't matter how many spaces(most editors automatically use four) as long as you are consistent every time throughout the code.
Example of a label:
label goodjobsport:
Don't forget the colon at the end, or you will get so many errors.
Alright, moving onto menus, and oh boy, so much that could go wrong here.
So menus are a keyword that creates an easy way to make use of user input. It makes it so users are presented with a choice, one that leads them to different paths or has different affects(hopefully!).
Here's the first common mistake people make with menus, they forget the colon or the indent. Menus, when placed in the code, have a colon after them. The stuff inside the quotation marks is what the menu button actually says(and that's indented compared to the menu), and the stuff indented under that is what happens when the player presses the button.
Example of a menu:
menu:
"Do things.": "You did stuff!" jump stuff "Do other things": "You did other things!" jump stuffthesecond That brings me to my next common mistake, do not code everything inside of a menu. While it's entirely possible for everything that happens as a result of a choice to be inside of the menu itself, and even place menus inside of menus, do not do that. I can't tell you how incoherent it makes code for someone else to look at. Move the results of the choice to another label, for the love of all things holy, do not do THIS:
menu: "I love you!": e "Do you really?" j "Of course I do silly! Did you think I hated you? e "No I didn't think that but sometimes I wonder about you..." j "Well you don't have to because I definitely love you." "Maybe I should ask if they feel the same?" menu: "Do you love me?": e "Of course I love you blah blah blah" "No, I'm sorry I don't.": e "How can you do this to me? I'm a nice guy!" j "Well I know you're a nice guy but-" e "Your destroying my heart. I'm literally dying!" j "Don't be so dramatic!" e "No literally, I'm a creature that survives on love. e "I'm dying right now!" menu: "What?"
ect ect. I've seen people do this. Do not do this! That is a pain in the ass to debug. It makes thing more difficult then it has to be! It is ripe for more indent mistakes. Do not do this! Ok? We clear? Fantastic!
Well IDK Ren'PyHelpDesk; what am I supposed to do instead?
Welcome to the jump! Jump is a keyword that you are going to come to love over your experiences with Ren'Py. I've seen people avoid using it, I literally can not understand why. It's the easiest way to control the flow of your script. It's not something you would use in other coding languages the same way you do with Ren'Py, but it's seriously awesome here.
Let me give a quick explanation of the "flow". Imagine a river flowing down its banks. The water is the information in the script being presented to the user, and the "banks" are the interpreter. Ordinarily, the river just flows straight from beginning to end. That's how the interpreter reads your script, with straight banks. Changes to the "flow" caused by conditionals, jumps, calls, ect. are twists. turns, dead ends, whirlpools, ect. in the information presented to the user.
A Jump is a keyword that controls the flow, like a bend in a river, and all it tells the interpreter is to stop reading and go here instead, It's a skip that tells it to skip the code below this point and start reading again at this other point. That's all it is, but it really works wonders for keep paths straight, or branching choices, ect. Even just to keep menus working cleanly.
Example of a jump:
label Seuss: "Could you would you on a train?" "Could you would you in a plane?" jump greeneggs label maleauthors: mnw "The cocaine isn't the point! The cocaine is a metaphor!" "Why hadn't she read his manifesto?". "The prostitute had read his manifesto." jump thecakeisalie label greeneggs: "Not in a boat, or on a train, or in a plane!" label thecakeisalie: "Aperture Science...we do what we must, because we can!" As you can see, the labels and jumps work together. If you get to the Seuss label, you skip over the maleauthors label and dod not see the blustering about cocaine being a metaphor. If you end up at the maleauthors label you'll not see the stuff about green eggs and ham. This means you can have entirely separate conversations right next to each other, and the player won't ever see it.(if you do it correctly) This is the prelude to have different branching paths, and so separate endings. You can do all of that inside of the same script file, though having separate files might make it easier!
Let me do one last thing here, well two. Jump is different from call in that jump transfers control from one area to another, and Call creates another context on top of the old one. That doesn't seem to make much of a difference at first, because the player still sees the different new parts of the game, but it does. Calling in a new context doesn't remove the old one, it just stacks it on top. And when you try to "return" to end the game or for any other reason, it discards the new context and everything that followed and takes you back to the original menu/label where you came from. Sometimes that's exactly what you want, but don't use call when you mean jump or vice versa. It'll be a headache I promise.
For more information between call and jump and "the stack" see this post here. As a finale of sorts, here is all three of these things fit together to make nice easy to read, clean code, that's easy to debug, and even easier to share.
label start:
label the_beginning:
menu: "keep going": jump the_beginning "The end!": jump the_end
label the_end: "You did it! You made it to the end!" "Congratulations!"
return
This is usable code btw. Plug that into a renpy game and it'll run. :3 So that's it guys. Tune in next time when I cover every conditional so we have more flow control. After that I'll start the step by step tutorials.
#renpy#ren'py#the help desk#renpyhelpdesk#coding help#tutorials#keyword: jump#keyword: menu#keyword: label
114 notes
·
View notes
Text
Tutorials: Conditionals, Variables, and You
Hey everyone and welcome to the second tutorial for the Ren'Pyhelpdesk! If you are looking for a step by step tutorial, don't worry! After this one is posted, I'm going to get started working on two step by steps. I just wanted to make sure everyone had something to go back to if they needed an explanation for how the individual components worked in the first simple step by steps.
Tutorial below the cut.
So let's talk about variables. At some point it becomes inconvenient and/or impossible to keep track of a complicated game with only menus, labels, and jumps. At some point it's easier to keep track of what the players have and haven't seen/done with variables, or you need them for another reason.(affection points for example.) Variables are custom named trackers of user input/user progress/user interaction. Variables can be set to numbers, true or false, empty lists, lots of things. The important part though, is that they are there to help you stay organized.
Some types of in game effects can't be utilized without variables. A dating sim's affection meter or a rpg character's strength won't work without variables.
The easiest type of variable to use is a True/False. It's a variable that's a binary. It only has two states, True or False. On or Off. Believe it or not, there's a lot you can do with just true/false binary variables. You can make menu options appear and disappear. You can have different endings. You can have separate dialogue.
For some of the fancier stuff, you need variables that hold numbers. All you need is a variable name and a number set after it. Mind you all variables are set by calling up python functionality. So in order to set or change a variable, you need a dollar sign.($)
On that note, I should talk about variable names. Like menu names they can't have spaces, but can have underscores, and just like menus, capitalization counts.
Examples of variables:
- $ boy_love = True
- $ strength = 10
- $ count = 1
-$ inventory = []
Let's talk about that last one real fast. That last example is a "list", an object borrowed from Ren'Py's underlying Python. It's an empty set that you can add things into. You can use it for an inventory, or an equip list. Basically it's really handy when you want to keep track of several different "items".
Variables that are empty sets use a different format to manipulate in game, so we're going to ignore that for now. However, expect me to come back to that during another tutorial.
You can change number variables with operands. And the system will remember the new number.
-$ strength += 1
- $ count = 1*2
- $ strength -= 3
You can call up the variable dynamically in the game text. "You currently have [strength] strength!" When calling it up in text, it tells you the current value. If you change it and call it up again, it'll be a different number. Last note about numbers, it doesn't have to be just whole numbers. The system can remembers decimals, called floats.
- $ count = 5/2
Some common mistakes with variables are trying to change or set a variable without using a dollar sign and outside of a python block. Another common one is typing the name wrong because of capitalization issues or using "=" when you mean "==". Remember "=" sets the variable and "==" checks to see if something is "exactly equal". Finally, reversing the "+=" to "=+" when trying to increment or decrement a variable is pretty common too. Always remember to check your work!
Now variables on their own don't do much of anything. They sit silently in the background, where the player can't see them, unless you do something with them.
You need to set initial conditions before you try to use conditionals to "do something" with it. By this I mean you can't check to see if boy_love is true or false before you've defined boy_love. The best place for things like that is the beginning of the game, or the start of the individual file containing the variable.
Conditionals-Doing Something with Variables!
Now, Conditionals get their name from the fact it controls the flow of the script "conditionally"(unlike jump,call, or return which are unconditional). Like the scene from Pocahontas where there are two river branches, a conditional checks variables previously established and picks which way to go based on them. Slow and steady, or fast and rocky.
Now, there are three conditional statements in Ren'py. If, While, and Pass. I'll explain each one and give an example, and then post a small bit of code at the end you can try in your own files.
If Statements:
The "if" statement is the one most commonly used in programming. It's versatile and easier to understand than while. An "if" statement tells the interpreter to check IF something is X way. Think of it like this, in the case of the binary True/False variable, it's checking to see if the switch is one way or the other. You can check if a variable is true, or if it's not true. You can check if the light is on or off basically.
If you check variables that hold numbers you can do all sorts of things. You can check to see if the variable is a specific number. If it's greater than or less than a number. If it's between two numbers, if it's every number BUT this one, ect. What you can use that for is limited by your imagination and need.
The thing to remember though, you are usually testing a variable to decide what happens next. Did they pick up that sword from before? If so they can defend themselves with it. Or maybe they got a bow? Bow and arrows it is.
If you want to test more than one thing at once you have to use either an "else" and/or "elif". An "else" at the end is optional, but sometimes necessary, especially if there are more than one option or you want the game to go somewhere else if the player "fails" the other if checks.
"Else" is always at the end, "Elif" is in the middle(and sometimes it's the last option), and "If" is always first.
"Elif" is an abbreviation. It means "Else If". When the interpreter is reading through the options, this is how it read it.
If X thing do this. Else if Y thing do this, Else do Z.
if strength = 15:
elif strength > 10 and strength < 15:
else:
If strength is equal to 15 do X, else if strength is greater than 10 and less than 15 do Y, else do Z.
Each one ends in a colon, and then there is a block underneath it indented as compared to the proceeding if statement. That tells the interpreter what to do IF this condition is met.
if strength = 15: "Wow mister you're really strong!"
It's that simple, or complicated, depending on what you are trying to test.
While Statements:
Now, "while" statements make loops. They work like this:
While these conditions are true(or false), do X. You set the conditions that need to be true at the beginning of the while statement, and then the loop runs. You need to have it self-terminate or for there to be a "break" command. It's easier to have it self-terminate though, since "break" is based on python functionality, and a little harder to implement in game.
What would you need a while loop for? Well you could use it to count down to blast off in game.
while count > 0: "[count]!" $ count -= 1
"Blast off!"
This way the game will continue to count all on its own without any input from you or the user.
But you can use it for other things too. I used it to program an event for the mock-up of the first day in my TMNT dating sim.
while count < 4: $ count +=1 jump questions
label questions:
In this while, the event continued as long as they hadn't been through 3 times(the count variable was set to 1 before the event started, and the label with the while loop was bypassed the first time through to go immediately to the questions label). There's an easier way to get the same result though that doesn't involve a while loop, so I used that later.
While loops would be especially useful for rpg battles though. You can tell the system that while battles is true that X, Y, Z things happens, and until the battle is over(and you set it out of battle mood in another part inside the battle itself) battle settings continue.
If you don't remember to either "break" or have it self-terminate though, you'll make an infinite loop.
While True: "This is the song that never ends!" "Yes it goes on and on my friends." "People started singing it not knowing what it was," "And they continue on and on just because..."
That loop will never terminate, and your game will be stuck like that. So be very careful with while loop construction. The worst that can happen when you mess up an if is it refuses to compile or won't trigger. If you mess up a while, you'll be stuck in Ground Hog Day...or The Mystery Spot.
Pass Statement:
Final stretch guys! Pass statements are the shortest one. You use those when the coding of a block requires there be something there, but you don't want it to do anything.
Example of a Pass Statement:
if points >= 10: "Kickass!"
elif points >= 1: pass
else: "Man you aren't so good at this game..."
It's that simple.
So how does this all work together? Here's a quick example for a dating sim.
label start:
$ boy1_affection = 0 $ boy2_affection = 0
menu: "I love Rob!": $ boy1_affection += 5 jump endings "I love Dan!": $ boy2_affection += 5 jump endings "I don't like either...": jump endings
label endings: if boy1_affection == 5: jump boy1_ending elif boy2_affection == 5: jump boy2_ending else: jump friends4ever
label boy1_ending:
"And so Rob and I got married. We had 2.5 children, a dog, and lived behind a white picket fence!"
"The end."
return
label boy2_ending:
"And so Dan and I became millionaires by counting cards in Vegas."
"We bought a condo on the beach and traveled the world in style."
"The end"
return
label friends4ever:
"I managed to convince them both that we should all remain friends."
"After we dodged the police in Vegas, we moved into the suburbs."
"Rob and Dan still argue sometimes, but not about me for once."
"Besides! I like girls anyway."
"The end."
return
So if you copy paste that into a script file in ren'py that should run easy peasy.
That's it everyone! I hope this has been helpful, and I'll see you soon for the first step by step tutorial. How do you get multiple endings anyway? And remember, if your code won't compile and you have no idea why? Who ya gonna call? The Ren'Py Help Desk!
#renpy#ren'py#the help desk#renpyhelpdesk#tutorials#variables#conditionals#condtiional: if#conditional: while#conditional: pass
107 notes
·
View notes
Text
Tutorials: So What Was Your Name Again?
Hello everyone, and welcome the eighth tutorial and third step-by-step tutorial. I'm your host, phone monkey, and information relay Ren'PyHelpDesk. Today in the wonderful world of Ren'Py, we're are going over how to get a new type of user interaction into your game. User input! Hold on to your butts coder kids, it's going to be a rollercoaster of fun!
The first thing I need to go over is a quick refresher of terms.
-Variables
-Python blocks
-Arguments and Keyword arguments
Variables are bits of code needed to remember previous user interaction or specific game objects.(like an affection meter or how many times they've seen a menu or pressed a button.) They are assigned using python functionality and are called up with either as a single line of code, with a dollar sign, or as a block with the "python" keyword.
Example:
$ strength = 10
$ met_kathy = True
Python blocks are coding blocks written using python functionality. You call them up using the keyword "python" and everything inside the block itself has to be written using python functions instead of the Ren'Py pseudo-code.
Example:
python: Jenny_love = 0 Robert_love = 0 Daniel_love = 15 Sandry_love = 5
And finally, arguments and keyword arguments are related to the Class structure (and well functions too) in Python itself. I haven't really gone over either in any detail yet, and I'm not going to do so here, but when you see me copy and paste a Class definition from the documentation, the arguments come before the keyword arguments, and while the arguments are always needed to create an instance of a "Class" the keyword arguments are optional.
Example:
Character(name, kind=adv, **kwargs)
Where "name" is an argument you have to specify every time you instantiate a new character, "kind" is an argument where the default is chosen as adv mode(which is why in you have to specify nvl mode when you create a character for that mode) and then it takes any number of optional **kwargs, including(but not limited to) color, image, who_prefix, ect.
Now that that's done, I can get to the actual discussion of the function in question. What we're working with is the input function, that allows user to save a piece of custom typed date in the system, so it can be evaluated and manipulated later. In the example I'm going to walk you through, we're going to use it to give the player character a custom name, but you can also use it to "input" a code to unlock content or how I'm going to use it in the TMNT Dating Sim, to insert preferred pronouns.
Here's the definition of the input function:
renpy.input(prompt, default='', allow=None, exclude='{}', length=None, with_none=None, pixel_width=None)
I'll explain each of the *args and **kwargs inside. The prompt is what the textbox displays to the player. It needs to be a string, or text inside of two quotation sets. Preferably, it should be a natural sounding part of the narrative, but it can be as simple as "Type your name here." Or some such.
Now allow and exclude have to do with the characters the player can type. You can allow all characters, or tell the system to exclude numbers if you want them to type in a player name. Or you can just type in what characters are allowed. Whichever is easier. For example, if you only want them to type numbers, it's easier to just place those in the "allow" section. They would be placed in between quotation marks and each character separated by a comma.
The length is a number that tells the system the maximum number of characters the input can take. Good for making sure names stay within certain length bonds and your textbox continues to rock.
Finally, pixel width is how many pixels wide an input can be. Better than character length in some ways. That way you don't limit it to say "10" characters, but instead how much room it can take up max.(only a consideration for things that stay on the screen like the player character name in this example.)
Ok, now that that's explained, let's pull up a quick example. I'll post some screen shots and explain them, but a link to the entire usable code will be at the end.
Alright! So this is the top of the code, and I just wanted to highligh something before I move on. I'll be coming back to DynamicCharacters as a class some other time, but it's in there to allow me to easily change the name of the "narrator". In an example this short, it doesn't make much of a difference, but in a more
complicated game, you better believe it will. The string used as the name in this case is a stand in. A variable in the same way that povname is. It's similarly assessed dynamically, so when I change it later in the script(as you can see highlighted in the full example I'll link to at the end) it changes the name.
Ok, onto the interesting stuff!
This one is a little small, but you can still get the gist of it. You can see me change the narrator's name in the game, and then there's the python block. Ok so let me explain that a little bit more.
First you call up the python functionality with the keyword "python" and then you indent because it expects a block. The first line is the name of the variable you're going to use to represent your pov character's name. As you can see, it matches the name of the variable you defined as the Character "name"(with a "shortcut" of sorts being "pov"). So that's one side of the equation. On the other side is the renpy.input function. This tells the system that the variable is an "input" by the user. There's the prompt string in quotation marks. That's what's actually displayed to your player.
The next part isn't really intutive, I know it wasn't to me the first time I did this, so let me explain. The strip function you see on the right side of the equation removes any extra spaces the player might have added by accident. But as you can see it's called povname.strip. This is because you are stripping the extra characters off of the povname variable. The variable which right before this you had the player input themselves.
So first they input the variable, then it's stripped of its extra spaces. You can only perform the strip() function on "povname" because it already exists as a variable in the system.(the first line).
The last part tells the system IF they just don't pick a name. Say they've played this before and they don't care, or maybe they just want to know what the default is, it tells the system to assign the "input"(povname) variable "Joshua". This way they can't go through your game with no name at all.
There's still more code after this for dealing with varifying the players name and such, but that's the basics.
You can find the entire code here, and it's been debugged and runs like a charm. Just copy paste everything to see it run. Here's the link!
So yeah, sorry for how long this took to get out everyone, I know it's short, but things are getting a little hectic over in making that Ren'Py Dating Sim land. But I'm still alive and still here. So remember, if your code won't compile and you don't know why? Who ya gonna call? The Ren'Py helpdesk!
103 notes
·
View notes
Text
Tutorials: Text, Dialogue, and Character Customization
Hello everyone, and welcome to the sixth tutorial from the Ren'Pyhelpdesk! I'm your host, question answer-er, and the only one manning the phones at this wacky call center.
Today we're going over some basics for how text, dialogue, and characters work. Don't expect anything fancy, but this is all needed stuff to get your Visual Novel business rolling. More info below the cut.
The first thing we're going over is how "text" works in Ren'Py. Here's a quick explanation:
The Ren'py interpreter thinks anything in between single or double quotation makes is "said", or text presented to the user in the dialogue box, also known as the Say Screen. Things are slightly different in NVL mode, but I'll do ADV first.
ADV-MODE:
Examples:
-"This is a sentence."
-'Also, this is a sentence.'
Both of those are considered text "said" by a character in the game. If you don't tell the system "who" said a line, it assumes that the "narrator" character inherent to the Ren'Py system is speaking.
A quick note though, let's say you want actual double quotation marks in your dialogue, what do you do?
The problem is the system, if you started that dialogue line with double quotation marks to designate the spoken sentence, thinks it'll end if you write another one. For example:
-"I'm sure you're such a "stud"."
Is going to be read very wrong. The first part "I'm sure you're such a" will end up being said by the character in question, but the second quotation mark with tell the system that dialogue ends. So "stud" itself will be missed, and then the character will say "." by itself. That's not what you want at all.
A solution is to use single quotation marks. Since only a single quotation mark with then end the dialogue.
-'I am sure you are such a "stud".'
But if you notice I had to rewrite the sentence so that there were no contractions. That's because the apostrophe used to denote the missing letters in English would have caused the dialogue to end once again.
So what to do?
The solution is to use "Escape" characters in the dialogue. This allows you to use any of those marks inside the actual dialogue itself without it causing any system errors. That first sentence could be written thus:
-"I'm sure you're such a \"stud\"."
The backslashes before the double quotation marks here tell the system to considering them part of the dialogue and not as signs to end the shown text.
Which type you use depends on what you're using to introduce dialogue in that line. There are also "Escape" characters for other things in the text as well. There are as follows:
- \" For Escaping double quotation marks.
- \' For Escaping single quotation marks.
- \\ For Writing backslash in the dialogue itself.
- [[ The left bracket is used to call up interpolated data(like dynamic variables). If you want to use brackets in your text you need two left brackets and then a right. [[stuff]
- {{ The left brace is used to call up various text style tags(like italics). If you want to use braces in your text you need two left braces and then a right. {{stuff}
There are two other Escape characters. \n, which calls up a new line, and "\ "<~this is a backslash and a space. Ordinarily the interpreter combines all spaces down into a single white space character. If you want the space there, you need to tell it so with this Escape character.
Now you obviously want your dialogue to be said by *someone* most of the time. In order to get an actual name for your dialogue you can write the name in quotation marks in front of the actual dialogue spoken.
-"Frank" "This is said by Frank."
-"Bill" 'And this is said by Bill.'
That's all well and good for a character you only use a few times, but if that's your main character, that's a ultra pain in the butt to keep having to write out. It doesn't seem like that big of a deal now, but once you are like 500+ lines into your game, you do not want to write out the main character's name for every line of dialogue. So what do you do?
Well Ren'Py has a way to handle that, it's called the Character object class.
Character(name, kind=adv, **args)
Classes are something that exists on the Python side of things, but the point is that you can define an object the interpreter can manipulate with a bunch of attributes specific only to that object.
In this case we are utilizing a class already in Ren'Py's library. In order to use it though, we need to define it as variable first. If you look in your script file at the top it has a section already laid out for you to define characters. It's placed above the start label, which tells the system that it's formed/built at "init" time.
If you look at "Elieen" it looks like this:
-define e = Character('Eileen', color="#c8ffc8")
There you call up the define keyword then tell it the name of what you are defining, and then what it is.
"define the variable e as"<~ That's what the interpreter sees on the left side of the equal sign.
"A Character object whose name is Elieen and whose "who_style" has this color"<~That's what the interpreter sees on the right side of the equal sign.
The "who_style" is the style of the name in the textbox(this defaults to "style.say_label" if not otherwise chosen). If you want to change the actual text color, you have to do it another way.
So now when you type dialogue all you have to do is write this:
- e "My name is Elieen."
Now Elieen will say that statement. This is all without you having to place the e itself in quotation marks.
A word of caution though, the system considers capitalization. So "E" is different than "e" to the system. Keep that in mind when making Characters.
You can also either use double or single quotations marks for the name inside the tuple as long as they match up. So write "Elieen" or 'Elieen' not 'Elieen".
Take a look at the Characters I have defined for my own work in previous tutorials, like Now Your See Me; Now You Don't, for more examples.
NVL MODE:
This is all well and good for the ADV mode, but what about NVL? Well NVL is more like a "book" page. The Say Screen takes up the whole background, and text is placed on top of it. How do you get the dialogue to appear and disappear? In ADV mode, every time you start a new dialogue line with "stuff" or 'stuff' it clears the screen and places the new dialogue up there, but in NVL mode, you have to tell it to clear or it won't. You also have to hide and show the window at times when you want the background to be clear of the NVL say screen.
You need to tell the system that the characters are for NVL mode, or it won't work. So when you define your characters now it looks like this:
-define s = Character("Sylvie", kind=nvl, color="#c8ffc8")
The Characters are automatically assumed to be in ADV mode (which is what you see in the generalized Character Class object before the **args) so you have to tell it otherwise.
You also have to define the narrator in this mode as opposed to just using the ADV narrator that defaults when there are no name tags in front of individual dialogue tags.
-define narrator = Character(None, kinds=nvl)
So that's how you get started, but if you just keep going eventually the text will end up off the bottom of the page. To fix that, you have to tell the system to paste it in pages by using the nvl clear statement.
Here's an example:
(this assumes you already have characters and narrator defined.)
"It was a beautiful day outside. The sun was shining, the birds were singing, all of creation was having an absolutely grand day. All of creation except Stinkmeaner."
Stink "I hate sunshine, ponies, dolphins, rainbows, and everything good in the world."
nvl clear
"Stinkmeaner glared up at the sun with the last of his poor eyesight, it was too bright and cheerful outside in his snarky opinion."
As you can see, the clear statement was used to make a whole different page with none of the other dialogue from before. Check out the script of "The Question" in NVL-mode here. You'll see it in the code.
The rest of the explanations for dialogue tags holds the same though.(Escape characters, white space, ect.)
Ok well this is great, but what if you want something special in the dialogue like italics, bold, underline, or anything like that? No problem!
Enter Text Tags:
They are used similar to BBC code format. If you are familiar with BBC code, then you'll be 75% there. You can find a good list of the general tags you'll use here. You'd use them with braces in the text. This is why you need two left braces to use braces in the text on their own, because otherwise the interpreter will think you are trying to use a text styling tag. Examples:
-{b}-bold
-{i}-italic
-{u}-underline
"This sentence is written in normal font."
"{b}And this is in bold.{/b}"
The ending brace needs a forward slash to tell the stem to stop the text style. It also follows the principal of last open, first closed. Examples:
"{b}{i}This is Bold and Italic done correctly.{/i}{/b}"
"{b}{i}This is Bold and Italic done incorrectly.{/b}{/i}"
Take a look at all your options in the link above for more fun stuff.
As a side note, if you notice yourself using text style option all the time for a certain character, it'll be much faster to make a style. That's not going to be covered here, but there is one final thing I want to cover in this tutorial.
Character Customization:
There are some customizations you can make without creating an entirely different style, and I'm going to cover them below. The full list can be found here, but here are some you’re going to use a lot:
-color="__"
-image="__"
-show_side_image="__"
-show_two_window=True/False
The color needs to be a red-green-blue hex triple. This is the same that's used on webpages or photo editors.
The image has to be the tag that you are using for the images associated with the character. I'll go over the specifics in the next tutorial about images and displayables, but the "tag" associated with an image series is the first word used after the define statement. So "define Elieen smile" and "define Elieen frown" are all under the "Elieen" tag. You'd simply the supply the image with Elieen in the double quotations so that the character has images attached to it.(I'll show how that works in dialogue in a second).
The show_side_image works by supplying it with an Image statement that specifies the image to use and it's position in a tuple. It looks like this:
show_side_image=Image("Magicalgirlside.png", xalign=1.0, yalign=.95)
The show_two_window is a True/False statement that tells the interpreter that this character either has their name in the dialogue with their dialogue or in a connected box above it. Here's an example of a character that has all of those properties in it.
define teach = Character(_("Magic Teacher"), color="#60003f", image="teach", show_two_window=True, show_side_image=Image("Magicalgirlside.png", xalign=1.0, yalign=.95))
This creates a character called "Magic Teacher" whose name is plum colored and in a separate box with a side image on the bottom right.
This tutorial seems to go on forever, but there's one last thing. When you have an image attached to your character like this you don't have to use the "show" to change the displayed character image once it's on the screen. Example:
- show teach happy
teach "What a beautiful day!"
teach concerned "I hope it doesn't rain."
As you can see the system searches your images under everything tagged attached to whatever image tag you've used when you created the Character. It then looks under those images and picks the one that matches the closest. If it can't find anything under the specific "teach concerned" or more than one match, it won't display anything, so be careful.
Ok everyone that was sure a looonngg tutorial and I didn't even cover everything you can do with Text, Characters, and Character Customization! I hope you all found this useful, and remember, if your code won't compile and you don't know why? Who ya' gonna call? The Ren'Pyhelpdesk!
#Ren'Py#RenPy#thehelpdesk#renpyhelpdesk#tutorials#Renpy: Text#RenPy: Characters#Character Customization
84 notes
·
View notes
Text
Tutorials: Images, Transitions, and Making the Scene
Hello everyone and welcome to the seventh tutorial for the Ren’Pyhelpdesk! I’m your host, codemonkey, and evening entertainment, and it’s time to go over the basic of images!
Now a Visual Novel is nothing without images; I mean it’s called a visual novel am I right? After I’m done with this, you’ll be able to make a simple VN with all kinds of shinnies in it. Actual tutorial below the cut.
In order to get started, you need to add your images to the game. In order for the interpreter to eventually find the pictures, they need to be in the "game" directory for the game you are making. All you have to do is copy paste, or move them into the "game" directory. If you want to keep it in a separate sub-folder instead of inside the game folder itself, you need to define the images differently later. So remember where you put it! The game directory is inside of the Ren'Py folder, inside of the folder with the game's name. So wherever you put Ren"py, go there and you'll find the game directory.
Once you have your images all comfy coozy in your game directory itself, you still need to define it as a specific "image" in the game. The interpreter works by reading the saved pictures as a specific game image, so you have to name it. You have to use the "image" keyword and it has to be in the init block before the game starts. You can't create entirely new images outside of the init block. What I mean is, you can't define new images outside of the init block. So you need to place all the images you need *before* the start label.
A word about names:
-The first word is the tag.
-There can be spaces.
-As always descriptive is better than not, but try not to make it too long.
Examples:
image bg forest day = "forestbright.jpeg"
image Danny happy = "images/Dannysmile.png"
The first one is how images are defined inside the game directory with no sub-folders involved. The second is how it's defined if it's inside a sub-folder inside the game directory. The directory "Happyville/game/" is assumed if there is nothing in front of the image definition. So, once again, watch out where you are saving things!
A note, backgrounds can be in either be in .jpeg or .png format, but it's in your best interest to save character art as .png. This is because character art usually needs to be transparent, or at least have that property, while background art typically does not.
After you have all of your images created in the init block, you can call them up in the script using either "show" keyword or the "scene" keyword. They each do different things. The "scene" keyword is only used to wipe the whole screen and place a new image in. The "show" keyword is used to place an image on top of all of the others there.
That means you should only use the "scene" keyword when you are bring up a new background/setting.
There is one last useful keyword when it comes to images showing up, and that the "hide" keyword. "Hide" does just that. It removes an image that you used "show" or "scene" to bring up. You'd use "hide" when you wanted to have one character leave but the "scene" itself isn't over.
Now, here is a good time to explain what I meant by "tag" from before, in the previous tutorial I talked about how you can attach a specific set of image tags to a Character object. When you define an image with the "image" keyword, the first word after the keyword is the "tag". The tag creates a group of images. This is useful for grouping together bg images or character images. If you call up an image with "show" or "scene" it automatically replaces an image with the same "tag", further, when combined with the image tag for the Character object, that means everything with a specific "tag" is attached to this character.
For example, all of Elieen's images have the tag "Elieen", so the first word after "image" in every Elieen image is her name and then a specific description of what the image is.
If you are careful when creating/naming all the images, you can group all the images for a specific character with a single tag. This makes it very easy for you later on to code, because you can just attach an image tag to the Character object.(You typically make those *after* you've "made" all your images in a section above the Character objects code.)
So that's how you get them into your game, but how to you position them so that they appear where you want? How do you make it so that two characters can be on screen without overlapping each other?
Luckily, there's a statement for that. Enter the "at" clause, designed to give you control over where your wonderful images show up. By default, images are centered with their bottom edge touching the bottom of the screen. That's cool for backgrounds and single characters, but if you want more than one person or want them to move around for emotional effect, you need to specify where you want the image on the screen.
There are 7 default positions you can place an image in. Topleft, top(center), topright, left(bottom left), right(bottom right), center(the default), and truecenter(the middle of the screen with no respect to the bottom edge of the screen or the bottom edge of the image). You can also define your own positions, but that's outside of the scope of this basic tutorial.(we'll come back to it when we do displayables in depth and animation language.)
So! To tell the system to place it at another position other than default, this is how it is written:
show Danny smile at right
It's that simple.
This is all well and good Ren'PyHelpDesk, but my pictures just show up on the screen. It's kinda jarring and ugly. What do I do?
The answer to your problems is transitions.
There are a number of pre-defined transitions, you can find the full list here, but I'll be using Dissolve and Fade as examples. In order to use transitions, you have to use the "with" statement to tack on the transition to the image.
Examples:
scene bg meadow with fade
show Danny frown with dissolve
Both of those work to display images to the user with the transitions in question.
A note about transitions, if you place both the bg image and a character image together with the same transition they will come in at the same time with the same transition. If you don't want that to happen, you can either place them on different lines or use the "None" statement.
Examples:
scene bg meadow
show Danny frown
with dissolve
#This makes them both show up at once with dissolve.
scene bg meadow with fade
show Danny with dissolve
#This tells the interpreter that they each are different.
scene bg meadow
with None
show Danny frown
with dissolve
#This shows the scene with no transitions, but the character image with dissolve.
Take a look at the pre-defined list in the link to see all the ones you have to work with without making one yourself. It also describes what the transitions look like/do. Fade(pre-defined) fades the old image to black before bringing in the new image. Dissolve takes half a second to dissolve the old screen into the new screen. Play around with them and others to get a feel for how they work and look.
Finally, there is a way to customize transitions, but once again, that's out of the scope of this tutorial.
One last thing, let's put this all together with the info from the previous tutorial about Characters and Text.
image bg house = "homebase.png"
image bg school = "wishitweresummer.png"
image bg mall = "hangoutspot.png"
image Danny frown = "Dan_sad.png"
image Danny smile = "Dan_happy.png"
image Danny blush = "Dan_blush.png"
define D = Character("Danny", color="#00008f", image="Danny")
label start:
scene bg house
show Danny frown at right
D blush with fade "I can't believe I live here! It's so embarrassing..."
D "I mean, who wants to live in a place with a giant neon sign on the side?"
D frown at left with fade "I sure don't!"
That's everything, if you want to know how it looks without the image tags in the character object, and/or without the character object at all...
label start:
scene bg house
show Danny frown at right
"Danny" "I can't believe I live here!"
show Danny blush with fade
extend "It's so embarrassing..."
"Danny" "I mean, who wants to live in a place with a giant neon sign on the side?"
show Danny frown at left with fade
"Danny" " I sure don't!"
That's more work(3 more lines), and that was just a few lines and images. I even had to use a different tactic to get the blush to show up during the lines of dialogue like the original. This is with short names too. try to imagine "Danny night happy" having to be typed over and over whenever you needed it in script?(the tag system works to find the closest image to the one described so if you already had a Danny "night" picture up there, when you replaced it you'd only have to specify "happy" instead of the whole thing.)
The next two tutorials, following tradition, are going to be step-by-step tutorials. We'll then come back to Music, Audio, Movies and Voice, and finally finish the basic tutorials with Ending Your Game and packaging it for distribution.
Alright everyone this was another big one, and we haven't even scratched the surface of what you can do with images! I hope you all found this useful, and remember, if your code won’t compile and you don’t know why? Who ya’ gonna call? The Ren’Pyhelpdesk!
#Ren'Py#RenPy#thehelpdesk#renpyhelpdesk#tutorials#RenPy: Images#RenPy: Transitions#RenPy: Image Positions#keyword: image#keyword: hide#keyword: scene#keyword: show
49 notes
·
View notes
Note
Is it actually possible to transfer a save file (with cache infomation and the like) into another game? Example: Mass Effect 2/3, how it grabs information from the previous games to unlock/lock content in this game based entirely on decisions made previously. Thanks!
Hey there anon, thanks for phoning in!
What you’re looking for is persistent data. Some things can be saved as persistent data and so exist not only between save files for the same game(and so can be used to unlock routes), but also between games. You can program your new game to look for information from its prequel and boot that into its programming to change its default states.
The specifics for how to use persistent data is found here: Persistent Data
I’ll give you a basic overview though so you can get started.
Persistent data is an object that is unrelated to specific parts of your game. A new object is called up using the keyword python to create a block(if you’re creating a bunch of persistent data at once) or a single dollar sign for a line of code. Then, you would tell the interpreter that this is an instance of the persistent data type. To do so you’d write it like this:
Example:
$ persistent.secret_agent = False
In this case, I’m using it as a flag that represents if the player chose the “career” of secret agent. Later in the game, if the player does chose to be a international man of mayhem, you’d change the flag like so:
Example:
$ persistent.secret_agent = True
You can then have it tested with a conditional somewhere else in the game or the next. Say they start out with different stats if they were a secret agent in the last game.
label initialstats: if not persistent.secret_agent: $ creation_stats = 15 jump creationscreen $ creation_stats = 25 jump creationscreen
You can scale this of course, such that people who played the game through before with any archetype get more points. This only works though between saves of a single game. If you want to have it work between two different games though, you have to use Multi-persistent Data. The Multipersistent data has to go in an initial python block.
Example:
init python: mp = MultiPersistent(”007″)
$ mp.secret_agent = True$ mp.save()
The stuff in parenthesis after the new instance of the MultiPersistent Class is the “key”. Everything saved to this particular MultiPersistent is attached to that key. The save function also saves the data to the local computer’s disk, it has to be used or it won’t save.
In the next game when you want to load in the old data you’d create a new MultiPersistent instance with the same key. This way the computer can not only access what’s already there, but add to it new stuff from the current game.
Example:
init python: mp = MultiPersistent(”007″)label start: …
label charactercreation: if mp.secret_agent: jump loadoldcharacter else: jump makenewcharacter
Easy peasy! I hope this answered your question. Remember Ren’Py fans, if your code won’t compile and you don’t know why. Who ya’ gonna call? The Ren’Py Help Desk!
#Anonymous#Ren'Py#RenPy#thehelpdesk#renpyhelpdesk#keyword: python#init python#persistent data#multipersistent data
23 notes
·
View notes