Ren'Py Need help fixing my sex system

Jun 11, 2020
59
130
The sex system in my game is currently a loop of two labels. The first contains the player's choices and allows them to change the variables of the sex. The second label it leads to contains a function that causes the npc to randomly generate an action based on their traits and the current variables, take that action and change the variables. Then it leads to back to the first label and the cycle continues until the scene ends. I think this is the basics of how sex systems work in these sorts of games.
My problem is that the second label in the loop isn't doing anything. This is what it looks like:


label sbo_suck:
$ sb_suck_action(y38, y39, tlist)
python:
if sstats.ar1 > 75 and sb_under == 'on':
sstats.ar1 = 75
if sstats.ar0 >= 100:
"Long female orgasm text."
$ sstats.ar0 = 0
if sstats.ar1 >= 100:
jump sbo_suck_end
if tlist[0] != 'true':
"[y38[0]]"
"[y39[0]]"
else:
sv "[y38[0]]"
"[y39[0]]"
if sstats.ar1 >= 50:
"You can see the sweat beading on his forehead."
elif sstats.ar1 >= 70:
"You hear his breath hitched in arousal."
elif sstats.ar1 >= 90:
"He's panting rapidly now."
else:
pass
python:
if y39[0] == '2':
sstats.ar0 += 2
elif y39[0] == '3':
sstats.ar1 += 3
elif y39[0] == '4':
sb_belt = 'open'
elif y39[0] == '5':
sb_pants = 'open'
sb.stats.cock_seen = 'yes'

The last few lines of variables determine whether his pants and underwear are on and if you've seen his cock before, respectively. y38, y39 and tlist are three lists that have their values changed in a function.

This is what that function is:
y38 = ["ph"]
y39 = ["ph"]
tlist = [""]

def sb_suck_action(y38, y39, tlist):

suck_list = []
suct_list = []

suck1 = "You catch the movement of his head in your peripheral vision and glance up to see that he's staring intently at your face. His eyes studying every detail. He's quite enjoying having a girl as beautiful as you standing on her knees in front of him."
suck2 = "He runs the fingers of one hand through your hair, slowly tracing from the top to the back of your head. It sends a tingle down your spine."
suck3 = "He slips both hands behind your head and pulls your mouth into his crotch. He gyrates his hips against your face once and then lets go, letting you take the wheel again."

suct1 = "Whores like you were born to slobber on my cock."
suct2 = "Yeah suck it bitch. Suck my rod. Only thing you're good for."
suct3 = "Always happy to see a bitch in her proper place. On her knees."

suck_list.extend([suck1, suck2])

if sb_under == 'on':
suck_list.append(suck3)
suck_list.append(suck19c)
else:
pass

if sb_under != 'on' and pf.attire.bra == None and (sb.personality.boob_pref == pf.appearance.b_size or sb_oral_decision == 'tits') and pf_mouth != 'full' and pf.appearance.b_size != 'flat':
suck_list.append(suck20a)
elif sb_under != 'on' and pf.attire.bra == None and (sb.personality.boob_pref == pf.appearance.b_size or sb_oral_decision == 'tits') and pf_mouth != 'full' and pf.appearance.b_size == 'flat':
suck_list.append(suck20b)
else:
pass


if sb.personality.vulgarity == 'sleazy':
suct_list.append(suct3)

if sb.personality.vulgarity == 'sleazy' and pf_mouth != 'free':
suct_list.extend([suct1, suct2])

if sb.personality.speech == 'talkative':
y38[0] = random.choices([random.choice(suck_list), random.choice(suct_list)], weights=[60, 40], k = 1)[0]
elif sb.personality.speech == 'reticent':
y38[0] = random.choices([random.choice(suck_list), random.choice(suct_list)], weights=[95, 5], k = 1)[0]
else:
y38[0] = random.choices([random.choice(suck_list), random.choice(suct_list)], weights=[75, 25], k = 1)[0]

