Any way to get sdt to remember what clothes a girl had in the beggining?

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
I want to make a progressive dialogue on a daily based system. So when you hit "End Day", most things will reset back to normal, one of which will be her clothes. I'd like to have the player be able to fully choose what her normal clothes should be. Is there any way to store and then load her original clothes back?
 

stuntcock

Staff member
Moderator
Joined
Jun 5, 2012
Is there any way to store and then load her original clothes back?
Are "normal clothes" and "original clothes" the same thing? When the player clicks "End Day", does it restore a set of clothing which they chose on Day 0? Or do you mean that the player is free to change clothing during the day ... but at the end of each day it restores a set of clothes which SkyHeart SkyHeart specified while writing the dialogue?

I assume that we intend to reapply a player-chosen outfit at the end of each day, but I just want to be sure. I'm imagining that the game would begin on Day 0. Instead of a "Next Day" button they'd see a "Begin" button. Before pressing the "Begin" button, they're supposed to costumize the outfit. It would then be saved, and their choice would be re-applied at the end of each day. Does that sound correct?

Note: I'm also assuming that customization would be based on the moreClothing mod. If the user manually loads a bunch of random SWF files then it would be difficult for the dialogue to reapply them all.

Can we assume that the entire dialogue will play out during one session? In other words: if the player presses Alt+F4 then they'll lose all progress; the next session will start over on Day 0 and they'll need to choose a new outfit. It's quite easy to store charCodes in memory, but saving them to disk (and then recalling them later on) requires scripting. The latter approach is feasible; you've probably already seen it accomplished in Slave Bazaar. It just requires more work and more testing.
 

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
Are "normal clothes" and "original clothes" the same thing?
Yes they are

does it restore a set of clothing which they chose on Day 0? Or do you mean that the player is free to change clothing during the day ... but at the end of each day it restores a set of clothes which SkyHeart SkyHeart specified while writing the dialogue?
They choose a set of clothing from day 0 that is re-applied at the end of the day until the player decides to switch to an outfit created by me (like fetish gear or cat girl)

Can we assume that the entire dialogue will play out during one session?
I'd like to be able to save progres since the end goal is to train the girl to your liking. Maybe it should be done at the end of each day?

I'm imagining that the game would begin on Day 0. Instead of a "Next Day" button they'd see a "Begin" button. Before pressing the "Begin" button, they're supposed to costumize the outfit. It would then be saved, and their choice would be re-applied at the end of each day. Does that sound correct?
I was thinking that the dialogue coulb save the outfit the girl is wearing when the dialogue is loaded but it's the same thing.
Yes, the chosen outfit would be re-applied at the end of each day

By scripting you mean something done in the dialouge file or a mod by itslef like weewille's mod or sby's more triggers?

Please keep in mind that this is my first dialogue (a little too ambitious for a start, i know). I did took some time to test triggers and how to work with basic dialogue actions commands (like da.clothes, da.breathPercentace) but i never really understood how saving and loading variables work. Are there any tutorials dedicated to it or do I have through a dialogue that uses it?
 

stuntcock

Staff member
Moderator
Joined
Jun 5, 2012
Are there any tutorials dedicated to it
Variable set and check statements are covered in the comprehensive dialogue guide written by @Slingerbult. There's also a more recent guide written by Pim_gd Pim_gd which covers topics such as mod integration. DialogueActions is documented separately.

I don't think that there's a tutorial for the advanced dialogues, in the sense of "let's start with a blank text file and then gradually build up a complex story step-by-step." Instead, I think that you're supposed to write a very short story which demonstrates each of the necessary features or concepts. Once you've figured out how to make everything work, then you can settle down and start filling in all of the actual content (storylines, attitudes, speech inflections, custom sexual positions, etc). If you begin writing before you've mastered the tools and syntax then you'll probably regret it (because you'll end up doing things "the hard way" and you'll write scripts or scenes which are very brittle).

But I've never actually written a dialogue. Pim_gd Pim_gd or @Slingerbult or @DrZombi could probably give you some proper advice.

or do I have through a dialogue that uses it?
SDT dialogues are usually released in "plaintext" form. It's possible to package them inside SWF files but that's rarely done. TXT is more convenient for authors as well as end-users.

Since everything is released in plaintext, it's difficult to obfuscate how a dialogue works. But the logic flow within a dialogue can be very intricate (or haphazard). Even when you see the whole thing in front of you, you might not understand how it was designed.

Hence: you're free to study existing dialogue files and borrow snippets from another writer's work, but it would be much more useful to ask them first. Along with permission, they might be willing to offer advice and feedback.

Also: use the Dialogue Checker so that Pim_gd Pim_gd doesn't need to reply to your first release with "I found 706 errors in your file; here's a list..."

