Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Kilyle

42
Posts
1
Followers
5
Following
A member registered Sep 24, 2016

Recent community posts

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 ^_^

(1 edit)

Thanks for being clear about expectations!  (And about whether or not you might consider a re-release.)  For a first game, it does seem quite large and detailed and interesting.

"A big learning experience in just getting something we felt happy releasing" is one of those moments I hope to have in my future, as a hobbyist game designer who's been trying to get some teenage+ nephews interested in actually completing something that we could submit to the public.  (Got any advice or "things I wish we'd known when we were just starting out"?)

(2 edits)

Yes, it's important to remember the scope of possibilities, given the resources and experience of the team.  Honestly, being not that familiar with itch.io but having played a small varieties of games here, I expect smaller projects, smaller teams, lower budgets -- but even there, there's room to grow, and to think more about what can be done within those limitations.  (I forget which thing I was watching or reading recently that discussed the benefit of working within limitations... possibly an episode of Start With This, by the creators of Welcome to Night Vale?)

I hope I don't come across as too critical in the feedback; I figure, since the creators donated their efforts to a good cause, then if I like it enough to both play more than a couple minutes of it and also wish it were better (more polished), I ought to provide at least a bit of a feedback about how that might be accomplished.  Whether that feedback helps with a revamp of this game, or in a future project, it might still be useful.  (As for the length: I tend to get wordy when I discuss things that interest me, and since I sometimes have trouble getting my point across, I tend to also over-explain things.  So I hope it wasn't too much.)  I know that with my writing, I appreciate detailed feedback about how to improve; that's not true of every creator (which is fine), but it's the position I start from, at least.

Oh, I understood perfectly well what the game wanted me to do.  But Spade-style players like to nose around the edges and see what the game lets you do.  And whether the designers anticipated that.