if y38[0] == suck1:
y39[0] = '1'
tlist[0] = ''
elif y38[0] == suck2:
y39[0] = '2'
tlist[0] = ''
elif y38[0] == suck3:
y39[0] = '3'
tlist[0] = ''

elif y38[0] == suct1:
y39[0] = 't1'
tlist[0] = 'true'
elif y38[0] == suct2:
y39[0] = 't2'
tlist[0] = 'true'
elif y38[0] == suct3:
y39[0] = 't3'
tlist[0] = 'true'

else:
y39[0] = 'Error'

This is a very shortened version. Through testing I've determined that y39[0] does correlate to the value of y38[0] so if the first one is suck1 then the second one will be '1'. The basic action and reaction loop should work but for some reason it doesn't. None of the NPC's actions are having an impact on the variables. Can anyone help me find out why?
 

hiro_san

Newbie
Jul 22, 2023
44
59
try to read your code. unfortunately, I couldn't understand.

if tlist[0] != 'true':
"[y38[0]]"
"[y39[0]]"
else:
sv "[y38[0]]"
"[y39[0]]"

I don't know what the difference is, not sure what 'sv' is used for. if 'sv' has no meaning that means this condition has the same result. why put condition?

You told you have two labels, but I just saw one. and something I think it's quite wrong. example,

if sstats.ar1 >= 50:
"You can see the sweat beading on his forehead."
elif sstats.ar1 >= 70:
"You hear his breath hitched in arousal."
elif sstats.ar1 >= 90:
"He's panting rapidly now."
else:
pass

From this statement, every 'sstats.ar1' with a value more than 50, will be in the first condition. (because you use 'elif').
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,188
This is what it looks like:

Python:
label sbo_suck:
    $ sb_suck_action(y38, y39, tlist)
    python:
        if sstats.ar1 > 75 and sb_under == 'on':
            sstats.ar1 = 75
    if sstats.ar0 >= 100:
        "Long female orgasm text."
        $ sstats.ar0 = 0
    if sstats.ar1 >= 100:
        jump sbo_suck_end
    if tlist[0] != 'true':
        "[y38[0]]"
        "[y39[0]]"
    else:
        sv "[y38[0]]"
        "[y39[0]]"
    if sstats.ar1 >= 50:
        "You can see the sweat beading on his forehead."
    elif sstats.ar1 >= 70:
        "You hear his breath hitched in arousal."
    elif sstats.ar1 >= 90:
        "He's panting rapidly now."
    else:
        pass
    python:
        if y39[0] == '2':
            sstats.ar0 += 2
        elif y39[0] == '3':
            sstats.ar1 += 3
        elif y39[0] == '4':
            sb_belt = 'open'
        elif y39[0] == '5':
            sb_pants = 'open'
            sb.stats.cock_seen = 'yes'