By scripting you mean something done in the dialouge file or a mod by itslef like weewille's mod or sby's more triggers?
Saving the game state requires a Loader mod; it cannot be done with a "vanilla" dialogue. DialogueActions provides a
SAVESETVARS trigger which allows you to write to an external file. Based on the idea that you've described thus far, DA should suffice for your needs. WeeWillie created a custom SWF file to support his Slave Bazaar mod, but it contained new graphics and sounds in addition to some custom AS3 code.

When all of that stuff is in-place, you must write special snippets of text within your dialogue file in order to invoke the external functions (such as showing on-screen buttons, saving a costume, slowly fading the screen to black, etc). Syntax is very important here; mismatched brackets can prevent your dialogue from running correctly -- and the game won't give you any on-screen feedback about why a failure has occurred. I'd recommend that you use the Flash Player projector content debugger in order to see exceptions as they occur, and to regularly use the Dialogue Checker tool to test for syntax errors in your writing.

You can also check the in-game dialogue log, but it's a bit minimal. It will tell you exactly which lines were played (which may be helpful if lines are getting pre-empted or interrupted), but it won't explain why any particular line was played.
 

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
DialogueActions is documented separately.
Well that's VERY usefull. Just found out that weewillie had this in his bundle too :grin:.

Saving the game state requires a Loader mod; it cannot be done with a "vanilla" dialogue. DialogueActions provides a
SAVESETVARS trigger which allows you to write to an external file. Based on the idea that you've described thus far, DA should suffice for your needs.
Guess I'll have to start experimenting
Thanks for the help, really appreciate it

Meanwhile,
If someone would be so kind to help me optimize this, because I have a hard time beliving that I'm anywhere near the most efficient way of doing it
act_b2:"[slap_s*RSC*]" {"style":"thought"}

slap_s0:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact0]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":80}}

SC1:"" {"style":"thought", "check":{"SCounter":"==4"}, "set":{"RSC":1}}

slap_s1:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact1]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":40}}

SC2:"" {"style":"thought", "check":{"SCounter":"==6"}, "set":{"RSC":2}}

slap_s2:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact2]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":0}}

SC3:"" {"style":"thought", "check":{"SCounter":"==8"}, "set":{"RSC":3}}

slap_s3:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact3]" {"style":"thought", "set":{"RSC":4, "da.breathPercentage":0, "da.oxygenPercentage":50}}

slap_s4:"[HOLD][RELEASE][SLAP]Б[HOLD][KNOCK_OUT]" {"style":"thought", "set":{"RSC":0}}
sreact<number> goes down to an appropriate reaction which then refers back to SC<number>
So my question is: How can I better check when SCouner is at the value that I want? Because I think that going through three lines will kind of ruin everything
 

Pim_gd

Club Regular
Joined
Jan 25, 2013
How do I make/edit buttons and menus? Making a big mod. That's a link to a post where I explain how WeeWillie's Bazaar works with regards to saving and loading of outfits. You could make use of this in order to create your own clothing system, but it's as easy as somehow saving all the variables in da.clothes and then loading them back in at a later point.

Code:
act_b2:"[slap_s*RSC*]" {"style":"thought"}

slap_s0:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact0]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":80}}

SC1:"" {"style":"thought", "check":{"SCounter":"==4"}, "set":{"RSC":1}}

slap_s1:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact1]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":40}}

SC2:"" {"style":"thought", "check":{"SCounter":"==6"}, "set":{"RSC":2}}

slap_s2:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact2]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":0}}

SC3:"" {"style":"thought", "check":{"SCounter":"==8"}, "set":{"RSC":3}}

slap_s3:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact3]" {"style":"thought", "set":{"RSC":4, "da.breathPercentage":0, "da.oxygenPercentage":50}}

slap_s4:"[HOLD][RELEASE][SLAP]Б[HOLD][KNOCK_OUT]" {"style":"thought", "set":{"RSC":0}}

Okay so the first thing here is that you have bad variable names. "SCounter" should probably be "SlapCounter" (or slapCounter, depending on whether you like PascalCase or camelCase). The bad variable names make it harder for me to read what your dialogue does.

It seems you have 4 entry points in this dialogue:

act_b2, SC1, SC2 and SC3. I think (again, that's because you use short line/variable names, so I have to guess) that act_b2 is a button handler. SC1, SC2 and SC3 seem like slap counter checks, but I have no idea how they're being called.

First, let me reorganize the lines so that they make sense for me.

Code:
act_b2:"[slap_s*RSC*]" {"style":"thought"}

slap_s0:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact0]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":80}}
slap_s1:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact1]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":40}}
slap_s2:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact2]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":0}}
slap_s3:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact3]" {"style":"thought", "set":{"RSC":4, "da.breathPercentage":0, "da.oxygenPercentage":50}}
slap_s4:"[HOLD][RELEASE][SLAP]Б[HOLD][KNOCK_OUT]" {"style":"thought", "set":{"RSC":0}}

