(SOLVED!) Livecomposite Minigame - Random Rewards on Click

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Wudgeous
Regular
Posts: 58
Joined: Tue Apr 30, 2019 5:59 am
Tumblr: herotome
itch: wudgeous
Contact:

(SOLVED!) Livecomposite Minigame - Random Rewards on Click

#1 Post by Wudgeous »

Hi all! I'm still a self-taught going-on-intermediate coder and I'm not quite at my wit's end. What I've built so far as been from researching the documentation and youtube videos, and I'm at the point where I'd like to ask for some insight.

I could be looking in the wrong places or using the wrong search terms - in which case, some guidance would be deeply appreciated.

Context
The concept is this:
You play as a friendly neighborhood pal. In your free time, unscripted and offscreen, you are going around doing Good Deeds and increasing your Renown as a result.

Image

This is represented with a LiveComposite map, and a number of random, regenerating, clickable hotspots.


Image

When you click a hotspot, you get a message with some flavor text and points. The hotspot will then deactivate for a certain amount of IRL time, so players can't farm infinite points by spam clicking.

The purpose of this minigame is to reward the player with bonus points in exchange for checking into the minigame's screen occasionally. The bonus points are not required to win in the main game, but they can be used to unlock special options later on.


This minigame is similar to the Spaceship minigame in Mystic Messenger, and I am sure several cookie clicker games utilize this mechanic.



Part One of my Dilemma is This:
The problem I have is with the "random" command. In my first attempt, I used the code below:

Code: Select all

define RMC = renpy.random.choice(['You helped an old woman carry groceries! \n \n Earned 5 Reputation.\n \n', 'You saved a cat from a tree! \n \n Earned 10 Reputation.\n \n', 'You tied your shoes. Aww. \n \n Earned 1 Reputation.\n \n'])
Using this, all three hotspots will all display ONE random message. In the above example, no matter where I click, I am always helping an old woman carry groceries. I'd have to completely close out of the game to get any of the other choices (saving a cat or tying shoes).

I'd like the code to randomly choose a message EACH time I CLICK, not each time the player quits the game.


One of my Attempts at a Solution is This:
I thought, maybe I'll just create different sets of messages, so each hotspot is guaranteed to be different from one another. This ends up looking like....

Code: Select all

screen MapClicker():
    tag menu
    modal True

    imagemap:
        ground "Ground.jpg"
        hover "Hover.jpg"
        hotspot (262, 117, 77, 73) action Show("ReputationGet_Set1")
        ##This links the hotspot button to the first list of messages.
        hotspot (469, 363, 71, 74) action Show("ReputationGet_Set2")
        ##This links the hotspot button to the second list of messages.
        hotspot (882, 575, 398, 225) action Hide("MapClicker")
        ##This exits the minigame, resuming the main game.
    frame:
        pass
        
define CivillianRMC_Set1 = renpy.random.randint(1,6)
define CivillianRMC_Set2 = renpy.random.randint(7,12)


screen ReputationGet_Set1(): 
    modal False
    zorder 200

    frame:
        xalign 0.5 yalign 0.5
        xsize 500 ysize 350
        xpadding 50 ypadding 50
        vbox:
            xalign 0.5 yalign 0.5
            if CivillianRMC_Set1 ==1:
                text "You called your family. They hope you’re doing well. \n \n Earned 10 Reputation.\n \n"
            elif CivillianRMC_Set1 ==2:
                text "You folded your clothes. Great job! \n \n Earned 2 Reputation.\n \n"
            elif CivillianRMC_Set1 ==3:
                text "You tied your shoes. Aww. \n \n Earned 1 Reputation.\n \n"
            elif CivillianRMC_Set1 ==4:
                text "You helped an old woman carry groceries! \n \n Earned 5 Reputation.\n \n"
            elif CivillianRMC_Set1 ==5:
                text "You saved a cat from a tree! \n \n Earned 10 Reputation.\n \n"
            elif CivillianRMC_Set1 ==6:
                text "You took a lint-roller to your clothes today. Thanks, cat. \n \n Earned 1 Reputation.\n \n"
            else:
                text "Bad luck! You didn't do anything useful..."
                pass
            hbox:
                xalign 0.5 yalign 0.5
                textbutton "OK" action [Hide("ReputationGet_Set1"), Show("MapClicker")]

