I am an idiot, Please Help Me Learn Ren'Py.

That’s great news!

It will happen when you call tick enough to roll over to the next day. See this post for some detail. If you don’t have a nextDay() function, this line will advance to the first period of the next day:

$ tick(len(time_map) - time)

“Semi-random” is the key phrase here. There are three basic techniques: roll-of-the-dice, draw-from-a-deck, and least-recently-used.

Roll-of-the-dice is the simplest.

  • Advantages: If you just want random flavour, and aren’t concerned about getting the same option several time in a row, it’s great.
  • Disadvantages: the number of options is fixed (or very hard to change) so it doesn’t work well if new options become available, or old ones disappear. If an option is critical to advancing the plot it may never be chosen.
$ rnd = renpy.random.randint(1,3)
if rnd == 1:
    "Treadmill"
elif rnd == 2:
    "Weights"
else:
    "Stepper"

Draw-from-a-deck is like drawing cards from a shuffled deck.

  • Advantages: guarantees all options will be seen before any is repeated, can handle new options and disappearing options. (actually used in electronic slot machines to guarantee odds)
  • Disadvantages: New options not (easily) added until deck is empty. Possibly too predictable?
default gymDeck = []

label gym:
    if len(gymDeck) == 0:
        # Add options in when the deck is empty.
        $ gymDeck.update([1, 2, 3])        # Add options 1, 2, and 3
        if anneMet:
            $ gymDeck.append(4)            # If anne has been met add her as option 4
    # Pick one card from the deck and discard it
    $ rnd = renpy.random.choice(gymDeck)  
    $ gymDeck.remove(rnd)
    if rnd == 1:
        "Treadmill"
    elif rnd == 2:
        "Weights"
    elif rnd == 3:
        "Stepper"
    else: # rnd == 4
        "Anne"

Least-recently-used

  • Advantages: guarantees an option isn’t repeated twice in a row, can handle new options and disappearing options
  • Disadvantages: a critical option that advances the plot may still not get chosen, as picks are random, but still more likely than roll-of-the-dice
default lastGym = None

label gym:
    $ options = [1, 2, 3]
    if anneMet:
        $ options.append(4)                # If anne has been met add her as option 4
    if lastGym != None:
        $ options.remove(lastGym)          # Remove the one picked last time
    $ rnd = renpy.random.choice(options)   # Pick one
    $ lastGym = rnd                        # Remember it for next time
    if rnd == 1:
        "Treadmill"
    elif rnd == 2:
        "Weights"
    elif rnd == 3:
        "Stepper"
    else: # rnd == 4
        "Anne"

The draw-from-a-deck and least-recently-used don’t have to work with numbers. You can add labels instead and use jump expression or call expression. For example (using jumps):

default gymDeck = []

label gym:
    if len(gymDeck) == 0:
        # Add options in when the deck is empty.
        $ gymDeck.update(["gymTreadmill", "gymWeights", "gymStepper"])        # Add options
        if anneMet:
            $ gymDeck.append("gymAnne")            # If anne has been met add her as an option
    # Pick one card from the deck and discard it
    $ rnd = renpy.random.choice(gymDeck)  
    $ gymDeck.remove(rnd)
    jump expression rnd                            # Jump to picked label

label gymAnne:
    "Anne"
    jump main

label gymStepper:
    "Stepper"
    jump main

label gymTreadmill:
    "Treadmill"
    jump main

label gymWeights:
    "Weights"
    jump main

In Tramp I use least-recently-used more often than not (with some draw-from-a-deck), and have classes to make these operations simpler. Tramp’s least-recently-used can give options different weights and priorities and eliminate one or more recently used options.

Note: On the whole I’d recommend using call/return over jump in a life-sim. See Some notes about RenPy.