Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Kilyle

65
Posts
5
Following
A member registered Sep 24, 2016

Recent community posts

Oh!  I missed that there's more to that file.

(Notepad++ lets me see all the times a search term comes up, but Scrivener just shows me the first and apparently expects me to hunt for the rest.  I've currently got the full code in Scrivener in sections so that I can easily hunt down which part to edit in NPP.)

Hmm... this might actually make part of what I'm doing easier.  Or possibly screw it all up again, depending.  Guess we'll see.

Gotcha.

I'm not finding any indication that having a nurse on staff helps characters heal overnight (in the end day process stuff).  Where is this code located?

Trying to figure out the logic in NextDayEvents()

if player.preg.duration > variables.pregduration && player.preg.baby != null:
    childbirth(player)
    checkforevents = true
    return
for i in globals.slaves:
    if i.preg.baby != null && (i.preg.duration > variables.pregduration ||
    (i.race == 'Goblin' && i.preg.duration > variables.pregduration/2)):
        if i.race == 'Goblin':
            i.away.duration = 2
        else:
            i.away.duration = 3
        i.away.at = 'in labor'
        childbirth(i)
        checkforevents = true
        return

Given that these checks end in Return, does that mean that the game only allows one birth per day, and the player's birth takes precedence?

Also, does this mean that if a birth happens, no other events happen?  Or what does checkforevents do?  (I'm getting a little overwhelmed by all the code lately.)

Also, the next section that's not commented out says "#Old scheduled event system" -- is it still functional, or am I looking at code that never activates, or...?

Just two spots, huh?  That's a relief (after the other things I've been fixing up have bled out all over the place).

And yeah, I want a new job that a different character can be -- a Majordomo, the top butler, the Edwin Jarvis who keeps everything running aside from the slaves themselves.  A head girl is like the chief slave (focused on keeping the slaves in line), but a majordomo is like the chief butler (focused on the smooth running of the household, such that the master never has to bother himself with the little details and always finds his preferences accounted for and only has the actually important stuff brought before him while the rest gets handled secretly).

Long before I ran into this game, I ran into the concept of the Majordomo (in Marvel Comics), and the thought has stuck with me ever since.  Sure would be nice to have someone whose sole job is to ensure that I don't have to clog my easily distracted ADHD brain with all the little details of life, just the ones that actually require my attention.

Besides the Mansion's end-of-day stuff, how many sections would I need to modify to establish a new role, like Headgirl, for a Majordomo -- someone who keeps track of certain details and informs me of them (like to replace "You notice some of your food/gold is missing" as if the leader of an estate with multiple slaves would be the one personally inspecting the storehouses each day).  I mean I might want to add some additional details later, but mostly I want to start with "Sir, your gold seems to be dwindling faster than the books would account for.  I presume one of your slaves is sneaking into the treasury" or the like.

Character would be more effective in a Butler's Outfit, and less effective under some other conditions, and certain stats or traits would affect it too -- most obviously Wit.

So, I found this section, which appears to be where the Cleanliness of the house gets reduced: each slave reduces it by 1, except that shortstacks do 2/3, beastkin 4/3, and a few key races nearly twice the norm.

for person in globals.slaves:
    if person.away.duration == 0:
        if person.bodyshape == 'shortstack':
            globals.state.condition = -0.65
        elif person.race in ['Lamia','Arachna','Centaur', 'Harpy', 'Scylla']:
            globals.state.condition = -1.8
        elif person.race.find('Beastkin') >= 0:
            globals.state.condition = -1.3
        else:
            globals.state.condition = -1.0

But then I took a closer look, and it appears that each line is setting the variable, not changing the variable.  That is, the only loop that matters should be the final loop, in which the condition is set te a negative number related to that specific slave's race.

But since the mansion clearly appears to be getting dirty in a less consistent fashion, it appears that these lines do something I didn't expect.  So I hunted around some more and found this:

func cond_set(value):
    condition += value*conditionmod
    if condition > 100:
        condition = 100
    elif condition < 0:
        condition = 0

...which is defined as the way that this variable gets changed/set.  So I take it that elsewhere in the code, "globals.state.condition = X" gets reinterpreted as "cond_set(X)"?

Related question: If I change these statements to -= X instead of = -X, how would that affect the code, if at all?

Ah, that would do it!  Thanks for the idea!

Browsing this sex code stuff is making my eyes cross.  I would like to include a desire to get bred, and have it met if the character gets ejaculated into.  I figured out the desire part, and how to add conditions (Submissive or Monogamous or Clingy, past a certain loyalty threshold, etc.), and how to make a category for breedable acts (one for MPreg, one for normal), so I can ask "was the last action a breedable action?" and probably also "was this character the receiving partner?"

But I can't see how to ask "did it involve ejaculation by the penetrator?"

It's not so much that the code would be unsalvageable, as that at some point my brain will revolt over the sheer enormity and complexity of it all, and scream at me until I push the old version to the side and start a newer, cleaner version, using more of what I've learned.

Cycles of iteration and all.  It's been a fascinating journey so far.

Haven't yet tested this lastest round (still touching up major portions, and I have a Thing about not testing in small chucks due to sheer annoyance with load times), but I believe I've managed to let Omegas (Submissives) get pregnant, and possibly allowed Alphas (Dominants) to get turned into Submissives if they take it up the ass enough (heh).  Plus I've recently managed, let's see...

  • A kajillion birth scenes based on this or that trait -- a big difference in reaction between a Prude, Spoiled, Sex-crazed, Infirm, etc.; Passives dissociate unless they feel cared for, and there's even a nod to the mother's reaction if knowing they'll not get to keep the kid
  • A set of more subtle pregnancy signs for the player (you're about halfway through when you stop denying that you've got a baby bump, and near the end you're complaining about it taking too long and how you can't breathe), and I'll be putting together more subtle signs for slaves as well
  • Costume/Accessory effects have been dolled up, though I'm still in the middle of that -- but like, using a Maid costume on a male character who's not Pervert/Deviant or Submissive will stress him out (even more if he's forced to go out in public that way), but the obedience gain is a bit better too.  I've got a whole set of trait-based modifications for the Living Suit, should I ever get far enough into the game to find it.
  • More interesting groups of names, though I petered out partway through so it's basically just fairies and sea creatures, plus surnames for elves and herdfolk, and changing the human names so that I stop winding up with names that break my immersion (like "Elvis")

Eventually I'll see if I can't manage litters for Beastkin (especially bunnies) and Omegas, but that seems like it might be a bit of an undertaking.  I also want to get to the point where I can fork a bit of the sex scenes so as to make Alpha/Omega sex more interesting.  With the new Omega fertility boost, I expect to be playing those scenes a lot, lol.

Oooh, I hadn't even thought of it being an effect (like "Captured").  That would actually be pretty useful.  Not sure I want to tackle it right now, though, if as you say it's a difficult thing.  I've been messing with enough systems lately that I'm just waiting for the whole thing to come crashing down around my ears and force me to restart, heh.

Is there a way to tell if the "mind break" (getting so stressed you dropped to 0 confidence etc.) happened on a given day?  Like, even just "was it today" would help, but "was it within the last three days" would be better.

If not, is there some simple way to rig this?  I'd like for the reaction to mind break to be incoherence for at least a couple of days.  It seems weird they'd be able to talk normally.

I mean, where would I put the "actually, gimme a sec while I change your name before the player ever sees it" code redirect, when the slave is getting created in either (a) combat/exploration zone or (b) slaves at the auction zone.  I'd just want to have a moment when the name is already set (so the code doesn't expect it to be messed with anymore) but before the player gets to interact with the name (so the player doesn't see one name and then a different one later).

With that sort of redirect, I should be able to put together a "let's look through your Traits to see what sort of nameset would suit you" function for e.g. names like Prince, Princess, Ryan, Adora for Spoiled characters, names like Gunther, Viktor, and Rodrigo for Tough characters, a pool for names that sound faster vs. ones that sound stronger, or more delicate, or prettier / more handsome.

Now that you've told me how to reference globals.names I should be able to use arrays for cute fairy names, Western/Country centaur/taurus names, ocean-themed Nereid/Scylla names, etc.  But being able to change the names based on traits (especially for humans, who don't have a more interesting natural detail to work from) wouldn't really work from an array, unless I made a ton of arrays, and even so it'd wind up needing code to sort through which array to direct to (e.g. female_rich_beautiful_delicate).

...actually, where would I hook a name-change function, if I wanted to change the name only after the character is completely put together and I can look at all the pieces like a normal character?  That'd probably be an easier way for me to do it.

I'd love to give the Spoiled characters uppity names, lol.

Where is the code that gives a character their name?  I can't seem to lay my hands on anything that looks like it actually makes use of those name lists, but they're clearly working (I keep getting "Joesph", one of the reasons I want to change them), so what am I missing?  I want to change how the game chooses names and surnames (based on ages as well as races, so it's easier for me to tell human children and teens apart from adults... and I might switch name lists based on class as well).  (I've already managed some build-it-yourself elven surnames, but the code wound up in an unusual place 'cuz I couldn't figure out how to reference names.gd.  Also, fairies are about to get super trendy weird baby names, lol.)

Also, how would I reference the race of the captive, in a "thugs" or "wolves with person" type encounter?  I wound up having it describe the captive using the race of the first thug -- whoops!  Dunno if there's any way to do this.

On the up side, I've finally gotten past the annoying-troubleshooting phase of the descriptions and dialogue, and those are working well; I've even split up the responses to a request for intimacy, so that we don't get a "meek nod" response from every possible character -- the request phrasing differs based on traits (Subs and Doms, slutty/pervy types, masochists, passive, etc.), and the reactions differ as well, and there's a different threshold by having various traits give a multiplier to either the Lust or the Resistance (e.g. Subs, Masochists, and Likes It Rough bump up the Lust part of the calculation, while Doms and Spoiled bump up the resistance, and at least one trait increases both).  Also, people who could get pregnant are a little more reluctant.  And because it's a multiplier instead of an addition/subtraction, it effectively increases the effect of the existing add/sub lines.  I'll need to refine it a bit (having a Passive character just shrug and go along with it despite being fairly rebellious was not very immersive, but I could change that by changing the threshold a bit and rephrasing the "acceptance").

Anyway, now I've moved on to refining the Encounters.  My Wimborn Outskirts now has random washerwomen, kids running around, and bullies that specifically target a child (or occasionally a teen) or a cat-girl or cat-boy, so it feels a bit more lively.  Frostborn Outskirts and the Forest both have people gathering firewood.  I hope to eventually dig into the code enough to change how many steps an area takes and how much energy it costs per step, so that there's more encounters for the same amount of energy.

One thing I've noticed is that the "bound tightly to prevent escape" stuff also shows up for the captive that was being bullied/attacked, which makes no sense.  Haven't yet figured out how to distinguish between the two types in code such that the captive gets a different description and it doesn't sound like I randomly tied up the person I've just rescued.

By the way, how would I go about making it that I can release captives in the wild in order to reuse that rope?  I once did this sort of thing and wound up with a phantom rope causing crash errors IIRC.  But there's plenty of times when I've got a passel of midling captives and I run across the type I'd really like to catch, but I'm out of rope; it seems like releasing a captive would get me that rope, but that's not how it works and it bugs me.

P.S. While trying to learn some of the string handling in Godot/GDScript, I noticed that "finds" is not the best choice when trying to see if a string merely contains a substring (e.g. "Beastkin" or "Halfkin").  I wound up with some errors using "contains" and eventually hit on:

if "Beast" in person.race

Anyway, is there any reason to favor "person.race.find("Beast") > 0" over "if X in string"?

Also, I've completely forgotten how to look up what sort of code (which edition of GDScript?) this game is using.

Oh, it's definitely a lot of branching statements and having to figure out which subqualities matter for which initial branches (e.g. the amount of Confidence by which a Submissive/Omega becomes notable is much lower than for a Dominant/Alpha, Fear isn't such a big deal for Doms, and Passive bypasses most of the checks I put in later by virtue of just going along with what's happening instead of actively trying to avoid it).  It's taking a while to bash this out, and I'm only on the opening lines!

But I do think that just adding some alternative trait-based and situation-based content (e.g. characters speaking differently if they're Captured, which I believe should effectively act like a counter for "the first few interactions" for most slaves) will make it much less samey and more engaging.  Plus, it should help me get a feel for the personality of my slaves without having to constantly go "wait, which one was the X one again?"  I've especially had fun putting together variations on what Foul-Mouthed characters might say (from being rebellious through to being affectionate).  My test world quickly wound up with a pair of Foul-Mouthed Dominant and Submissive, so I'm tickled that I'll get to test what happens when alphas and omegas express themselves in coarse language ^_^

Ah.  Might be a bit much for me right now, but I'm glad for the info.

So far -- although I'm in the middle of coding it and haven't tested anything -- I've been working on changing the opening line when the slave gets brought to your chambers.  The aim is for traits like Passive, Submissive, Dominant, Spoiled, Ascetic and the like to take control enough to set a baseline style, and then for stats like fear, confidence/courage, wit, and charm to nuance the portrayal.  Seems to be going well in theory, but like I said, haven't gotten to the point where I can readily test it.

Also is "dom" just obsolete code?  In SlaveDialogues' CheckSpeechPatterns:

if (person.conf < 35 && person.dom < 40 && person.traits.has('Dominant') != true) ||
(person.traits.has('Submissive') && person.conf < 60):
shy = true
if (person.conf > 55 && person.dom > 60 && person.traits.has('Submissive') != true) ||
(person.traits.has('Dominant') && person.conf > 35):
bold = true

I don't see it elsewhere but Scrivener doesn't seem to appreciate that one might want to search for a short term without getting the longer ones (e.g. "random") so I've gotten too many results to really sift through.

Is there any record of how many dates a given slave has had?  Like, if this is the first date interaction?

If not, do you have a suggestion for the best place to add such a variable?  I'd hope with like variables such as might be used for the statistics rundown, where I could also list number of dates we've had, or maybe track separately which dates ended positively vs. negatively.

What, if anything, does the following code do?  I don't see other references to this variable.

var newclass = dateclass.new()
newclass.sex = globals.player.sex
newclass.name = globals.player.name_short()
newclass.person = globals.player
dateclassarray.append(newclass)
newclass = dateclass.new()
newclass.person = person
newclass.sex = person.sex
newclass.name = person.name_short()
dateclassarray.append(newclass)

I'm trying to figure out how to make the "dating" more interesting without breaking too much in the process.  Don't have a lot of spoons for troubleshooting right now.

Ah!  That explains my confusion.

Glad I asked, or I'd still be barking up the wrong tree.

I have returned to ask: Is punish.expect a static setting that never goes away once you've berated a slave, or am I just not finding the right part of the code that cancels it?

I'm working on my dialogue options again and there's the "Scared" option somewhere in the code that's like "if slave is over 34 stress and expects punishment then they're Scared" and I borrowed that concept for part of my dialogue tree but if this is a "you berated him once, he's always gonna hold that against you" thing then I might change how I navigate that dialogue tree.  That, or add a bit somewhere that gets rid of punishment expectation if the slave gets to a certain level of loyalty/obedience and hasn't been unfairly punished.  I don't recall many of my slaves getting to a positive relationship without a little discipline somewhere along the way, and berating them is the lightest thing you can do, so it feels weird to have that be a static setting instead of a dynamic one.

Don't suppose there's a "days since last punishment" variable somewhere, like with "days since last sex"?

I suppose that's good -- I always kinda hated the way that my Sims had a limited time to be at a given age, even as part of me also loved the "realism".

Debating whether having elders would amuse me enough to be worth the effort of creating a new age category...

(I'm currently down a rabbit hole of skintones, haircolors, and eyecolors -- trying to figure out patterns and where I'd like the patterns to change, and how to achieve a more bell-curve or weighted bell-curve (similar to advantage/disadvantage in DnD) for heights and such.  Like, petite and towering should be comparatively rare for humans but comparatively common for elves, that sort of thing.  And red hair rare, and why do humans not have brown and dark as part of their skintone range?)

(Also I get a very different impression of "red hair" for mundane/human vs. fantasy/fairy, so I'm gonna change the terminology to have auburn/copper/strawberry-blond hair for humans, with the term "red hair" reserved for fantasy races and probably augmented with "bright" or "deep" or "rich" -- I'm working on some color-nuance code to give more interesting shades like lavender and silver, and fairies and lamias can have pink hair.)

(1 edit)

I'm starting to mess with the races and got to wondering about characters switching age ranges.  I can find code for a baby to... I guess go away for a while until they're a child/teen/adult based on a button press?  I'm not finding any section that can age up a child to teen or teen to adult.  Does such a mechanic exist?  If so, where; and does it change the height range when a person levels up? because the height range for a child is understandably short, but that shouldn't say anything about their adult height, right (aside from not going down in height)?

Oop! just ran across the Maturing Pot.  Forgot about those.

Is there a different mechanic for ages or is it only by potions?

It's gonna take me a while to digest all this, but this is super, super useful.  Especially this part: "The dot operation for objects and dictionaries is simply an alias for the square bracket operation with a string key."  (Is this the case in Visual Basic, I wonder?  If it is, either I never got taught it explicitly, or I've forgotten it in the intervening years.)

I appreciate you taking the time to show me the incremental steps to get down to the most efficient version, so that I can more easily conceptualize what's going on and why.  As a self-taught programmer with what is likely ADHD, I find it all too easy to gloss over bits that seem surface-level "duh" or "I can look this up whenever", but explanations that are succinct enough to focus on but also detailed enough to help me grasp the underlying principles (instead of just the surface-level appearance) are exceedingly useful yet difficult to find.

P.S. I presume the debug mode would be a better way of handling the troubleshooting process than pulling out bits of code like I've been doing... so I just gotta get past the inertia/resistance of "but I don't want to figure out the New Thing, I'm working on this thing, and the irritation of doing this poorly is less of a problem than the effort it takes to do things better" brain mode.  Same reason it took me like five years to get to the point of modding Skyrim, and now I can't imagine playing without mods.  Brain inertia is fun (sigh).

Just to be sure I understand this:

You're specifically referencing the part that didn't work and corrupted the string, and saying that if I want to turn that into a string, then I need to take an extra step.

As opposed to "so the rest of your code may look like it's working, but it's not working right, and you really do need to take this extra step on all the things that so far seem to be working."  Which is currently this:

var accessory = globals.state.unstackables.get(person.gear.accessory)
var acc = getaccessory(accessory.code)
 
func getaccessory(code):
    var acc = null
    match code:
        "accslavecollar":
            acc = "collar"
        "acchandcuffs":
            acc = "handcuffs"
        _:
            acc = null
    return acc

...with variations for costumes and underwear.

I'm not sure if it's possible to shortcut the first two lines to avoid an extra variable that gets immediately discarded?  Something like this:

var acc = getaccessory(globals.state.unstackables.get(person.gear.accessory).code)

I debated about trying that but decided that despite the throwaway variable (three of them, all told), the code just looks nicer and more readable when I separate those two steps.

Anyway, I've gotten to the point of being able to reference and sort by these values, and it's all working pretty smoothly now that I've put it behind "if x != null" walls (which checks if the variable isn't set -- in this case, if the character isn't wearing anything, as opposed to wearing a different thing).  I presume I could do a similar thing using typeof() to make sure it's a string, which is likely a good habit to get into (sanitizing input), but at present all I am looking for is whether it's null.

(P.S. I understand print() functions to display text on the screen (pop-up box); does it have a different function or multiple functionality in Godot?)

Also, on the up side, I've gotten to the point where nearly all the problems get washed away in a few rounds of basic troubleshooting (e.g. pull the newly added code out to a text file, make sure the base isn't broken, add it back in in pieces, find the part that throws a wobbly, then look extra carefully to see if I've forgotten a quote or colon somewhere or misspelled a variable or the like (Notepad++ is actually really good at reducing the (already low) chance that I'll misspell a variable I've used elsewhere in the code), or if the issue is another round of misunderstanding how the code actually works).

So now it's just... ye gods, that's an ambitious level of fine-tuning my brain wants to do to the script!  I'm not even to the fancier parts of the code, just the description you see when you look at a slave and what the slave says to you when you talk to them.  I've condensed parts of the description to lines like "You see Wisteria Smithee, a towering, strikingly gorgeous Halfkin Wolf youth with her hands bound behind her" (which also omits the average part, unless both height and beauty are average, in which case it says "unremarkable" for humans and "typical" for non-humans) and fancy descriptions for costumes based on whether the character is handcuffed or wearing a collar (and the collar description changes when the character is more loyal).

Tomorrow, if all goes well, I'm gonna tackle separating the upper body description from the lower body description so that the eye flows seamlessly down the body.  And then figure out which parts of the character traits I'd like to weave into the description and where.  It'd be nice to see bits of description that combine e.g. beauty and strength (Strong, Frail), or agility and charm to add up to gracefulness, or like have a foul-mouthed character in handcuffs with low obedience throw you the bird.

Okay I think I got to the right stuff where I can easily check what I want

but en route I ran across a weird output formatting?  I'm gonna scrap this code, it was just to pin down the right details, but I am baffled as to how this produces the output.  This isn't even a question really, just a "wtf??"

(NOTE: the line break in the one text line is for readability here and not in the actual code)

CODE:
text += "Not naked!  "
var clothes = globals.state.unstackables.get(person.gear.costume)
var accessory = globals.state.unstackables.get(person.gear.accessory)
 
text += "clothes: " + clothes + ", type: " + typeof(clothes)
    + "; accessory: " + accessory + ", type: " + typeof(accessory)
text += "\nClothes Code: " + clothes.code + "\n Accessory Code: " + accessory.code
 
RESULTS:
1393, type: ; accessory:, type: 1393, type: ; accessory:, type:
Accessory Code: acchandcuffs

So it did spit out the right details, so now I know how to get it.  And I need some error-catching to make sure I'm handling actual variables and not making messy code when they're not wearing anything.  And the actual variables there translate to numbers hence the need for a thing to look them up and all (and 1393 appears to be the null entry? I guess?).

but... why did "clothes: " disappear? why did "Clothes Code: " disappear?  Do mishandled null entries actually erase part of existing strings???

(1 edit)

I knew my code was definitely not right, I just had absolutely no clue what the next step would be or how to look it up (as I had tried, some time ago, to find any example in the Godot/GDScript documentation that matched what I was seeing there, and came up blank).

var gold = 5
var formatPython1 = { gold : gold }  # creates { 5 : 5}
var formatPython2 = { 'gold' : gold }  # creates { 'gold' : 5}
var formatLua = { gold = gold }  # creates { 'gold' : 5}
var emptyDict = {}
emptyDict[gold] = gold  # creates { 5 : 5}

*tearing my hair out*

okay so

let me get this straight:

the Lua format lets you make a string without using quotes, that becomes a string in the code and gets referenced as a string???

never in a million years would I have made that leap on my own

this is my "dot operator" moment for this language

(actually it's more like... this language has broken one of the Core Concepts of every language I have studied thus far (aside from perhaps HTML), which is that strings go inside quotes and non-strings stay outside quotes and never the twain shall meet)


Thank you so much for laying it out so succinctly so I can compare the formats.  That helps a hell of a lot, and I much appreciate it.

Yeah, I'd guessed as much.  In the moment, I was irritated, but afterwards I was just amused -- I'm a language buff, and it's always interesting to run across signs that someone isn't a native speaker (though I do have to wonder about "shit hole" since most of the languages I've studied have "shit" as a base obvious swear with roughly equivalent meaning).  It also explained a lot of odd phrasings in the rest of the program (another detail I'm focused on while modding, just to increase immersion).

As far as the modding, guess for now I'll stick to the existing files and see how far I can go with just that.

Latest roadblock: What is the distinction between these two formats?

## First Format:
var rules = {'silence':false, 'pet':false, 'contraception':false}
## Second Format:
var gear = {costume = null, underwear = null, accessory = null}
var itemlist = {clothmiko = {code = "clothmiko", type = "gear", subtype = "costume"}}
## List of possible costumes:
#costume: clothmaid, clothkimono, clothmiko, clothbutler...
 
## This line works:
if person.rules["nudity"] != true:  ## Nope!
    text += "Not naked!"
## This line doesn't:
if person.gear[costume] != null:
    text += "In costume!"
 
## But the code gets REALLY SUPER WEIRD for that second format???
## These are things I found that seem to reference it:
for i in globals.itemdict.values():
    if !i.type in ['gear','dummy']:
        i.amount += 10
 
var handcuffs = false
for i in person.gear.values():
    if i != null && globals.state.unstackables.has(i):
        var tempitem = globals.state.unstackables[i]
        if tempitem.code in ['acchandcuffs']:
            handcuffs = true
for i in ['clothkimono','underwearlacy','accamuletemerald']:
    var tmpitem = globals.items.createunstackable(i)
    globals.state.unstackables[str(tmpitem.id)] = tmpitem
    globals.items.enchantrand(tmpitem)

What the heck is going on here?  It seems like the first format (dictionary?) allows for a super easy reference to keyed codes ("Does he have this specific rule? Y/N"), while the second format -- which I think I tried to look up soon after dipping into this language, and could not find -- seems to either require several more steps, or require you to manually hunt through every entry to locate the thing in question.

What I want is to be able to see if a person is wearing a specific costume, underwear, or accessory, and then give description based on that.  How to reference these values?

Sweet.  So now the only other major roadblock I've hit (that hasn't cleared up with some troubleshooting) is how to add an extra .gd file of my own, because I couldn't make that work at all.  I presume that has to do with something outside the basic scripts folder?

Anyway.

Yeah, if I were thinking to make a mod for more than just my own private use, I'd probably try to work out a nice integrated restriction like those you mentioned.  Or if it turns out that I wind up using it too much, I guess, but I doubt that'll be an issue.

For the traits, I'm definitely putting a lot of work into expanding the dialogue based on various traits and trait combinations.  First step is just working on the basic Talk Mode thing -- just trying to make sure I grasp the flow enough to make things work without breaking things (the first major step! spent way too long troubleshooting just to realize I'd forgotten a colon and a quote somewhere).  I've been having way too much fun making up randomized dialogue options for Foul Mouth (and I don't usually like things with swearing! but it feels weird to have slave characters with such a pronounced trait who talk just the same as everyone else even when being outraged at their captor).