SC1:"" {"style":"thought", "check":{"SCounter":"==4"}, "set":{"RSC":1}}
SC2:"" {"style":"thought", "check":{"SCounter":"==6"}, "set":{"RSC":2}}
SC3:"" {"style":"thought", "check":{"SCounter":"==8"}, "set":{"RSC":3}}

There we go, now we can see the duplication.

Let me point out the duplication for you:

Code:
slap_s0:"[HOLD][RELEASE][SLAP]Б[HOLD]
slap_s1:"[HOLD][RELEASE][SLAP]Б[HOLD]
slap_s2:"[HOLD][RELEASE][SLAP]Б[HOLD]
slap_s3:"[HOLD][RELEASE][SLAP]Б[HOLD]
slap_s4:"[HOLD][RELEASE][SLAP]Б[HOLD]

[OW][WINCE][ADD_TEARS][sreact0]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":80}}
[OW][WINCE][ADD_TEARS][sreact1]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":40}}
[OW][WINCE][ADD_TEARS][sreact2]" {"style":"thought", "set":{"SCounter":"+1", "da.breathPercentage":0}}
[OW][WINCE][ADD_TEARS][sreact3]" {"style":"thought", "set":{"RSC":4, "da.breathPercentage":0, "da.oxygenPercentage":50}}

That bit is duplicated. How do we fix this?

Normally I'd go on a long explanation of the low level bits, but you'll have to do your own legwork. There's various dialogue guides on this forum, I'm sure you can find some of the information there.

Code:
initial_settings:{"x":"*","slap0.breathPercentage":80,"slap1.breathPercentage":40,"slap2.breathPercentage":0, "slap3.breathPercentage":0,"slapCallback":""}

slapLine:"[SETVAR_RSC_*RSC + ( ( RSC == 3 ) x 1 )*][SETVAR_SCounter_*SCounter + ( ( RSC != 3 ) x 1 )*][SETVARBYNAEM_da.breathPercentage_slap*RSC*.breathPercentage][HOLD][RELEASE][SLAP]Б[HOLD][*slapCallback*]"

This is one of the ways, using a callback line. Not recommended in your case, as you can see I have to do all sorts of shenanigans to get the proper data into one line.

Instead, extract the animation:

Code:
initial_settings:{"x":"*","slapAnimation":"[HOLD][RELEASE][SLAP]Б[HOLD]","slapReactionNormal":"[OW][WINCE][ADD_TEARS]","triggerStart":"[","triggerEnd":"]","slapReactString":""}

doSlap:"[APPENDVARBYNAEM_slapReactString_triggerStart][APPENDVAR_slapReactString_sreact*RSC*][APPENDVARBYNAEM_slapReactString_triggerEnd][checkPreSlap*RSC*]" {"style":"Thought","set":{"slapReactString":""}}
checkPreSlap0:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":80}}
checkPreSlap1:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":40}}
checkPreSlap2:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":0}}
checkPreSlap3:"[playNormalSlap]" {"style":"Thought","set":{"RSC":4,"da.breathPercentage":0, "da.oxygenPercentage":50}}
checkPreSlap4:"[playSlap]" {"style":"Thought","set":{"slapReaction":"[KNOCK_OUT]"}}

playNormalSlap:"[SETVARBYNAEM_slapReaction_slapReactionNormal][APPENDVAR_slapReaction_slapReactString][playSlap]" {"style":"Thought"}

playSlap:"*slapAnimation**slapReaction*" {"style":"Thought"}

So, this took me a while to think up. First, SDT's format for providing variable values is pretty much okay. That is, this section:

Code:
checkPreSlap0:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":80}}
checkPreSlap1:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":40}}
checkPreSlap2:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":0}}
checkPreSlap3:"[playNormalSlap]" {"style":"Thought","set":{"RSC":4,"da.breathPercentage":0, "da.oxygenPercentage":50}}
So we should make use of that. This format you see is pretty flexible.
Code:
[SETVAR_RSC_*RSC + ( ( RSC == 3 ) x 1 )*][SETVAR_SCounter_*SCounter + ( ( RSC != 3 ) x 1 )*]
Whereas that format is set in stone.

How it works is like this.
Code:
doSlap:"[APPENDVARBYNAEM_slapReactString_triggerStart][APPENDVAR_slapReactString_sreact*RSC*][APPENDVARBYNAEM_slapReactString_triggerEnd][checkPreSlap*RSC*]" {"style":"Thought","set":{"slapReactString":""}}
First, with "set":{"slapReactString":""}, we clear the slapReactString. Then, once the line plays, we do the following:

[APPENDVARBYNAEM_slapReactString_triggerStart]
[APPENDVAR_slapReactString_sreact*RSC*]
[APPENDVARBYNAEM_slapReactString_triggerEnd]

This, in essence, is equal to

slapReactString += triggerStart
slapReactString += ("sreact" + RSC)
slapReactString += triggerEnd

Since we define triggerStart as [ and triggerEnd as ], you get

slapReactString += [
slapReactString += ("sreact" + RSC)
slapReactString += ]

So you're basically building [sreact*RSC*] with this.

Next is [checkPreSlap*RSC*] to move to the next line.

Code:
checkPreSlap0:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":80}}
checkPreSlap1:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":40}}
checkPreSlap2:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":0}}
checkPreSlap3:"[playNormalSlap]" {"style":"Thought","set":{"RSC":4,"da.breathPercentage":0, "da.oxygenPercentage":50}}
checkPreSlap4:"[playSlap]" {"style":"Thought","set":{"slapReaction":"[KNOCK_OUT]"}}
Since in your code, variables were set at the moment of the animation beginning, we can do the same. DialogueActions will cause lines with only triggers that don't have delays (anything that doesn't make stuff animate, basically) to play instantly (yes, infinite loops may freeze the game). So we can use as many triggers as we want.

Depending on RSC, we get to checkPreSlap0, 1, 2, 3 or 4. In there, I have placed the slap_s# line setters. For RSC 0-3, we call playNormalSlap, for RSC 4, we call playSlap with a slapReaction of [KNOCK_OUT].
Code:
playNormalSlap:"[SETVARBYNAEM_slapReaction_slapReactionNormal][APPENDVAR_slapReaction_slapReactString][playSlap]" {"style":"Thought"}
What playNormalSlap does is, first set slapReaction to the value in slapReactionNormal. Then append the trigger we have built in doSlap (the [sreact*RSC*] trigger). slapReactionNormal is defined in initial_settings. Next, playSlap is called.
Code:
playSlap:"*slapAnimation**slapReaction*" {"style":"Thought"}
If you arrive from playNormalSlap via checkPreSlap1, here's what will have happened:
Code:
doSlap:"[APPENDVARBYNAEM_slapReactString_triggerStart][APPENDVAR_slapReactString_sreact*RSC*][APPENDVARBYNAEM_slapReactString_triggerEnd][checkPreSlap*RSC*]" {"style":"Thought","set":{"slapReactString":""}}
First, slapReactString is cleared and then set to [sreact1].
Code:
checkPreSlap1:"[playNormalSlap]" {"style":"Thought","set":{"SCounter":"+1", "da.breathPercentage":40}}
CheckPreSlap1 is ran, increasing the SCounter and setting the breathPercentage to 40.
Code:
playNormalSlap:"[SETVARBYNAEM_slapReaction_slapReactionNormal][APPENDVAR_slapReaction_slapReactString][playSlap]" {"style":"Thought"}
PlayNormalSlap is ran, setting slapReaction to the value of slapReactionNormal, and then appending the sreact trigger. The resulting value of slapReaction is "[OW][WINCE][ADD_TEARS][sreact1]".
Code:
playSlap:"*slapAnimation**slapReaction*" {"style":"Thought"}
PlaySlap is executed, which plays the animation, and then the reaction. In our case, it expands like so:
Code:
playSlap:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact1]" {"style":"Thought"}
As a result, the animation and response are played, and sreact1 is fired.

Feel free to ask questions if you need to.
 

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
WOW.
"slapAnimation":"[HOLD][RELEASE][SLAP]Б[HOLD]"
First off, I had no idea I can set variables to play triggers like that.

slapReactString += triggerStart
slapReactString += ("sreact" + RSC)
slapReactString += triggerEnd

Since we define triggerStart as [ and triggerEnd as ], you get

slapReactString += [
slapReactString += ("sreact" + RSC)
slapReactString += ]
Or that I can chain variables into one trigger

"slapReactString":""
Does this set the variable to nothing? Like a NULL value?

I guess sreact# is a trigger that reffers to the line in which I'll be adding dialogue?

Thanks a lot, you, kind sir, have unstuck my dialouge.

Now that I get this and clothing out of the way, I'd like to start implementing the core idea of this dialouge which revolves around random events. So my question is: Does it work like this?

Lets say I have a trigger, we'll name it "enddayEvent", and two other triggers "normalEvent" and "randomEvent" and then I use it it will go to this:
Code:
enddayEvent:"[normalEvent]"
enddayEvent:"[normalEvent]"
enddayEvent:"[randomEvent]"
enddayEvent:"[normalEvent]"
Does the randomEvent have a 1/4 chances of happening? Are there any other things I have to keep in mind for this (Like if the ordering matters in some way)?