In World of Warcraft, a long while before certain expansions, there was a place atop Ironforge that only a few players ever got to see.  You had to do a weird combination of jumping and sprinting and knowing (or guessing) precisely where to aim in order to make it up there.  But there was content there, for those of us who managed it.  Similarly, in one game (I forget which, maybe a GTA?), there's an area you can only get to by something like a game-breaking bug, and there's like graffiti on the wall (I haven't played the game in question) saying something like "Hey, you're not supposed to be up here!"

A smaller game designer can't be expected to account for all the ways a player might try to play the game (heck, even the big game designers can't account for everything), but they can still work out flow charts for areas and figure out where adventurous players might try to go.  Heart-type players might try to interact with the characters (and get disappointed if the NPCs are too simplistic).  Diamond-type players might try to see if there are goodies to collect.  Club-type players like to assert dominance over the enemies and the game itself.  And Spade-type players like to explore (and break the game scripts by doing what the game doesn't expect).

Consider if, in the midst of that storm, there were just a couple characters out there -- not like the guards, not blocking the path (a mechanical detail), but out there to give a little color to the landscape for those players who didn't follow the game's directions to go straight to the inn.  Maybe the lighthouse keeper is checking the integrity of the lighthouse.  Maybe a farmer is checking to make sure that his animals are all right.  Maybe a mom is out hunting for her storm-enjoying kid.  A little something, maybe something that most players wouldn't see, but players who ran around the town a bit during the storm would run into these characters.  It'd give a little color to the people in the town (Heart), show that the designer was thinking about more than just the linear story (Spade), and maybe it could give a small goodie to the player (Diamond) that doesn't impact the game much in the long term, but might be a useful boost in the short term (e.g. 20 gold coins for helping the lighthouse keeper gather wood to fix up his windows).  Throw in a little challenge (like tracking down a couple of animals) and you might even make the Clubs happy, if they happened to hunt around in defiance of the game's logic.

If it's a character you meet later, then when you run into them "for the first time" (as the game expects), the game could remember your interaction the night before and greet you in a different way.

But if there's literally nothing to find out by venturing through the storm, then physically prevent that from happening.  Make the inn be next to the entrance to the town, and have a guard not allow strangers in during the night, or have the gate be locked and not guarded due to the storm.  Or maybe the storm's knocked over a big tree that blocks the path to the rest of the town, and they won't be able to clear it until the storm clears.  Maybe the storm flooded a river and it's flowed over the field that separates the inn area from most of the town, so you can only really explore a tiny part of the town during the storm -- and maybe use that corner-of-map preview to let the player get a peek at upcoming areas, without being able to walk around in them just yet.  Maybe you see the graveyard from the edge of the screen (behind the trees and rocks that block the path), so you'll know it's a point of interest for later.  Maybe if you nose behind some bushes to the side of the inn, you see a short interaction between two characters that starts a little mystery about what's going on in town, or that makes it suspicious when that character seems super nice the next morning (not having seen you spying on them).

You don't want it to be as obvious (and boring) as No Sidepaths, No Exploration, No Freedom (see TV Tropes), but by artistically cutting down on where the player can go (at any given point), you can improve the player's experience and cut down on frustration (one type of frustration being "I'm not sure I checked all the nooks and crannies").  And if you allow a small amount of exploring while the game's waiting for the player to hit the next section, you can make simple yet interesting choices about what the player finds if they actually do start exploring, and you can expect the explorative characters to find the things you set up (as opposed to wandering around a giant town during a storm and then getting bored and wandering back to the inn without having found the one section where you hid something neat).

Quite pleasant music design, good graphics, overall enjoyable game with decent controls, not a bad boss battle.  I loved the coin-explosion animation for the chest and the large number of coins compared to the bushes I chopped down (I always felt like Zelda had too few: If I'm chopping bushes to earn money, gimme more faster!).

I am not usually one to complain about open-ended level/area design, but that is the area I would most recommend that you focus on.  First, you have to go through half a dozen screens with zero content and no branching, just to get to the cave; I'd suggest the cave be on the first screen there, or perhaps the second (so you'll likely have grabbed the sword).  If you want some distance when the character returns to that spot, there are other ways to achieve it.  (The cave itself was not a bad design, if a little back-tracky.)

Secondly, the town wanted me to go to the inn, but, being a Spade, I wandered.  And I found just a ton of open areas with no dangers (which was actually nice), but also no content.  I could basically get hints about upcoming areas to explore after the storm (lighthouse, graveyard, mayor's house, random buildings), and coins from chopping bushes, but that was it.  Several screens had me stuck in a tiny spot where I could see the screen but not interact with it unless I backtracked and found a way to it -- which would be fine as a preview of "aha, the boss/treasure is over there" but this happened to "preview" spots I was at just two screens ago.  One "previewed" a corner of the island next to otherwise all ocean.

(I couldn't tell if I couldn't enter the houses or just hadn't figured out the correct button.  Having the doors react to "knocking" in some fashion would be useful.)

Earthbound has the police cordon off the not-useful places at the start, so you can only really go up to where you're meant to go to progress the story.  This was funny, but also useful to prevent the player from spending time in ways that have no long-term effect on the game.  I recall A Link to the Past being pretty restrictive at the start, in a natural fashion by not letting you chop bushes yet (or bypass guards?).

You can have some larger open areas, but, in general, think of areas as having enter/exit points, and design the screen around that concept.  Trees and rocks and cliffs and the like help guide the player toward useful content, much like lit-up areas ("go here") and broken cars, fences, and trash piles ("you can't go that way") do in Left 4 Dead.  If you do it right, the player doesn't even notice that they're being led around; they feel free to do things, but also are physically prevented from wandering too far off course.

(World of Warcraft did this between low-level and high-level areas, not as a hard limit but some pretty obvious signs that a certain area is Bad News.  That I ignored those signs and got my level-12 character killed by a level-40 spider is my own fault.  But most games won't even let the low-level characters get anywhere near the high-level stuff unless the player has been particularly tenacious in bypassing the signs.)

Anyway, that's the area that I think could use the most improvement.  The only other issue that I ran into was a minor fine-tuning thing: It'd be nice if bumping into the wall slightly off from the path just bumped me down toward the path instead of being a hard stop, so that it felt easier to get my character in where I wanted to go.  That's not likely a big concern at this level, but it's something to consider for smoother controls once you get to bigger projects.

This was a pretty good game!  I might play more of it later (I'm just kinda dipping my toes in the water for a few of the games I just got, and offering feedback if the game is good enough to warrant a little polish).  Thanks for making it!

<beelinespan class="beeline-node">Remembered links would likely be sufficient, especially as you get near the end of the game and even if you tried to get 100%.  (I'm not generally a 100%er, but I am a Spade, and digging into the little details of a small game is a lot of fun.)  Kinda reminds me of a pattern I saw once for a computer that taught itself a tiny (3x3) version of chess... and was made out of matchboxes, no electricity involved.  (Every time the human wins, remove the bead that indicates the move that made the computer lose.  Eventually, the computer becomes unbeatable.)</beelinespan>

<beelinespan class="beeline-node">The lack of always-good or always-bad options is a nice touch.  I have a storytelling card deck I've been designing with that general theme, which is kinda based around balance or wisdom (the portion of wisdom that judges when to use Tactic A and when to use Tactic B and when to choose a third option).  Like how following authority can be good in one circumstance and bad in another, or how violence can be appropriate in some cases but not in others, or how Nature vs. Technology sometimes goes one way, sometimes another, or how loyalty is not a positive quality when it ties you to a bad person/force.  Even the Loss cards are understood to be a positive change sometimes, and other times a road block that you get stuck in and need to move beyond.</beelinespan>

What a neat idea!  I've been trying to get my nephew and me to sit down for a week and try to make a game (basing our options on the engines I have available, the assets I have available, and the list of easiest game genres from Extra Credits' "Minimum Viable Product" video), but now the idea of doing it with some random mechanics intrigues me.  I could see having the stages of game development come at us randomly: "Today we (draw) record sound effects!" (without knowing what exactly we're recording them for, aside from the general genre)  "Today we (draw) create background graphics!"  "Today we (draw) develop a basic physics engine!"  "Today we (draw) choose a color scheme!" lol

Yeah, my biggest issue with this was the amount of "I have no idea what this is going to do" except that snakes kill and steeds possibly carry me out of danger.  There needs to be a Tooltip, at the very least, to show what the card types are for after the start; it'd be nice to have them numbered up in the corner somewhere so that even when the cards are not on the table you know which ones you have left.

Also -- although perhaps you've already accounted for this -- in playing the game through a second or third time, it'd be nice to see the number of choices that you haven't taken under a given choice, making it easier to hunt through and find paths you haven't yet explored.  And maybe it could keep track of which cards you used on previous encounters with a given location/scenario (and perhaps provide you with a "mystic view of the future" or whatever, as to what lay down that path (that you already tread last time)), so that you could decide whether to use the same card or a different one.

Overall, pretty enjoyable!  Although I wasn't sure if using the snake card at the start was a key factor or just one of many in the ending I got.  I'm a Spade, so it felt right to do the thing that most good-style players wouldn't use (plus, at the time, I was under the impression that perhaps the snake would do something other than kill).

If you get around to recreating (or open-sourcing) it, I would like to be notified.  I hope that "Follow" is sufficient to let me do this?  (I'm not that familiar with this site.)  I may not have much time to play text adventures these days, but they do fill me with nostalgia, and I love that people are still developing engines to make them faster and easier than anything I could've done back when I got started programming.

P.S. Look up Inform 7; it's an incredible engine based on human-readable code.

When you're done checking out Quest, look up Squiffy (by the same group) and then Inform 7.

Squiffy is closest to the basic Choose-Your-Own-Adventure book format, updated for a digital environment and with minimal support for variables and such.  But it works as webpage code (JavaScript?) and thus can be hosted just like a webpage.

Quest lets you create rooms and such, in a somewhat complicated GUI; I haven't played with it all that much, but it seems useful for small projects.

Inform 7 works from human-readable code (!!), wherein you describe the world and the objects within it, explain how they relate to each other and how they can be interacted with, define new verbs (and interrupts for if the player tries to do something forbidden: "Instead of picking up the car, say 'Do you think you're Superman?'"), all in code that's as close to English as I have ever seen.

So if you want to create a branching story with minimal interactivity, go for Squiffy; if you want to create a text-adventure world with tons of objects that could be manipulated by the player in any number of ways, go for Inform 7.

Y'know, I love that I got all these game assets in this pack, thus giving me additional fuel for my hobbyist game-design doodling, but this stuff is just making me remember that I once (like a decade or two ago) started a project to make RPGMaker-style trees for, like, all the conifers and maybe some of the broadleafs as well.

I do not have time to delve back into pixel art.  I really hope my Muse doesn't pick up this idea and run with it, not right now.

But anyway!  Thank you for creating this set.  The trees really look neat, and I like how the shadows make it feel more defined.  And the car looks pretty darn sweet!

Thank you!  That was fast, and it's much easier to understand now.  I appreciate the update!

"Use the asset only in one (1) end product or game title."
Does this mean that in order to use the assets in a second end product, one must pay for a second copy of the assets?

Also, I assume this implies that if the games never get to the public-distribution phase, they don't count, but if the game gets to public distribution (beyond alpha stage?), it counts even if it's distributed for free instead of for money.

Looking forward to this one!  I do so love seeing old game mechanics given new life in new contexts.  (Have you played Hexcells Infinite?)  The combination of the two types makes this especially appealing.

Since people mentioned colors: If you haven't yet accounted for colorblind players, I hope you consider adding at least a couple of color scheme options so players can figure out one that works well for them.  I'm not colorblind (though one of my nephews is, and he comes over a lot), but I often like the colorblind sets more than the normal sets -- for example, in Mini Metro.  And greater color choice is always a plus.

(Someday I'm gonna run across a game that repurposes Backgammon as some war between Girl Scouts selling cookies and chasing off the rival gang.  I've long felt that Backgammon mechanics would suit a game for younger players if it had cutesy graphics and some more interesting context.)

What?  Dang.  Yet another game incompatible with my Dvorak.  Still, I tend to assume that a lot of games in environments like this are from hobbyist devs who are still at the stage of "throw things at the wall and see what sticks."  So I'm not too bothered by it; I don't expect full compatibility from this level of game design.

(By contrast, a full-fledged game from a professional studio has no excuse for having hard-coded keyboard controls.  See "Sherlock Holmes: The Devil's Daughter", which I was managing to fumble along with until the eavesdropping mechanic required manipulating one cursor with the mouse and the other with the keyboard, simultaneously, as they randomly move away from the target.)

Actually, related to that: Have you ever played Puzzle Pirates?  The gameplay is based around a lot of different minigames.  It'd be neat if this game eventually got a couple new minigames for different aspects of gameplay.  Or gave an option of which of three types of minigames is the one you'd like to play for alchemy, so there's a bit of a switch-up and it's not quite so tedious at times.

Lastly (for now): I know it's low priority, but I wish I could choose the color hierarchy for the minigame.  I love purple, but it only shows up when the game is complex enough that it's not so fun anymore.  When I finally get enough experience in the game to make it easier and more fun, the purple's gone!  I'd love to be able to set the colors in some menu, individually, either ordering the colors I've discovered so far, or specifically choosing custom colors for each difficulty level.  Also, would be kinda nice if getting a high score at the game gave you an extra potion (if you were doing at least X potions).  Say that for every four potions you're making at once, there's a chance of a fifth potion, so if you were making 12 potions, you could conceivably get back 15 (some chance of getting 13, lower chance of getting 14, very low chance of getting 15), and it's based on how well you played the game.  Also, would be neat to have a bonus round of some sort if you get the potion done and there's still X seconds left on the clock, but only when it's not the easiest level (because that would get tedious).  Maybe an option for which level is the lowest level that bonus rounds kick in on.

Is there a part of the GUI or whatever that indicates when the Eagledeen merchants happen? because right now, I just have to head over there and see if they're there, which wastes both in-game and out-game time.  (Why does traveling by portal to a nearby town waste a whole chunk of time, anyway?  Shouldn't portal travel be instant, but making use of an area (foraging, shopping, etc.) be the thing that makes time advance when you leave?)  A game that I pull out of my pocket at random times when I'm bored should not also be a game where I have to keep mental track of some sort of schedule within the game world.

I still can't find anyone who sharpens swords.  And why is it that broken swords stack, but tiny copper rings don't?  How long before I get the ability to enchant a ring (or a sword)?  Am I missing something here? something I ought to be doing instead of foraging through the dungeon areas, turning the stuff into potions, selling the potions in my shop, taking whichever quests the guild offers, and talking to random people at random times in the hope that something new pops up?

I've got multiple quests that basically just go "Hey, those guards are blocking the way, can't fulfill this quest yet."  What?  How long before the guards move?  It's been months of in-game time!  I beat the forest and I'm halfway through the temple area, just opened up the graveyard.  Why would I get a quest to deliver flower petals to a shopkeep in Eagledeen at a time when I can't enter any regular shops?  Why didn't the "go to Eagledeen" quest disappear once I went there, instead of constantly reminding me that I can't fulfill the next step yet?

When can I get/create a bigger backpack?  I assume from the silk?  When will I get recipes to make the silk into something I can sell?  (I've been selling low-quality silk, but saving the good quality for whichever item I can eventually make.)  Why does silk require alchemy, I mean seriously? it's a weird outlier.  Would be less immersion-breaking if I went and sold spiderweb to a specific merchant, and got paid the same price as it would take to buy silk from that merchant (in quantities limited by the amount of spiderweb I brought them).  Also, I'd love to be able to make cloth items and enchant them, or create potions whereby to enchant them, something like that, to sell them.

(Unbalanced ingredients is one of my pet peeves, from back when I was hooked on Facebook games.  Theirs was deliberate (trying to get you to buy the items you needed), but this one's just incidental.  Still, having a ton of something you can't use, that just takes up space, is irritating, and I hate to just destroy it (might need it later), and I'm always getting more of it.)

And I'd like to see an alchemist or magic user from a neighboring area, or one who's just starting out, use my shop to buy extra mats for their work.  That way I could get rid of all this extra slime ooze.  I've started fleeing slimes just to avoid the overstock, and I still get way too much extra from the Fighter Guild forays.  Maybe give us a way to squash slime into higher-level ingredients or something?  Donate it to the Mage Guild for points?  Use it as fertilizer to grow extra resources at home?

Also, why is it that nobody's buying my old armor or the cupcakes and cakes I bought from next door?  I can't appear to sell my old armor to the Eagledeen vendor, so it should be something I can sell in my shop.  Is it just that the right buyer hasn't entered yet? because I've had multiple times when the shop closes without any sales, though my shelves are stocked with cupcakes and such.