Next step will be to change the character descriptions again (I did this in a previous attempt, but I want to start from scratch), making them more condensed and flowy and less gamified.  Bits I've thought of include, let's see... logic for when the sizes for two things are equal, nearly equal, or very unequal, then making the sentence combine them ("small X and Y"), use a basic "and" ("small X and average Y"), or contrast ("small X but huge Y" or "huge X but small Y").  Combining longer hair with description of chest ("her long hair flows down and around her large breasts", "his long hair contrasts his muscular chest"), depending on hairstyle.  Describing the clothing they're wearing, once I figure out how to reference items/gear (butler suit, geisha outfit, but also handcuffs or slave collar, etc.).

My first attempt was mostly to get rid of the genital description because I'm not the kind of "master" who wants to see penises every time I enter a room (I initially changed them to how far apart they spread their legs).  And even the way they stand or the way they look at me could be switched up based on traits and/or stats.

Later on I'll be trying to revamp the sex scenes a bit, see what I can do without breaking everything.  I definitely want the Dominant/Submissive stuff to work more like Omegaverse, and the non-human cocks to actually matter.  And the thing that actually got me into modding was being halfway through a scene when the term "rectum" was used, and then "shit hole", and I'm like "......well, someone doesn't have a firm grasp on reasonable sex-scene terminology" (or possibly just English registers -- the idea that certain terminology works in doctor's offices and not in the bedroom) and then I went "hmm, wonder how hard it would be to change this stuff..." and down the rabbit hole I went.

Hmmm.  Sounds like suboptimal code, the idea that characters get created before the game knows whether they even matter (whether the player will in any way get to see the details).  It would make more sense to say "There's two bandits over there, do you want to engage?" and then, if you engage, generating characters.  This problem would be even worse for those giant packs of bandits I've seen (but not yet engaged with).

Actually, optimal code would likely generate a full character only upon capture, and generate a partial (necessary stats only) character for combat, then generate the next partial bit at the end of combat (when you get to see a few new stats), and finally transferring the partial character into a fresh full character if you capture them.

It's good to know that the uniqueness sticks around even if you sell them, though.  That does avoid some issues.

(1 edit)

It's working fine!  The only thing I noticed is that the immediate update changes the name in the left (personal) panel, but not in the slave list (until I change screens).  I presume there's a "rebuild slave list" call or something that'd do that, just like your last line there.

I went ahead and updated the logic to include the effect on the slave:

func _on_namechangeconfirm_pressed():
get_node("namechange").visible = false
var text = "Yes, $master."
 
if person.obed >= 70:  ## Highly obedient
    if person.loyal >= 50:
        text = "— Of course, $master.  It's my pleasure to mold myself to your desire."
        person.loyal += 10  ## They're pleased with the personal attention and "gift" of a new name
        person.stress -= 5
    else:  ## They're not yet broken in, but have been forced to high obedience
        text = "— Of course, $master.  Your will is all that matters."
        person.loyal += 5  ## They have mixed feelings about the personal attention
        person.stress += 5
elif person.obed < 35:  ## Not yet broken
    if person.conf > 30:
        text = "— You can't just take my name away!"
    else:
        text = "— Are you really going to take away even my name??"
    person.stress += 15  ## Highly stressed at having their individuality taken from them
else:  ## Moderate, compelled obedience
    if person.conf > 60:
        text = "— I guess I don't have much choice, do I?"
    else:
        text = "— Yes... $master."
    person.stress += 5  ## Kinda used to it by this point, but it's still a negative
 
person.name = get_node("namechange/LineEdit").get_text()
get_tree().get_current_scene().close_dialogue()
get_tree().get_current_scene().popup(person.dictionary(text))
get_parent().slavetabopen() # Ankmairdor - add this to update GUI and show new name immediately

So basically, if you name them right away it helps to break them; if you've already done some work before naming them it's a little stressful; if you wait until they're well trained then it's still a little stressful but bonds them more to you; and if you hold off until you're sure of their loyalty then it's a wonderful gift.

I mean you could totally abuse the function to just repeatedly stress them out (or increase their loyalty a bunch), but I don't intend to use it that way and thus don't care to code around it.

P.S. Forgot to include support for Mute characters, but now have a similar section with reactions ranging from outrage to resignation to joy.  There's so much that can be done with body language, even without access to words!

Hmm, interesting.

So the fact that the ID is so high is because I caught and sold a bunch of slaves in between finding ones I liked.

Does the unique ID stay with sold slaves (until they presumably vanish from the market), or are they given a new ID when you buy them back?  I've been using a sell-and-buyback strategy to get Mansion Upgrade points and a brand.

If selling slaves gets them out of the pool but maintains a higher slave counter, would it be possible to change my preferred slaves to the IDs e.g. 12, 13, 14, 15?  I could either ignore the relations/interactions data, or figure out how to swap a few numbers around.

I wouldn't be messing with the unique/quest slaves, yeah.  I pretty much always use the same starting slave specs anyway (I found a nice setup that works with my overall story concept, and gives me a neat pun, so it'll be a while before I tire of that specific character).