My idea was that, at the end of each day/night, there's a chance of, lets say 1/50 to get a random event. If no event happened in a while
then the probability for one to happen increases to 1/40, and so on until there's a 1/2 chance for one to happen

Does having a lot of choices for a trigger to choose from slow down the game or the dialogue? If so is it a big slow-down?
Or does it just play the first one it scans?

Note: There isn't any text or other triggers in the enddayEvent , It just dictates how the next day/night will start (randomEvent will probably load another dialogue with the specific event)
 

Pim_gd

Club Regular
Joined
Jan 25, 2013
Triggers will slow down the game because they're code. SDT dialogues aren't compiled, so a bunch of empty triggers would still eat time.

That said, if you rig SDT's dialogue system as such that it doesn't wait for character printing and instead just executes triggers (which is what DA does if you append your linename with _INSTANT, or if your line consists of only one trigger and it's a trigger that neither the game nor any of the mods know AKA line-reference trigger, a trigger that will select the next line to be played)...

It will go pretty fast.

I recall I had a discussion with WeeWillie one day about a slow dialogue...

Basically, the Bazaar has to load clothing stuff into variables and it does so by looping through a buncha stuff. This used to take about a minute. A minute of staring at a black screen waiting for the dialogue to "load".

This was fixed by adding the feature to append _INSTANT to a line name and having it just "do all the triggers" without printing text.

The result was that loading did not take long at all - about half a second or so. And that's about 300-500 or more triggers all doing various expensive stuff like loading character codes or copying large amounts of variables and saving stuff etc.

So basically, use _INSTANT for lines that have just code in them.

First off, I had no idea I can set variables to play triggers like that.
See the technical details section of this dialogue guide: Pim_gd's Advanced Dialogue Guide (v1.01 - updated 10 December 2013)

Specifically:
7) Play the random line that was picked by...
8) First applying the set and next line attributes.
9) Then converting percent encoded characters to real characters. This is why you might have to replace % for %25, if it's followed by two hexadecimal characters [REGEX: (%[A-F0-9]{2}) ]
10) Next up, inserting any variables and variable substitutions. When dealing with variable substitutions, they are replaced in this order: FINISHES, YOUR, YOU, ME, MY.
11) The line is played, character for character. When a trigger is found, it's checked for an action. If it doesn't have an action, the content of the trigger is set to be played as the next line. If it does have an action associated with it, that action is triggered and things will happen (Mood changes, coughing, looking up or down, etc...).
Set and next line attributes go first, then percent encoding, then variables, then the line plays. As the line plays, triggers happen.

Code:
"slapReactString":""
Does this set the variable to nothing? Like a NULL value?
It sets the variable to empty string.

I guess sreact# is a trigger that reffers to the line in which I'll be adding dialogue?
See your own dialogue:
Code:
slap_s0:"[HOLD][RELEASE][SLAP]Б[HOLD][OW][WINCE][ADD_TEARS][sreact0]"
It has sreact0 at the end of slap_s0, sreact1 at the end of slap_s1... so if the line to be played is determined by "slap_s" + RSC, then we just make the slap line contain the shared content + "[sreact" + RSC + "]".

Lets say I have a trigger, we'll name it "enddayEvent", and two other triggers "normalEvent" and "randomEvent" and then I use it it will go to this:
Code:
enddayEvent:"[normalEvent]"
enddayEvent:"[normalEvent]"
enddayEvent:"[randomEvent]"
enddayEvent:"[normalEvent]"
Does the randomEvent have a 1/4 chances of happening? Are there any other things I have to keep in mind for this (Like if the ordering matters in some way)?

