Rhapsy wrote: ↑Thu Mar 07, 2024 6:51 pm
1_What commands should I execute to unlock pages of new characters in the game?
Example. The command is already written in the Script, but I want it to remain blocked or invisible in the game until the protagonist meets that character.
One way is to add more characters at some point in the script. To add an element to a list, usually do
my_list.append(new_element). E.g.:
Code: Select all
eel "Hello! My name is Eel."
$ characters.append({ID: "eel", "name": "Eel", "desc": "Some guy with long hair.", "points": 4})
Another way is to add some parameter to characters, like "hidden" or "show", and filter the list by that parameter when showing screens etc.:
Code: Select all
define characters = [
{ID: "cat", "name": "Kitty", "desc": "...", "points": 2, "show": True},
{ID: "dog", "name": "Doggy", "desc": "...", "points": 6, "show": False},
]
Here "cat" has "show" == True to show it since the start. And "dog" would be hidden until you set its "show" to True:
Code: Select all
dog "Hello! I'm the famous Doggy!"
$ characters[1]["show"] = True
From that moment "dog" character would be shown.
Note:
You see here "dog" character is referred to as
characters[1], because
1 is its index in the list. I.e. it's second, right after "cat".
It's easy to address a list element like that, but it's not very convenient to remember maybe dozens of indexes for characters. And if you happen to add or delete one from the middle, the rest of the indexes change, and it can become a nightmare to maintain such code.
Therefore it would be better if you could use something like
char["dog"] instead. Hence you can make "characters" a dictionary instead of a list. Then elements would be addressed by "key" instead of "index".
But to show screens "previous" and "next", a list with simple indexes is more convenient.
As the best solution, you can either
(1) Use a dictionary and get a list (converted from dictionary) when needed.
(2) Or use a function to access a list element containing proper ID. For example:
Code: Select all
init python:
def char(char_id):
for n in range(0, len(characters)):
if characters[n][ID] == char_id:
return characters[n]
Then instead of
$ characters[1]["show"] = True you could write
Note first the parentheses there, not square brackets.
Now to filter list elements with certain fields ("show" True or False), we can either
(1) change our code by adding checks and skipping hidden elements; But that's a bit complex.
(2) Or when we need filtered "characters", we use another list, a filtered one.
E.g. we can create such list before showing characters' screens. (Or when we change a character's visibility).
Code: Select all
label char_list:
$ _return = 0
# Create the filtered list, using so called list comprehension:
$ ch = [x for x in characters if x["show"]]
# And in the screen, use list "ch" instead of "characters"
It seems that it's easier to add new characters dynamically (1st approach here), but if there are different branches and different conditions to start showing characters, the 2nd approach (with "show" parameter) might be more reliable (bug-resilient). I think.
2_If the protagonist of the game reaches maximum affinity with a character and I would like to add a special event when that happens.
What commands should I write here?
Yeah, it's a question that might deserve a separate topic.
I mean, if you don't know at which exactly point in your story this would happen, and want to put some effect there, it's one thing.
But if you just want to show the character screen differently when "points" are maxed, use "if" or maybe "showif":
https://renpy.org/doc/html/screens.html#if
https://renpy.org/doc/html/screens.html ... -statement