Ren'Py Loop

dakila

New Member
Mar 31, 2018
9
0
Hello :)

I need your help, because i dont really understand the loop function.
This is what i want to do:


(lt dont change
default lt1 = "name1"
....
default lt7 = "name7"
default lt10 = "name10"

(mt will change the position randomly after next day)
default mt1 = "name7"
....
default mt10 = "name3"

default te1 = ""

(this should find out with a loop if its the same name, if lt7 is reached it should trigger and copy lt7 to te1)
for i1 in range (1,10):
if mt1 == lt[i1]:
$ te1 = lt[i1]


I know there is something wrong, so i need help :)
Thank you!
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,192
I need your help, because i dont really understand the loop function.
It... loop ?

I know, my answer look silly, but it's because what you are asking for have nothing to do with the understanding of the loop function. As far as I can judge, you understood it correctly, the problem come from everything else.


(this should find out with a loop if its the same name, if lt7 is reached it should trigger and copy lt7 to te1)
for i1 in range (1,10):
if mt1 == lt[i1]:
$ te1 = lt[i1]

I know there is something wrong, so i need help :)
Well, there's many things wrong :
  • for is not a Ren'Py statement ; you can only use it in a Python block.
  • $ is not a Python thing ; you can only use it in a Ren'Py label or a Ren'Py screen.
  • lt is not a list and do not exist ; therefore lt[i1] do not exist either.

But more that this, it's the whole logic that is wrong ; as I implied above, the loop is in fact the only thing correct here.

As I understood it:
lt is supposed to be a constant list ; what it have at the start of the game will stay, and stay in this order, during the whole game.
As for mt, it's supposed to be a list that have the same content than lt, but in an order that randomly change time to time.
And I have not a single clue regarding what te is supposed to be.

So, firstly what you should do is effectively use a list, and not a suit of variables: define lt = [ "name1", "name2", ... "nameN" ]
Just be aware that list indexes starts at 0, therefore it's lt[0] that give you "name1".

Secondly, you copy this list into mt: default mt = lt[:]
You now have two different lists that happen to have the exact same content.

Thirdly, when you want to change the order of mt, you just shuffle it: renpy.random.shuffle( mt )
You now have two different lists that have the same content, but not in the same order. mt is now randomly ordered, while lt still have its original order.
 

dakila

New Member
Mar 31, 2018
9
0
You're right, there are many things wrong, i know. I try to understand how it works and learn how much I can. Can you explain why "for" does not work without python block?
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
Can you explain why "for" does not work without python block?

RenPy itself doesn't have a for command/statement for normal script coding (although it is supported within the screen language).

To do anything like that, requires that you ask python to do it for you. Hence the $ or alternatively python: code blocks.

It should be noted that default is only "create this variable for later use". All default statements are processed by RenPy before the game actually starts. When it's running, they are ignored.

The other thing is that as far as I can see, you aren't actually creating variables that python can loop around.
For example, you have lt1 thru lt10. But those are 10 separate variables that are completely independent of each other. You as a human can see the connection, but programming languages can only follow their internal rules.

If you check my .sig you'll see a link to a guide I wrote for lists. I'm imagining something that might look more like:

Python:
default lt_list = [ "Name1", "Name2", "Name3", "Name4", "Name5", "Name6", "Name7", "Name8", "Name9", "Name10" ]
default mt_list = []

label start:

    scene black with fade
    "*** START ***"

label new_day:

    $ mt_list = lt_list[:]
    $ renpy.random.shuffle(mt_list)

    python:
        for i in range(10):
            renpy.say("Nobody", "Person #" + str(i) + ", is " + mt_list[i] + " today.")

    "*** THE END ***"

    return

Some further explanations...

$ mt_list = lt_list[:] is effectively "copy lt_list to mt_list".
Without the [:], python only creates a reference called mt_list which points at lt_list.
Think of it like creating an alias rather than creating a new object/variable.
The brackets are to specify "from" and "to" when copying a list. If you omit the "from" number, if defaults at the first item. If you omit the "to" number, it defaults to the last item. So [:] can be thought of as "from first to last". In this case, it's handy way to force python to create a new variable rather than just a reference.
The problem of randomly shuffling a reference is that BOTH variables/lists are linked, so both would get shuffle (at least from your point of view).

renpy.random.shuffle randomly shuffles (and overwrites) an existing list. It's why I'm copying lt_list to mt_list before doing anything else with it. Though it really depends on whether you need separate randomized and unrandomized lists.

$ is effectively "do python command".
python: is also "do python command", except it processes all the lines below that are part of the code block (the indenting).
Generally you'd use $ for a single line or a couple of lines (with multiple lines starting with $).
When you have more lines, perhaps 4 or 5+, you can consider using python: instead.

I used both here for only 2 lines just to show the difference.
Alternatively, the for loop could have been written as a single line as:
$ for i in range(10): renpy.say("Nobody", "Person #" + str(i) + ", is " + mt_list[i] + " today.")
... or the whole lot could have been a single python: block.

Python lists start at #0, which is common to most programming languages these days. So the first entry in this code would be lt_list[0] and the last one would be lt_list[9]. Still 10 entries, just counting from 0 to 9 instead of 1 to 10.

renpy.say is just a way of printing stuff for testing, as if a character called "Nobody" is speaking dialogue. It's a bad way of doing it in a real game, because commands run by python are ignored by RenPy's rollback system. I'm imagining the list of names being part a screen somewhere, which is much better supported by RenPy.

I will add that doing stuff directly in python and processing lists and stuff like that is fairly "intermediate" level RenPy knowledge. It feels like you might be trying to bite off more than you can chew at this early stage. Which shouldn't stop you trying. I merely offer caution.
 
Last edited:

dakila

New Member
Mar 31, 2018
9
0
First of all, thank you very much for all the information. I know that RenPy is not even close to Python, this is like a userfriendly "interface" with the screens etc, i really like it, but also i hate it because of the "basic" functions. So i need to find out a better way than python single and block codes. I find a way to work without the "for" function, but the lists is a good idea, also the shuffle function. Didn't know that before.