Ren'Py Trouble with random encounters

Malachite1789

Member
Dec 25, 2019
177
260
Ok i have a new random number problem if anyone wants to help a poor confused old scrub that's just starting out :)

I'm trying to make a random encounter system and i've got it mostly working but it's throwing an error whenver Autoreload kick's in and also blocking auto saves .

SPOILER: This is the error

and this is the code that is causing it
Code:
label randomencounterengine: #hurhur engine my arse
python:
import random

$randomnum = random.randint(1,3) #(randomize random encounters)

if randomnum == 1:

jump slimefight1
if randomnum == 2:

jump gnollfight1
if randomnum == 3:

jump skeletonfight1
I know it's not exactly elegant but it works. (sort of)

my only guess is that it's storing the random number and that's causing the error? maybe...
is there maybe a way to clear the stored number (if that's what's happening) after the event is over?
i've tried googling it but no luck.

*Edit* after thought could it be the python bit at the begining. I know from experimenting that i need that for it to roll a different number each time it triggers (Because renpy.random.randint only rolls the first time it's triggered then gives the same result every time). If that is the problem is there an end type statement to stop the python after it's done it's job (Maybe. I'm really just guessing at this point.)
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
(Because renpy.random.randint only rolls the first time it's triggered then gives the same result every time).

This is a deliberate choice by the RenPy team.

It's still random numbers, but those random numbers are fixed as/before the random is processed.

The intent is to stop people rolling back and then playing forward to get a more favorable result. After all, what's the point of a 10% random chance, if the player can keep rolling back to make it effectively 100%? It also prevents " ", where the player reloads from an earlier save once they realize they've gotten the "wrong" result.

I know it feels counter-intuitive that the random number appears to not be random. But in reality... it's still a random number like any other - but with extra safeguards to avoid cheating.

Edit: I should probably add that I would recommend using the standard instead of the whole import random, blah, blah. Yeah, it "feels" more random to do it the other way - but the intended functions are generally better suited for RenPy games. Unless your game is so different that I'm wrong. Your game... your choice.
 
Last edited:
  • Like
Reactions: Malachite1789

Malachite1789

Member
Dec 25, 2019
177
260
Ok i *think* I've found my error I looked at some examples and they all used init python instead of just python. so i put added that and the errors stopped so i'm just gonna assume that was the problem and go sleep because 2 am. (If anyone can confirm or explain why this is the cause i would love to read it in the am. G'night all
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,978
16,234
(If anyone can confirm or explain why this is the cause i would love to read it in the am. G'night all
Well...

Ren'Py is robust, and can deal with many errors. Among them, there's the lack of indentation when you use script statements that should be used in label[icode]s only.. Globally, when it happen, Ren'Py create an anonymous label, that will be played at the end of the previous label... if there's no branching before it. And it happen that [icode]python is one of them.

Therefore with:
Code:
label whatever:
    scene whatever
    "some dialog line"

python:
    import random
The python block will be proceeded after "some dialog line", and only at this moment. But:
Code:
label whatever:
    scene whatever
    "some dialog line"
    jump somewhereElse

python:
    import random
The python block will never be proceeded.

As for init, it's a particular statement that, like label is to use at 0 level of indentation. It will then create an independent block that will be proceeded at init time.
It take an optional argument, python that tell Ren'Py that the content of the block will be purely Python script.

In the end, as you wrote it, the module random was not always imported, preventing code like random.randint( whatever ) will throw a NameError exception.
When you changed the block into init python:, it made the importation happen every time right before Ren'Py display the main menu for the first time.
 
  • Like
Reactions: Malachite1789

Malachite1789

Member
Dec 25, 2019
177
260
Well...

Ren'Py is robust, and can deal with many errors. Among them, there's the lack of indentation when you use script statements that should be used in label[icode]s only.. Globally, when it happen, Ren'Py create an anonymous label, that will be played at the end of the previous label... if there's no branching before it. And it happen that [icode]python is one of them.

Therefore with:
Code:
label whatever:
    scene whatever
    "some dialog line"

python:
    import random
The python block will be proceeded after "some dialog line", and only at this moment. But:
Code:
label whatever:
    scene whatever
    "some dialog line"
    jump somewhereElse

python:
    import random
The python block will never be proceeded.

As for init, it's a particular statement that, like label is to use at 0 level of indentation. It will then create an independent block that will be proceeded at init time.
It take an optional argument, python that tell Ren'Py that the content of the block will be purely Python script.

In the end, as you wrote it, the module random was not always imported, preventing code like random.randint( whatever ) will throw a NameError exception.
When you changed the block into init python:, it made the importation happen every time right before Ren'Py display the main menu for the first time.
Thank you for the explanation :)