Oooh, thanks!  Downloading.

And yeah, I noticed that the name didn't update directly after changing (I had to switch screens to get that to work), but that was a minor inconvenience I could figure out later if it bugged me.

P.S. Next "hmm, wonder if I can...?": Port my favorite slaves of my current game into a fresh game via manipulating save files.  I've put a lot of work into a handful and would prefer not to just abandon them...

I figured out the backup files folder pretty early on; it's saved me from a recurring crash-on-load error, when I was able to just pull files from the backup and replace the entire directory, phew!

What I do now is, I copy all the files fresh from the backup folder into my own folder somewhere else, go through that personal folder and delete any files that look like they aren't going to be something I'm interested in and/or capable of editing, and then I split the files I do want to edit into different folders as separate "Mods" (since that seems likely to be less error-prone than my previous attempt to Do Everything All At Once).  E.g. one mod just to update the gendered language in that little exchanges-dictionary (all the $sir and $master and $brother stuff).  Once I've edited the files there, I go copy them into the Mods folder in my AppData/Roaming/Strive/Mods folder, so I'm not editing any of the backup files directly at any step (unless I seriously screw up my process and accidently save the wrong file, which I've done at least once but did recover from).  I could reload the entire game at some point if need be, make sure it's all fresh.  In fact that might be advisable.  Hmm.

I've never had any problems with Notepad++ -- aside from occasionally winding up forgetting which version of a file I've opened and thus editing the wrong one, but I've gotten better at being careful with that.  The code is definitely getting to the right StatsTab file (or it wouldn't come up with the extra button in the first place), and I'll check later to make sure that the other file is likewise properly updating.