screen ReputationGet_Set2(): ##Possibly make/have four of these screens....
    modal False
    zorder 200

    frame:
        xalign 0.5 yalign 0.5
        xsize 500 ysize 350
        xpadding 50 ypadding 50
        vbox:
            xalign 0.5 yalign 0.5
            if CivillianRMC_Set2 ==7:
                text "You picked a new background picture on your phone. \n \n Earned 1 Reputation.\n \n"
            elif CivillianRMC_Set2 ==8:
                text "You decided to stop biting your nails. Here's hoping you can commit! \n \n Earned 2 Reputation.\n \n"
            elif CivillianRMC_Set2 ==9:
                text "You did the dishes! \n \n Earned 3 Reputation.\n \n"
            elif CivillianRMC_Set2 ==10:
                text "You watched an inspiring video. \n \n Earned 3 Reputation.\n \n"
            elif CivillianRMC_Set2 ==11:
                text "You made a motivational instagrum post. You got a lot of likes! \n \n Earned 10 Reputation.\n \n"
            elif CivillianRMC_Set2 ==12:
                text "Selfie time! \n \n Earned 8 Reputation.\n \n"
            else:
                text "Bad luck! You didn't do anything useful..."
                pass
            hbox:
                xalign 0.5 yalign 0.5
                textbutton "OK" action [Hide("ReputationGet_Set2"), Show("MapClicker")]
        

And it works! Since each hotspot pulls from a different set of messages, there are no more duplicates. So the only problem remaining, is the way ren'py will only make a random choice each time I exit the game, rather than each time I click... However, if the hotspot times out/hides (say, for two hours before reappearing) maybe the cooldown will allow the game to choose a new message?

I have no idea how to move forward in coding cooldowns. The hotspots will need to be hidden (or disabled), and then reappear after a certain amount of time. Hopefully with a new, randomly chosen message.

Perhaps some of you have created something similar in the past? I'm looking through the timed menu documentation (yes yes, it's out of date), but I'm blanking on how I can use it in this situation...


This was fairly tricky to explain, but I did my best. Please don't hesitate to ask for more clarity if I've skimmed over something. Thoughts? Alternatives? Links? Examples? Or maybe you have a better, tidier way of doing things? I'll love you forever.
Last edited by Wudgeous on Tue Jan 07, 2020 10:56 am, edited 1 time in total.
Have confidence. Let go of perfectionism. I love you!
Image
A superhero dating sim in fresh hot development!


You can also keep up with me on Twitter and Itch!

User avatar
Per K Grok
Miko-Class Veteran
Posts: 882
Joined: Fri May 18, 2018 1:02 am
Completed: the Ghost Pilot, Sea of Lost Ships, Bubbles and the Pterodactyls, Defenders of Adacan Part 1-3, the Phantom Flyer
itch: per-k-grok
Location: Sverige
Contact:

Re: Livecomposite Random Rewards on Click (Minigame)

#2 Post by Per K Grok »

Wudgeous wrote: Mon Jan 06, 2020 3:13 pm Hi all! I'm still a self-taught going-on-intermediate coder and I'm not quite at my wit's end. What I've built so far as been from researching the documentation and youtube videos, and I'm at the point where I'd like to ask for some insight.

I could be looking in the wrong places or using the wrong search terms - in which case, some guidance would be deeply appreciated.

----------

And it works! Since each hotspot pulls from a different set of messages, there are no more duplicates. So the only problem remaining, is the way ren'py will only make a random choice each time I exit the game, rather than each time I click... However, if the hotspot times out/hides (say, for two hours before reappearing) maybe the cooldown will allow the game to choose a new message?

----

You need to run the random setting each time a spot is chosen.

As far as I can see you only run it once (when you define the variable). The variable then remains the same throughout the game.

So, you could set the variable right before calling the screen, or in the screen itself.

$ CivillianRMC_Set1 = renpy.random.randint(1,6)

philat
Eileen-Class Veteran
Posts: 1912
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Livecomposite Random Rewards on Click (Minigame)

#3 Post by philat »

You're in luck as it's the new year and things have been very slow at work so I am quite bored. Here, a working example of random clicking (you can throw this in a new project and run it).