[...]
Python:
        y38 = ["ph"]
        y39 = ["ph"]
        tlist = [""]

        def sb_suck_action(y38, y39, tlist):

            suck_list = []
            suct_list = []
           
            suck1 = "You catch the movement of his head in your peripheral vision and glance up to see that he's staring intently at your face. His eyes studying every detail. He's quite enjoying having a girl as beautiful as you standing on her knees in front of him."
            suck2 = "He runs the fingers of one hand through your hair, slowly tracing from the top to the back of your head. It sends a tingle down your spine."
            suck3 = "He slips both hands behind your head and pulls your mouth into his crotch. He gyrates his hips against your face once and then lets go, letting you take the wheel again."
           
            suct1 = "Whores like you were born to slobber on my cock."
            suct2 = "Yeah suck it bitch. Suck my rod. Only thing you're good for."
            suct3 = "Always happy to see a bitch in her proper place. On her knees."

            suck_list.extend([suck1, suck2])
           
            if sb_under == 'on':
                suck_list.append(suck3)
                suck_list.append(suck19c)
            else:
                pass

            if sb_under != 'on' and pf.attire.bra == None and (sb.personality.boob_pref == pf.appearance.b_size or sb_oral_decision == 'tits') and pf_mouth != 'full' and pf.appearance.b_size != 'flat':
                suck_list.append(suck20a)
            elif sb_under != 'on' and pf.attire.bra == None and (sb.personality.boob_pref == pf.appearance.b_size or sb_oral_decision == 'tits') and pf_mouth != 'full' and pf.appearance.b_size == 'flat':
                suck_list.append(suck20b)
            else:
                pass


            if sb.personality.vulgarity == 'sleazy':
                suct_list.append(suct3)

            if sb.personality.vulgarity == 'sleazy' and pf_mouth != 'free':
                suct_list.extend([suct1,  suct2])

            if sb.personality.speech == 'talkative':
                y38[0] = random.choices([random.choice(suck_list), random.choice(suct_list)], weights=[60, 40], k = 1)[0]
            elif sb.personality.speech == 'reticent':
                y38[0] = random.choices([random.choice(suck_list), random.choice(suct_list)], weights=[95, 5], k = 1)[0]
            else:
                y38[0] = random.choices([random.choice(suck_list), random.choice(suct_list)], weights=[75, 25], k = 1)[0]

            if y38[0] == suck1:
                y39[0] = '1'
                tlist[0] = ''
            elif y38[0] == suck2:
                y39[0] = '2'
                tlist[0] = ''
            elif y38[0] == suck3:
                y39[0] = '3'
                tlist[0] = ''

            elif y38[0] == suct1:
                y39[0] = 't1'
                tlist[0] = 'true'
            elif y38[0] == suct2:
                y39[0] = 't2'
                tlist[0] = 'true'
            elif y38[0] == suct3:
                y39[0] = 't3'
                tlist[0] = 'true'

            else:
                y39[0] = 'Error'
God, even presented correctly (please, use the code tag when you include code in your post), this is so unbearable.
I get that not everyone is a professional, and I've always encouraged amateurs to push their limits, but please guys, starts by something you can handle. Don't try do build a nuclear central when you can barely build a wall.



Why those python blocks ? You clearly know how to use inline python since it's the first line of your label, and you also know that if is also a Ren'Py statement since you use some of them at label level. So why this horrible and useless mix ?

As for the variable names... They should be explicit enough, what is clearly not the case for at least "y38" and "y39". I wonder how long you'll need before confusing both, and hope you'll never have to take a week break, because you'll not even remember the number after it.

And there's this terribly ugly if tlist[0] != 'true':. Of course, some would say that != isn't pythonic, but the real issue is the "'true'". Why do , if it's to see people doing such ugly things ? If you don't want to use True and False values, at least use 0 and 1 like someone civilized.

Constants are constants, declare them with like expected, instead of recreating them every single time the function is called.
By the way, a would be way better than I don't even want to imagine how many suckX and suctX variables you have.

You define y38, y39 and tlist as a list, but declare them as having only one value, and the code you shown clearly don't expect them to have more. What is the interest to have a list for something that is clearly not intended to be one ?

What language do you use to use ? One that isn't really strict, and that clearly pass parameters by reference, but I wonder which one.