On your advice, I went ahead and got that Godot engine editor (two copies -- the last stable full build (not the current dev/alpha build) and the highest final number on the one you recommended for this game particularly.  That's (checks) 4.3 and 3.3.4.  Being able to load up the game and look at the behind-the-scenes details was five or ten minutes of pure excitement-joy as I went through seeing all the screens.  It did kinda spoil a later plot point because that's the text on one screen, but eh, I knew I was gonna get spoilers due to messing with the code to begin with.

At this point, this feels like a "this step is beyond my skills" roadblock, which at least confirms I'm not missing something that would be obvious to veteran Godot coders.  When I first went to college (some 25 years ago), I signed up for Visual Basic because I couldn't make anything work, despite self-teaching myself from GW-BASIC through QBasic.  Turns out I'd missed the dot-operator (the object.property thing), and once I learned that, I could make everything work and basically didn't get all that much from the rest of the class (which was aimed at newbies, while I'd been coding since like 14).  Knowing that the block isn't something that basic is a relief.

I think what I'll do is step back slightly, content myself with figuring out how to mod the code that has been working, continue exploring as I go, and probably change the "call me Master" button to a slave name change button, since in fact I was able to make that much work (losing a function I don't really care to make use of anyway).  Or maybe I'll see if I can replace the "Release" button that I'm always afraid of pressing, since I don't really intend to use it.

I appreciate you taking the time to work through the troubleshooting with me; that has reduced my frustration back to a much more manageable level.  And hey, getting me over the hump to actually downloading the editor might wind up with me getting back into hobbyist game design, who knows?  Maybe that'll go somewhere interesting.

(3 edits)

Yeah, I specified that I didn't change spaces in the actual code because I did add line breaks here (to prevent it going off the side of my screen when I switched it to Code Mode there).  I'm aware that spaces can be functional; they aren't in most of the languages I've used, but since Godot/GDScript uses indentations functionally I presume that all whitespace is potentially functional and I'm careful about not messing with it (my brain is pretty well specced to grasp open/close mechanics such as parentheses and nesting -- that's the very thing that those classmates in college were messing up all the time, pasting code into random spots and breaking the nested logic of the original code).