I didn't bother with the timed part because I don't know what you want to do, exactly. That said, you can search the forum for 'real time' for examples of real-time gating (e.g., viewtopic.php?t=48299#p478576) or simply gate calling the MapClicker screen with a variable and timer.

Code: Select all

default rep = 0

# static list of possible clicks and reputation points. You could easily extend this concept to get a random set of coordinates for a hotspot, etc. 
define RandomClickQuestsSeed = [
    ("You called your family. They hope you’re doing well. \n \n Earned 10 Reputation.\n \n", 10),
    ("You folded your clothes. Great job! \n \n Earned 2 Reputation.\n \n", 2),
    ("You tied your shoes. Aww. \n \n Earned 1 Reputation.\n \n", 1),
    ("You helped an old woman carry groceries! \n \n Earned 5 Reputation.\n \n", 5),
    ("You saved a cat from a tree! \n \n Earned 10 Reputation.\n \n", 10),
    ("You took a lint-roller to your clothes today. Thanks, cat. \n \n Earned 1 Reputation.\n \n", 1)
    ]

# changeable list that we will shuffle for randomness
default RandomClickQuests = []

screen MapClicker():
    vbox:
        for i in range(min(3, len(RandomClickQuests))): # show no more than the first three quests in the list
            textbutton "Random" action SetVariable("rep", rep+RandomClickQuests[i][1]), Return(RandomClickQuests[i]) # Return() returns the tuple, which is then passed to the Rewards screen

screen Rewards(r):
    on "show" action RemoveFromSet(RandomClickQuests, r) # get rid of "used" quests (the r here refers to the passed-in tuple)

    vbox:
        xalign 0.5
        yalign 0.5
        text r[0]
        textbutton "OK" action Return()

screen rep():
    text "Reputation: "+str(rep) xalign 0.9

label start:
    show screen rep
    pause

label RandomizeClickQuests:
    $ RandomClickQuests = RandomClickQuestsSeed[:] # copy the seed list
    $ renpy.random.shuffle(RandomClickQuests) # shuffle the copied list (since it's shuffled, by cycling through it we get a random result each time)

label CallRandomClickScreen:
    if len(RandomClickQuests) > 0: # if there are random quests left
        call screen MapClicker
        call screen Rewards(_return) # _return is where items returned by Return() are stored
    else: # if not, re-copy and re-shuffle
        jump RandomizeClickQuests
    jump CallRandomClickScreen

User avatar
Wudgeous
Regular
Posts: 58
Joined: Tue Apr 30, 2019 5:59 am
Tumblr: herotome
itch: wudgeous
Contact:

Re: Livecomposite Random Rewards on Click (Minigame)

#4 Post by Wudgeous »

Per K Grok wrote: Mon Jan 06, 2020 5:52 pm You need to run the random setting each time a spot is chosen.

As far as I can see you only run it once (when you define the variable). The variable then remains the same throughout the game.

So, you could set the variable right before calling the screen, or in the screen itself.

$ CivillianRMC_Set1 = renpy.random.randint(1,6)
You absolute wizard, Per K Grok, thank you so much for the straightforward solution and explanation. I put the variable in the screen itself and it works like a charm. (Also, why didn't I think of that? 🤦 For some reason I didn't connect the dots that the random command is, in fact, setting a variable.)

This solution does eliminate the need have multiple set lists, and it's even further eliminated with tech druid philat's working example. I am the luckiest luciano in the living world.

I recognize elements of working example from Doki Doki's poem game, which also pulls messages from a pre-written list. I understood the function well enough when I decompiled it in the past, but my attempt to use it was... far less successful. So, I bow deeply to you for this code plus helpful notes - I'll be parsing through it this evening.

I'll mark this as "solved," since this is now a passable minigame. I will try to update with findings for the timed feature though, once I get that figured out. <3 Thank you both of you, you've helped me learn so much.
Have confidence. Let go of perfectionism. I love you!
Image
A superhero dating sim in fresh hot development!


You can also keep up with me on Twitter and Itch!

User avatar
Wudgeous
Regular
Posts: 58
Joined: Tue Apr 30, 2019 5:59 am
Tumblr: herotome
itch: wudgeous
Contact:

Re: (SOLVED!) Livecomposite Minigame - Random Rewards on Click

#5 Post by Wudgeous »

Before I take a stab at the timed feature, I did manage to figure out how to create random hotspot coordinates. No new questions, just wanted to update the thread for anybody in the future who might be struggling with something like this. (: (That "anybody" has been "me" many, many times).


I added these three sections to philat's lovely code. Idk that it's perfect, but it works.

Code: Select all

##Below are eleven possible (x,y) positions for the hotspots to appear. You can have as many or as few as you like, but in this example, you'll need more than three. 
##The actual combinations will be shuffled, too.
define RMCCoordinatesSeed = [
    (232, 89),
    (262, 102),
    (285, 190),
    (300, 200),
    (338, 283),
    (369, 333),
    (401, 363),
    (428, 378),
    (456, 400),
    (481, 490),
    (500, 567)
    ]
default RMCCoordinates = []

Code: Select all

screen MapClicker():
    vbox:
        for i in range(min(3, len(RandomClickQuests))): # show no more than the first three quests in the list
            textbutton "Random" action SetVariable("rep", rep+RandomClickQuests[i][1]), Return(RandomClickQuests[i]) # Return() returns the tuple, which is then passed to the Rewards screen
                pos(RMCCoordinates[i])  ##uses three of the (x,y) positions from the RMCCoordinatesSeed

Code: Select all

label RandomizeClickQuests:
    $ RandomClickQuests = RandomClickQuestsSeed[:] # copy the seed list for quests
    $ renpy.random.shuffle(RandomClickQuests)
    $ RMCCoordinates = RMCCoordinatesSeed[:] # copy the seed list for coordinates
    $ renpy.random.shuffle(RMCCoordinates)
Have confidence. Let go of perfectionism. I love you!
Image
A superhero dating sim in fresh hot development!


You can also keep up with me on Twitter and Itch!

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot], piinkpuddiin