As for the answer to your question, there's a major obvious error in your code: You didn't cared to learn the two languages (Ren'Py script and Python) you are using, not even their basis.

So, starts by reading (that is also available on your computer, in a subfolder of the SDK), and learn .


You don't have permission to view the spoiler content. Log in or register now.
 
Jun 11, 2020
59
130
try to read your code. unfortunately, I couldn't understand.

if tlist[0] != 'true':
"[y38[0]]"
"[y39[0]]"
else:
sv "[y38[0]]"
"[y39[0]]"

I don't know what the difference is, not sure what 'sv' is used for. if 'sv' has no meaning that means this condition has the same result. why put condition?

You told you have two labels, but I just saw one. and something I think it's quite wrong. example,

if sstats.ar1 >= 50:
"You can see the sweat beading on his forehead."
elif sstats.ar1 >= 70:
"You hear his breath hitched in arousal."
elif sstats.ar1 >= 90:
"He's panting rapidly now."
else:
pass

From this statement, every 'sstats.ar1' with a value more than 50, will be in the first condition. (because you use 'elif').
Yeah that elif bit is something I missed. Fixed it now. And 'sv' is used to mark a line as character dialogue. Also I got the thing to work with some help from the people on discord. Wish I could delete resolved threads.
 

hiro_san

Newbie
Jul 22, 2023
44
59
Code:
    if xxx >= 50 and xxx < 70:
        "You can see the sweat beading on his forehead."
    elif xxx >= 70 and xxx < 90:
        "You hear his breath hitched in arousal."
    elif xxx >= 90:
        "He's panting rapidly now."
    else:
        pass
Code:
    if xxx >= 50 :
        "You can see the sweat beading on his forehead."
    if xxx >= 70:
        "You hear his breath hitched in arousal."
    if xxx >= 90:
        "He's panting rapidly now."
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,188
Code:
    if xxx >= 50 :
        "You can see the sweat beading on his forehead."
    if xxx >= 70:
        "You hear his breath hitched in arousal."
    if xxx >= 90:
        "He's panting rapidly now."
If xxx is superior or equal to 90, it is also superior or equal to 50 and to 70, and therefore all the three lines will be displayed.

Python:
    if xxx >= 90:
        "He's panting rapidly now."
    elif xxx >= 70:
        "You hear his breath hitched in arousal."
    elif xxx >= 50 :
        "You can see the sweat beading on his forehead."
 
  • Like
Reactions: hiro_san
Jun 11, 2020
59
130
By the way, a would be way better than I don't even want to imagine how many suckX and suctX variables you have.
How would a dictionary help? I have a few dozen of those variables but the way I'm picking the NPC's response is by appending the appropriate variables to a list based on a bunch of parameters and then randomly selecting one from that list. If I used a dictionary, I'd still have to define the variables separately and then add them right? But y38 is the actual text and y39 is sort of like a key so if I used a dictionary would I only need of those?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,188
How would a dictionary help? I have a few dozen of those variables but the way I'm picking the NPC's response is by appending the appropriate variables to a list based on a bunch of parameters and then randomly selecting one from that list. If I used a dictionary, I'd still have to define the variables separately and then add them right?
*sigh*

You don't have permission to view the spoiler content. Log in or register now.

This is the exact copy of the code you shown, it do strictly everything that your code is doing, with less lines of code ; the seven last lines coved all the possibilities for both "suck" and "suct" values, including the ones you haven't copied.

Cherry on the cake, it would have worked fine right from the starts, without the need to pass parameters, return values, and catch the returned values.


But y38 is the actual text and y39 is sort of like a key so if I used a dictionary would I only need of those?
Yes you would only need the key since with it you can easily get the value with a single line. But before this you would need to update a bit your approach, not anymore having two list of text:

You don't have permission to view the spoiler content. Log in or register now.


But in the end, like you already use object, for "sb" by example, there's an even better and simpler way to do all this:

You don't have permission to view the spoiler content. Log in or register now.

Note: I kept the code as you wrote it, in order to make the changes more obvious, but with a class even more than without it, there's absolutely no fucking reasons for "y38" to be a list !
 
  • Like
Reactions: UCheatedUrself
Jun 11, 2020
59
130
Note: I kept the code as you wrote it, in order to make the changes more obvious, but with a class even more than without it, there's absolutely no fucking reasons for "y38" to be a list !
True. I thought it would only work as a list or dictionary since those are mutable but I was wrong. Turns out I was doing other things wrong besides using a string that made it not work before.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,188
[...] a list or dictionary since those are mutable but I was wrong
They aren't mutable. Well, for dictionary they can since few 3.x versions, but only when explicitly declared as it.

Their content can be changed, but it's something radically different from mutability. And anyway this have no impact on variables access, especially with Ren'Py where all variables available in the game scope is nothing more than an object attribute.
This is pure scripting, no one care about the variable reference, the only thing that matters is its name.
 
Jun 11, 2020
59
130
*sigh*

You don't have permission to view the spoiler content. Log in or register now.

This is the exact copy of the code you shown, it do strictly everything that your code is doing, with less lines of code ; the seven last lines coved all the possibilities for both "suck" and "suct" values, including the ones you haven't copied.

Cherry on the cake, it would have worked fine right from the starts, without the need to pass parameters, return values, and catch the returned values.




Yes you would only need the key since with it you can easily get the value with a single line. But before this you would need to update a bit your approach, not anymore having two list of text:

You don't have permission to view the spoiler content. Log in or register now.


But in the end, like you already use object, for "sb" by example, there's an even better and simpler way to do all this:

You don't have permission to view the spoiler content. Log in or register now.

Note: I kept the code as you wrote it, in order to make the changes more obvious, but with a class even more than without it, there's absolutely no fucking reasons for "y38" to be a list !
I've run into a problem with this. Sorry for asking this so late, I just got around to finishing this part. I stopped using a list as you said and decided to just use a variable named 'fuck' instead.
So I made these modifications to the final bit of code you gave:

Code:
class Sbo_fuck(renpy.python.RevertableObject):[/INDENT]

    fuck_dict = {
lots of stuff
}

      def __init__(self):
            self.fuck = []
      def fuck_action(self):
          [...]
      self.fuck = random.choices([random.choice(fuck_list), random.choice(fuct_list)], weights=weights, k = 1)[0][/INDENT]
@property
def tlist(self):
        return self.fuck.startswith( 't' )
@property
  def entry(self):
        return self.fuck_dict[fuck]

default sbofuck = Sbo_fuck()
(Don't mind the indents, they're correct in the code but couldn't get them right here. )
And I call it with:

Code:
    if sbofuck.tlist:
        "[sbofuck.fuck]"
        "[sbofuck.entry]"
    else:
        sv "[sbofuck.fuck]"
        "[sbofuck.entry]"
But the error I'm getting is that 'fuck' is not defined. Specifically I'm getting this in the traceback:
While running game code:
File "game/Sales.rpy", line 4375, in script
"[sbofuck.entry]"
File "game/Sales.rpy", line 2050, in entry
return self.fuck_dict[fuck]
NameError: name 'fuck' is not defined
Where did I mess up in translating it from a list to a variable?
 
Last edited:

peterppp

Active Member
Mar 5, 2020
762
1,347
I've run into a problem with this. Sorry for asking this so late, I just around to finishing this part. I stopped using a list as you said and decided to just a variable named 'fuck' instead.
So I made these modifications to the final bit of code you entered:

Code:
class Sbo_fuck(renpy.python.RevertableObject):[/INDENT]

    fuck_dict = {
lots of stuff
}

      def __init__(self):
            self.fuck = []
      def fuck_action(self):
          [...]
      self.fuck = random.choices([random.choice(fuck_list), random.choice(fuct_list)], weights=weights, k = 1)[0][/INDENT]
@property
def tlist(self):
        return self.fuck.startswith( 't' )
@property
  def entry(self):
        return self.fuck_dict[fuck]

default sbofuck = Sbo_fuck()
(Don't mind the indents, they're correct in the code but couldn't get them right here. )
And I call it with:

Code:
    if sbofuck.tlist:
        "[sbofuck.fuck]"
        "[sbofuck.entry]"
    else:
        sv "[sbofuck.fuck]"
        "[sbofuck.entry]"
But the error I'm getting is that 'fuck' is not defined. Specifically I'm getting this in the traceback:
While running game code:
File "game/Sales.rpy", line 4375, in script
"[sbofuck.entry]"
File "game/Sales.rpy", line 2050, in entry
return self.fuck_dict[fuck]
NameError: name 'fuck' is not defined
Where did I mess up in translating it from a list to a variable?
self.fuck
 
  • Like
Reactions: UCheatedUrself