ETA: And yes, I am very careful about the distinction between tabs and spaces.  I'm using tabs in the code for all the indentations -- they don't just look similar, they are equivalent even in the whitespace.

Here's my code (again omitting Anchors and Margins, for brevity).  Again, these are in the exact same files, matching the original code exactly, including the white space (the line breaks have been added here purely for readability, and are not used in the code); the only thing I have changed is the variable names (carefully matched in logic to the original set of names), obvious Strings, and some If/Then logic that shouldn't impact the buttons themselves, just the text displayed (I even commented it out with a test string instead, to be sure it wasn't screwing things up).

##############################################
#### Testing to see if I can add a button ####
##############################################
[node name="namechange" type="Popup" parent="MainScreen/slave_tab/stats"]
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="TextureRect" type="TextureRect" parent="MainScreen/slave_tab/stats/namechange"]
texture = ExtResource( 44 )
expand = true
[node name="Label" type="Label" parent="MainScreen/slave_tab/stats/namechange"]
size_flags_horizontal = 2
size_flags_vertical = 0
text = "What name should $name respond to?"
align = 1
[node name="namechangeconfirm" type="Button" parent="MainScreen/slave_tab/stats/namechange"]
size_flags_horizontal = 2
size_flags_vertical = 2
text = "Change Their Name"
[node name="LineEdit" type="LineEdit" parent="MainScreen/slave_tab/stats/namechange"]
size_flags_horizontal = 2
size_flags_vertical = 2
caret_blink = true
##################
#### END TEST ####
##################
##############################################
#### Testing to see if I can add a button ####
##############################################
[connection signal="pressed" from="MainScreen/slave_tab/stats/namechange/namechangeconfirm"
to="MainScreen/slave_tab/stats" method="_on_namechangeconfirm_pressed"]
##############################################
#### Testing to see if I can add a button ####
##############################################
#### Function called when new button gets pressed:
func namechange():
get_node("namechange").popup()
get_node("namechange/Label").set_text(person.dictionary("What name should $name respond to?"))
get_node("namechange/LineEdit").set_text(person.name)
get_node("namechange/LineEdit").set_placeholder(person.name)
#### When new button gets pressed:
func _on_namechangeconfirm_pressed():
get_node("namechange").visible = false
var text = ""
text = "Yes, $master."
#if person.obed < 35: ## Not yet broken
# if person.conf > 30:
# text = "— You can't just take my name away!"
# else:
# text = "— Are you really going to take even my name away??"
#elif person.obed > 70: ## Highly obedient
# text = "— Of course, $master.  Every part of me exists to serve your will."
#else: ## Moderate, compelled obedience
# if person.conf > 60:
# text = "— I guess I don't have much choice."
# else:
# text = "— Yes... $master."
person.name = get_node("namechange/LineEdit").get_text()
get_tree().get_current_scene().close_dialogue()
get_tree().get_current_scene().popup(person.dictionary(text))
## Testing to see if I can add a button
buttons.append({text = person.dictionary("Change Name"), function = 'namechange'})