My idea was that, at the end of each day/night, there's a chance of, lets say 1/50 to get a random event. If no event happened in a while
then the probability for one to happen increases to 1/40, and so on until there's a 1/2 chance for one to happen
Again, see the advanced dialogue guide:
(It's possible that steps 1 and 2 are reversed in order, and it's possible the checks are run only once, and the played line filtering is done later. It's not really relevant. It just does those things and you can't interrupt them.)
1) First, define the linetype that will be played. This is done by checking for if a next line is defined, and else going through a set of checks for things like pulled_up, pulled_down...
2) After having defined the linetype, get all the lines that are related to that linetype, and haven't been played yet. Now filter them based on check, mood, held and style (Speak + mouth filled is a no go).
3) If no line is found, clear the list of played lines for the linetype, then repeat step 2.
4) If no line is found after THAT check, stop trying to display a line (it's not possible, there are no lines playable).
5) If lines are found, pick a random one. Add that to the played lines.
6) If the played lines amount is equal to the lines amount for that line type, clear played lines list.
7) Play the random line that was picked by...
What this means is:
It picks a linetype to play - "enddayEvent", because that's the next line to play. Then it takes the ones of those lines it hasn't played yet, and filters them based on the constraints you have supplied. In your case, the default style is "Speak", so if her mouth is full, all the lines will be filtered out. If it has no lines left (either because all the lines were already played or because they were all filtered out), it resets the lines played list (This means that if you have 50 enddayEvent lines of which only 1 is the lucky one and they have default style or Speak style and she can't speak, the "counter" will reset!). If the lines played list was reset, it tries again. If it finds lines to play, it plays one random line out of that bunch, else it just stops.

Basically, if you need a one in two chance, duplicating your line is fine. If you need a 1 in 3 or 1 in 4 or 1 in 6, sure, duplicate!

If you need 1 in 50, use variables and da.random. I don't think the dialogue will get very slow with lots of lines (but it might, a bit), but it's still not ideal to just have 50 copies of the same frickin line.

The documentation for dialogueactions mentions how to use da.random: Pim_gd / SDTDialogueActions / source / Documentation / For Dialogue Writers / Variables.txt — Bitbucket
Code:
da.random {read only} - returns a random value between 0 and 1 (0 <= value < 1). Example usage to make it 1-10: (you'll have to define x as "*" in initial_settings to get access to multiplication operator) [VA_SET_VARIABLE_var1_*da.random x ( 10 - 1 + 1 ) \ 1 + 1*] - formula is ( random * ( max - min + 1 ) ) + min \ 1 + 1
Now, that's how to get a neatly rounded number. You don't care about neatly rounded numbers. Here's what you care about:

eventChance = 1 / ( difficulty - rollsMade )
success = randomRoll < eventChance

Where random roll is between 0 and 1. (Which is what da.random gives!)

Let's plug in some numbers (difficulty = 50)
1 / ( 50 - 0 ) = 1 / 50 = 0.02 (2%)
1 / ( 50 - 1 ) = 1 / 49 = 0.0204 (2%)
1 / ( 50 - 25 ) = 1 / 25 = 0.04 (4%)
1 / ( 50 - 49 ) = 1 / 1 = 1 (100%)

This is the same as SDT.

Code:
initial_settings:{"difficulty":50,"rollsMade":0}

start:"Rolling... [tryYourLuck*da.random < ( 1 / ( difficulty - rollsMade ) )*]"
tryYourLuck0:"Too bad... roll *rollsMade* failed.[start]" {"set":{"rollsMade":"+1"}}
tryYourLuck1:"Hurray!"
And if you want to, say, test your dialogue, you could temporarily change difficulty to 1. Or just increase the rollsMade from the start. That beats having to duplicate or delete lines just to set the difficulty.

Of course, SDT would, if given 49 "bad" lines and 1 "good" line, give you a proper random distribution containing 1 good line and 49 bad lines. The snippet I posted would give you, hmm, well, the bad line counter doesn't reset, and even then, the good line isn't taken out of the pool if it plays.

On the other hand, SDT will happily play all of the bad lines first before allowing you to play the good line again. So if you had the good line hit first, you'd be guaranteed 49 bad rolls in a row, because it filters for unplayed lines. Making use of variables allows you to have a more fine-tuned system with regards to randomization the lines that are played. SDT's system works best for simple randomization (1/3 chance, 1/4 chance) of non-repetitive events. SDT's system also works great for playing lines that the player hasn't seen yet (Basically, to prevent her from saying the same thing over and over and over again). It does NOT work well for randomization contraptions where it's important you have the correct chances to hit something.

Does having a lot of choices for a trigger to choose from slow down the game or the dialogue? If so is it a big slow-down?
Or does it just play the first one it scans?
I am not sure I completely understand your question.

Okay, so, the thing is... when you have the step where it checks for each line if the line is playable, you can see that duplicating lines for randomness causes slowdowns. As the amount of duplicated lines grows, so does the amount of lines that SDT needs to check. The finger that goes through the list has to move through all the entries one by one, so if the list is longer, it will take longer. (The real thing of interest might be the speed of the finger, though - if the finger moves at a rate of a million lines per second, you don't care. Computers are fast.)

But... look at this construct again.
Code:
start:"Rolling... [tryYourLuck*da.random < ( 1 / ( difficulty - rollsMade ) )*]"
tryYourLuck0:"Too bad... roll *rollsMade* failed.[start]" {"set":{"rollsMade":"+1"}}
tryYourLuck1:"Hurray!"
What really happens is this.

First, this line plays:
start:"Rolling... [tryYourLuck*da.random < ( 1 / ( difficulty - rollsMade ) )*]"

The variables are replaced...
*da.random < ( 1 / ( difficulty - rollsMade ) )* - DialogueActions first fills in the values...

*0.20456123 < ( 1 / ( 50 - 0 ) )* Then evaluates per subexpression...
*0.20456123 < ( 1 / 50 )* step
*0.20456123 < 0.02* by
*0* step.

Leaving you with this line:
start:"Rolling... [tryYourLuck0]"

Which is then played, printing "Rolling... " and then moving to the next line, "tryYourLuck0".

The thing is, there's only 1 line for "tryYourLuck0".
tryYourLuck0:"Too bad... roll *rollsMade* failed.[start]" {"set":{"rollsMade":"+1"}}

That one. And SDT thus only has to check 1 line to see if it can play.

Another way to look at this is that "slap_s" + RSC does not have to "look" and "decide" whether it should be "slap_s0", "slap_s1", "slap_s2" or some other string... it just concatenates (puts together) the two and the result is what line it will want to play.
 

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
Pim_gd Pim_gd
Sorry for responding so late, I've been trying all these things out and it works out great.
Thanks for responding so fast and detailed to my questions. Your mod is way more complex then I ever thought
Thanks again, I'll get to writing

One more question :grin: What do the "layers" do in the [COPYOBJECT] trigger. I think it refers to what layer of the object in copies to.

(From your "about object variables.txt")
[COPYOBJECT_1_Outfit1._da.clothes.] does it copy "da.clothes." to "Outfit1." ? If so,
(From weewille's slave bazaar, "Girl1.txt", it's the last time it finds "COPYOBJECT" in the file) [COPYOBJECT_0_lastOutfit._Slaves.slave1.CurrentOutfit.] Why is it "0" here and not "1"?
 
Last edited:

Pim_gd

Club Regular
Joined
Jan 25, 2013
SkyHeart SkyHeart

So, let's take a look at the documentation: Pim_gd / SDTDialogueActions / source / Documentation / For Dialogue Writers / Triggers.txt — Bitbucket

DialogueActions documentation regarding COPYOBJECT said:
[COPYOBJECT_layers_targetObjectVariable._sourceObjectVariable.] Copies all variable values from sourceObjectVariable to targetObjectVariable, up to <layers> deep. 0 layers means "all layers". Keep in mind that object variable notation requires a period at the end of the variable name. See "About object variables.txt" in the documentation for further details.
[COPYOBJECT_layers_targetObjectVariable._sourceObjectVariable._USING_structInfoVariable] COPYOBJECT, but uses structInfoVariable to determine which variables need to be copied. Only variables present in both structInfoVariable and sourceObjectVariable will be copied.
"0 layers means "all layers".".

The concept of layers isn't very well documented, though.

Here's the implementation: Pim_gd / SDTDialogueActions / source / src / VariableManager.as — Bitbucket

Code:
public function copyLocalObject(layers:Number, targetObjectVariable:String, sourceObjectVariable:String):void {
    var sourceVariables:Array = getLocalVariablesDenotedByObjectNotation(sourceObjectVariable);
    var periodCounter:uint = StringFunctions.countOccurances(sourceObjectVariable, ".");
    for (var i:uint = 0; i < sourceVariables.length; i++) {
        var variableName:String = sourceVariables[i];
        if (layers == 0 || (periodCounter + layers) >= StringFunctions.countOccurances(variableName, ".")) {
            var varValue:String = getVariableValueViaSDT(variableName);
            var varVal:Number = Number(varValue);
            if (isNaN(varVal)) {
                setVariableValueViaSDT(variableName.replace(sourceObjectVariable, targetObjectVariable), varValue);
            } else {
                setVariableValueViaSDT(variableName.replace(sourceObjectVariable, targetObjectVariable), varVal);
            }
        }
    }
}
What this does is look for all the variables that are contained "within" the object variable. For da.clothes, that would be da.clothes.panties, da.clothes.tops, but also da.clothes.panties.type or da.clothes.panties.r. The thing is, when you want to copy the values of clothing, you don't really want to store the individual rgb values. What would it mean if the clothing string stored in "da.clothes.panties" didn't match the subvariables (I don't know how this would happen, but still)? Thus the idea of being able to copy an amount of layers deep, by which you would be able to get "da.clothes.panties", but not "da.clothes.panties.r".

Basically, da = layer 1, da.clothes = layer 2, so if you wanted to copy everything directly under da., you'd copy da 1 layer deep (from 1 to 2).

If you need more explanation than this, please ask.
 

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
Thanks, got it now

Now, lipstick, skin color, eyeliner etc. don't get saved with da.clothes. Can those even be saved? Or do I have to make a big menu with a lot of [LOAD_CHARCODE]
 
Last edited:

Pim_gd

Club Regular
Joined
Jan 25, 2013
Those aren't exposed yet in DialogueActions. Sooo... yeah, you're probably stuck with making a large menu. I got a couple of days off coming up though, so I could add this in.
 

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
Was writing this while you PM-ed me. Please finish what you're doing first
:tongue::tongue::grin::grin::tongue::tongue::grin::grin:


Hi again Pim_gd Pim_gd :smile:.
Back on the topic of events, more specifically, remembering what events were played, or not
The way I do it, is with this variable: "Event.<type of event (Normal or Random) ><number of event>done". And this can take 3 values: 0 (Event not reached or denied), 1 (Event done CORRECTLY) or 2 (Event done WRONG).
So will look something like "Event.normal0done":"0"
I don't think there is another way to do it, keeping in mind that I want to specifically be able to remember which event happened and its result but it's always better to ask
 

Antimatter42

Content Creator
Joined
Sep 2, 2017
Location
Address Unknown
That said, if you rig SDT's dialogue system as such that it doesn't wait for character printing and instead just executes triggers (which is what DA does if you append your linename with _INSTANT, or if your line consists of only one trigger and it's a trigger that neither the game nor any of the mods know AKA line-reference trigger, a trigger that will select the next line to be played)...

It will go pretty fast.
So, for example, if I type this line:
Code:
intro_INSTANT:"[RIGHT_ARM_HIS_LEGS]This is a line."
This line will go by twice as fast?
 

SkyHeart

Avid Affiliate
Joined
Apr 17, 2017
So, for example, if I type this line:
Code:
intro_INSTANT:"[RIGHT_ARM_HIS_LEGS]This is a line."
This line will go by twice as fast?
Hi,
I think the answer would be no
You should use "_INSTANT" when you have a line that only has triggers.

For example:

Lets say we're coming from a menu only screen where both her and him are hidden into a scene where the player gets to fuck the girl.
So for this we want to set up a position, reset her clothes and go through all the SHOW_<PART> triggers, but we also want a bit of dialogue to play at the beggining of the scene

As such, instead of making only one line with triggers AND text like this:
Code:
customLineName:"[COPYOBJECT_0_da.clothes._var.whereWeStoredHerClothes.][ANIMTOOLS_positionName][END_FLASH][SHOW_HIM][SHOW_PENIS][SHOW_BALLS][SHOW_HER][SHOW_HAIR]Welcome to the new position"
We separate the text and triggers like this:
Code:
customLineName_setup_INSTANT:"[COPYOBJECT_0_da.clothes._var.whereWeStoredHerClothes.][ANIMTOOLS_positionName][END_FLASH][SHOW_HIM][SHOW_PENIS][SHOW_BALLS][SHOW_HER][SHOW_HAIR][customLineName_text]"
customLineName_text:"Welcome to the new position"
This way, the triggers get executed very fast and the text doesn't wait for any triggers

Hope this helps, If you have any further questions, don't hesitate to ask.
Happy writing!
 
Last edited:

Antimatter42

Content Creator
Joined
Sep 2, 2017
Location
Address Unknown
Hi,
I think the answer would be no
You should use "_INSTANT" when you have a line that only has triggers.

For example:

Lets say we're coming from a menu only screen where both her and him are hidden into a scene where the player gets to fuck the girl.
So for this we want to set up a position, reset her clothes and go through all the SHOW_<PART> triggers, but we also want a bit of dialogue to play at the beggining of the scene

As such, instead of making only one line with triggers AND text like this:
Code:
customLineName:"[COPYOBJECT_0_da.clothes._var.whereWeStoredHerClothes.][ANIMTOOLS_positionName][END_FLASH][SHOW_HIM][SHOW_PENIS][SHOW_BALLS][SHOW_HER][SHOW_HAIR]Welcome to the new position"
We separate the text and triggers like this:
Code:
customLineName_setup_INSTANT:"[COPYOBJECT_0_da.clothes._var.whereWeStoredHerClothes.][ANIMTOOLS_positionName][END_FLASH][SHOW_HIM][SHOW_PENIS][SHOW_BALLS][SHOW_HER][SHOW_HAIR][customLineName_text]"
customLineName_text:"Welcome to the new position"
This way, the triggers get executed very fast and the text doesn't wait for any triggers

Hope this helps, If you have any further questions, don't hesitate to ask.
Happy writing!
Grazi, mio amico (thanks, my friend)!
 

Antimatter42

Content Creator
Joined
Sep 2, 2017
Location
Address Unknown
By the way, how do I get SDT to read custom linetypes? I'm writing a loader dialogue with dialogueactions, and I am trying to get the game to read the linetype "initiating00." Thanks in advance for answering.
 
Top Bottom