So yeah, I don't think I missed something as simple as using the wrong name.  And since changing the original names (in both files) to blahCallOrder and blahCallOrderConfirm completely broke the original sections that were working, and since none of the other files in either directory reference these variables, it definitely feels like I'm missing a piece that needs to get accounted for elsewhere.

Also, I included the buttons.append line exactly as you quoted, in my "samples of my code" at the end of my first post there.  Just added it to here for completion.  Really wish the code formatting let me include line breaks, this wall of text stuff is killing me.

Okay, I give.  It's possible I'm not even messing with the right part of the code (I recently did a giant overhaul of the game's text just for fun before realizing that the text I was working with was obsolete/nonfunctional and just a few lines had been lifted to an entirely different part of the code, which was the part that actually mattered, sigh).  It's possible that I'm overlooking something basic, or that the part of the code I'd actually need to mess with isn't even editable in the user-accessible text-style files, so here I am hoping for answers/guidance.

(Note: I'm a longtime hobbyist coder/game designer, and new to Godot/GDScript, but it's similar to many languages I've used over the years, and most of the basics are easy enough to grasp.  So I expect I might be failing at some core distinctions or underlying foundational details.)

Anyway, so, in StatsTab.gd I found the section where some buttons pop up and you can order them to call you by a new name.  So I figured I'd try to add a button that lets you change their name.  Mostly I'm just copying what seems like a reasonable section of code and changing a few tidbits that seem like they won't break anything.  (I do feel a bit like the classmates I tutored back in college, when I was already skilled in Visual Basic while they were randomly copy-pasting code with no grasp of the underlying structure and then getting confused why it broke.)  It easily created a button, but of course the button doesn't do anything.

So I hunted through a few files, making some educated guesses, and happened across Mansion.tscn (I've only recently dug into files that aren't .gd), which does have the right variable names (callorder, callconfirm).  So I copied some code there, changed names to match the other file, and gave it a shot.  No dice.  Button appears, but does not do anything.

I double-checked that I hadn't misspelled anything, and that all the references match the pattern of the original code ("callorder" becomes "namechange", "callconfirm" becomes "namechangeconfirm").  Nothing looks like it needs a particular uncopyable code (e.g. a unique numerical ID).  It appears that having identical names (like "Label") is fine so long as they're under distinct Nodes.  I finally got smart enough to open all the files collectively in Notepad++ and search for the variable name, and it appears that these are the only two files that reference it, out of the Scripts folder and the Files folder.

And just to test, I went through the original functions and changed the internal parts (not referencing the variable name) and got a functional change-name button.  But changing all the references to "callorder" and "callconfirm" to "blahcallorder" and "blahcallconfirm" breaks the button entirely, so clearly there's something else going on here.

So now I'm stumped.

Here's the original code.  To keep the code here shorter, I've omitted the Anchors and Margins, as I can't imagine they're part of the problem here (and I haven't messed with them, just copied them wholesale hoping the button would show up in the same place).  Again, all I did was change "callorder" to "namechange" and "callconfirm" to "namechangeconfirm" in copied code in the same file:

Part 1 (in Mansion.tscn):
[connection signal="pressed" from="MainScreen/slave_tab/stats/callorder/callconfirm"
to="MainScreen/slave_tab/stats" method="_on_callconfirm_pressed"]
Part 2 (in Mansion.tscn):
[node name="callorder" type="Popup" parent="MainScreen/slave_tab/stats"]
size_flags_vertical = 2
[node name="TextureRect" type="TextureRect" parent="MainScreen/slave_tab/stats/callorder"]
texture = ExtResource( 44 )
expand = true
[node name="Label" type="Label" parent="MainScreen/slave_tab/stats/callorder"]
size_flags_horizontal = 2
size_flags_vertical = 0
text = "How should $name address you?"
align = 1
[node name="callconfirm" type="Button" parent="MainScreen/slave_tab/stats/callorder"]
size_flags_horizontal = 2
size_flags_vertical = 2
text = "Confirm"
[node name="LineEdit" type="LineEdit" parent="MainScreen/slave_tab/stats/callorder"]
size_flags_horizontal = 2
size_flags_vertical = 2
caret_blink = true
Part 3 (in StatsTab.gd):
func callorder():
    get_node("callorder").popup()
    ## Improved phrasing
    get_node("callorder/Label").set_text(person.dictionary("How should $name address you?"))
    get_node("callorder/LineEdit").set_text(person.masternoun)
    get_node("callorder/LineEdit").set_placeholder(person.getMasterNoun())
func _on_callconfirm_pressed():
    get_node("callorder").visible = false
    var text = ""
    ## Improved phrasing plus support for characters who don't speak with their mouths
    if !person.traits.has("Mute"):
        text = "You have ordered $name to call you '$master' from now on. "
    else:
        text = "Since $name cannot speak, you teach $him a way to sign '$master'."
    person.masternoun = get_node("callorder/LineEdit").get_text()
    get_tree().get_current_scene().close_dialogue()
    get_tree().get_current_scene().popup(person.dictionary(text))
Part 4 (in StatsTab.gd):
buttons.append({text = person.dictionary("Order to call you ..."), function = 'callorder'})
SAMPLES OF MY VERSION:
## Testing to see if I can add a button
buttons.append({text = person.dictionary("Change Name"), function = 'namechange'})
#That part worked fine, but the rest doesn't:
[node name="namechange" type="Popup" parent="MainScreen/slave_tab/stats"]
[connection signal="pressed" from="MainScreen/slave_tab/stats/namechange/namechangeconfirm"
to="MainScreen/slave_tab/stats" method="_on_namechangeconfirm_pressed"]
func _on_namechangeconfirm_pressed():

Note: I'm not adding interior line breaks or tabs in the actual code unless they're there in the code I'm working from.  The copy is identical except for the variable name changes, the obvious strings (like "Order to call you..." to "Change Name", which works fine), and a bit of If/Else code (which I'm not having any trouble with elsewhere and doesn't seem to be related to the problem).

Any clue what I'm missing?

That's fair.  Thank you for letting me know where I might start looking!

Does this have a setting to only play the sounds during certain keystrokes, instead of all of them?  I'm glad I got this, it sounds awesome and I'm eager to try, but I can already anticipate that it might be a bit of an overload for my brain.

I would like to have it play only for vowels (so about half of my typing, maybe less), or maybe, if even that was too much sound to deal with, maybe only on punctuation marks or only on capital letters or only on the return (yay, you finished a paragraph!).

Even better if there were a field I could type in the specific letters or combos it'd make noise for (e.g. maybe it's a VW kinda day, or maybe I'm trying to type something without the letter E, or maybe I just want booing sounds when I start to type the villain's name).

(1 edit)

Thanks!  That lines up with Extra Credits' video about "Minimum Viable Product," and I'll try to bear that in mind while I get started.

Also, just noticed that you're from the Pacific Northwest -- sweet!  Always nice to connect with creators from the same area.  Maybe sometime I'll see some local plant life in your games (madronas?).  Stardew Valley's creator is also from around here (I found out yesterday), and he added salmonberries to SDV ^_^