1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Low FPS Auto-clean

Discussion in 'Loader' started by kaito_ishiyama, Sep 7, 2014.

  1. kaito_ishiyama

    kaito_ishiyama Potential Patron

    Joined:
    Oct 16, 2013
    Messages:
    5
    Likes Received:
    0
    Whenever I am using the Loader (Version 5.39) the game is constantly alerting me of low FPS and it auto-cleans the spit/cum/etc. every 2 seconds. I find this especially annoying since visually you cannot tell the FPS is low (game is running flawlessly) and each time he comes the cum is cleaned before it even lands on her. Is there a fix for this or can someone please try looking into it? Thanks.
     

    Attached Files:

  2. aztlan

    aztlan Swell Supporter

    Joined:
    Sep 14, 2013
    Messages:
    507
    Likes Received:
    15
    I believe it is from DA 3.0. This does this to enable it to keep FPS > 10, which is necessary to consistently detect input commands for dialogues. Or at least that's my understanding. What is your FPS when this happens?
     
  3. kaito_ishiyama

    kaito_ishiyama Potential Patron

    Joined:
    Oct 16, 2013
    Messages:
    5
    Likes Received:
    0
    I do not know but if it's from DA 3.0 that's most likely the source on my end. I downloaded both the updated loader and DA 3.0 at the same time so I haven't really focus my attention to DA 3.0 being the cause. Is there any way to bypass DA 3.0's fps check/correction?
     
  4. kaito_ishiyama

    kaito_ishiyama Potential Patron

    Joined:
    Oct 16, 2013
    Messages:
    5
    Likes Received:
    0
    DA 3.0 is the source of the auto-cleaning spit/cum. I have no idea how I overlooked the little bit of info posted in the .rar but that's so source. Now if I could just disable that little feature....
     
  5. aztlan

    aztlan Swell Supporter

    Joined:
    Sep 14, 2013
    Messages:
    507
    Likes Received:
    15
    Are you using strandlimitV3 by sby? (under the s-z spoilerin http://www.sdtmods.com/index.php?topic=2888.0 ) I use this and never see the alert you mention even though I also use DA 3.0.
     
  6. kaito_ishiyama

    kaito_ishiyama Potential Patron

    Joined:
    Oct 16, 2013
    Messages:
    5
    Likes Received:
    0
    I'm not but I'll install it and see if it makes a difference.
     
  7. kaito_ishiyama

    kaito_ishiyama Potential Patron

    Joined:
    Oct 16, 2013
    Messages:
    5
    Likes Received:
    0
    It stills cleans up the strands, even before there's any on screen. I have to bring the flash down to medium quality for it to run smoothly without auto-cleaning.
     
  8. Pim_gd

    Pim_gd Swell Supporter

    Joined:
    Jan 25, 2013
    Messages:
    718
    Likes Received:
    46
    You'll have to ask WeeWillie about that. I can hack it out for you but WeeWillie is the one that's working on DA these days.

    He just doesn't seem to get the idea of release management though; I'd never keep a version that's altered but not ready for release without fixing the issues with it as soon as possible.
     
  9. ModGuy

    ModGuy Club Regular Content Creator

    Joined:
    Feb 17, 2011
    Messages:
    1,754
    Likes Received:
    22
    Pick one.

    EDIT:

    Neither do any of us.

    Anyway, Flash is laggy. Press Escape to see FPS. Should be 30 ish.
     
  10. sby

    sby Club Regular Content Creator

    Joined:
    Sep 11, 2012
    Messages:
    1,331
    Likes Received:
    73
    lol 30 ish, isn't that max?
    i usually get 25 with medium quality and low strand quality. it'll dip down to 22 with some strands on screen
     
  11. Pim_gd

    Pim_gd Swell Supporter

    Joined:
    Jan 25, 2013
    Messages:
    718
    Likes Received:
    46
    I don't keep a version of DialogueChecker or DialogueActions that contains many changes but is not ready for release yet. And if I did I'd likely to be working on it.
     
  12. ModGuy

    ModGuy Club Regular Content Creator

    Joined:
    Feb 17, 2011
    Messages:
    1,754
    Likes Received:
    22
    So you don't like things unfinished. Either you're meticulous or just plan well. I can't say I have any sources in an unfinished state but I'm never quite in the mood to upload them.
     
  13. WeeWillie

    WeeWillie Casual Client Content Creator

    Joined:
    Nov 8, 2013
    Messages:
    339
    Likes Received:
    13
    I just noticed this thread.

    #1. Isn't this working as designed? Hit ESC and see your frame rate. I bet its less then 10, and if the strands and cum weren't being cleaned up, I bet you would notice that the game is coming to a crawl. As such, I wouldn't want to yank that functionality it out of 3.0 unless somebody else can come up with a better solution for SDT framerate issues on a decent machine.

    #2. I'm not sure I understand Pim's comment on understanding release management? In my mind, DA3.0 is not broken, even given this thread. So what am I doing wrong?

    #3. I don't really enjoy making DA releases. I enjoy making complex dialogs. I just wanted new functionality for my dialogs and Pim disappeared for a time so I had to build it myself. If people don't like how I handle DA3.0, then I'm perfectly fine with saying DA3.1 (I have a local version with a fix and new functionality that I need for my new project) is only to be used by me, and Pim can take DA over and we just branch. The source for DA3.0 is posted. I always do a bundle anyway, so a DA_WeeWillie3.01 would just be used by my dialogs (and if you are running at less than 10fps with my dialogs, they tend to break horribly).

    Any thoughts from anybody?
     
  14. Pim_gd

    Pim_gd Swell Supporter

    Joined:
    Jan 25, 2013
    Messages:
    718
    Likes Received:
    46
    It's okay if you want to keep working on stuff for yourself.
    For DialogueActions, which a lot of people use, it'd be far better to release new functionality as you add it, once you've verified it works. That's because others may then start to use this functionality. You'll get feedback (hopefully, but the content creators [writers] are a lot more vocal than content consumers [regular users]). This feedback contains ideas you might like, or improvements, or what have you.

    Regarding release management; that's from a bit more professional level where you keep development, testing, acceptance and production separate. The notion that making a change would cause a branch is not that concerning; the notion that making a change would cause a branch that can't easily be merged when you're not in the process of a major overhaul is far more worrying.
     
  15. WeeWillie

    WeeWillie Casual Client Content Creator

    Joined:
    Nov 8, 2013
    Messages:
    339
    Likes Received:
    13
    Okay, sounds good. Maybe I'll put work on my dialogue project on hold, and focus more on adding the things I need to DA first and get 3.1 into shippable shape and release it. That way, you (Pim) can take over working on it again if it suites your fancy.

    And one of the things I'll try to add is a settings configuration so individuals can disable the clean strands hack.

    It would also be good for Pim_gd to review a fix I put in to VA where integers weren't working as global variables properly. I'm not 100% comfortable with my change, but the fix works under my test cases.
     
  16. Pim_gd

    Pim_gd Swell Supporter

    Joined:
    Jan 25, 2013
    Messages:
    718
    Likes Received:
    46
    I'd need source to review the fix...
     
  17. WeeWillie

    WeeWillie Casual Client Content Creator

    Joined:
    Nov 8, 2013
    Messages:
    339
    Likes Received:
    13
    Of course I'd publish the source at the same time I publish the mod. Regarding the specific change, I can give you a sneak peak though.

    A change I made was that for my save game addition, global variables now have a corresponding local variable of the same name. For example, you make a global variable of "gMyVar", there will be a local variable of gMyVar. That local variable is manipulated by the dialog. When you load a save, the globals are loaded and then are copied to their counterpart. When you make a save, the locals are written to the globals, then the globals are written to the file. This is to keep from having to manually copy variables back and forth between local and global.

    Independent to that though, I was encountering errors trying to set global variables with integer values. I've made the following changes to VariableArithmeticTriggers.as
    Code:
    		public function setGlobalVariableByNameI(name:String, value:String):void {
    			variables[name] = m.getVariableManager().getVariableValueViaSDT(value);
    			// Added by Wee Willie, 8/27/2014, global variables always have a regular counterpart.
    			setVariableI(name, variables[name]);
    		}
    		
    		public function loadGlobalVariable(name:String):void {
    			var value:String = variables[name];
    			if (value != null) {
    				// Changed by Wee Willie, 8/27/2014, handle integer variables properly.
    				//m.getVariableManager().setVariableValueViaSDT(name, variables[name]);
    				setVariableI(name, variables[name]);
    			} else {
    				m.displayMessageRed("No global variable " + name + " is known. (on trigger: [VA_LOAD_GLOBALVARIABLE_" + name + "]");
    			}
    		}
    
     
  18. Pim_gd

    Pim_gd Swell Supporter

    Joined:
    Jan 25, 2013
    Messages:
    718
    Likes Received:
    46
    How the hell did that piece of code work again... I'm fairly certain you broke some advanced feature with your change, but what you tried is good and it's simple to apply the fix in proper. Gimme a sec...

    setGlobalVariableByNameI is the implementation of setGlobalVariableByName, the function that serves as entry point for both the trigger and other classes. setGlobalVariableByName handles array arguments unpacking to the proper fields.

    setGlobalVariableByNameI then stores the value in DialogueActions's memory by pulling it from the game. It does so via the variableManager... and getVariableValueViaSDT. getVariableValueViaSDT is normally used for VariableArithmetic's Arithmetic functions; that is, for *x > 6*, it sees "x", ">" and "6". x is not in the operator list so it's retrieved from SDT, > is in the operator list so it's returned as >, and 6 is returned as empty string since it's not a defined variable. Empty string is then disregarded, turning the whole thing (if x is 7) into *7 > 6*. Then it's parsed.

    In this case, getVariableValueViaSDT is used to retrieve the value of a single variable. So that gets you the value of the variable (or empty string if it isn't declared).
    This is then stored in DialogueActions's memory. No bugs there.

    You added saving to a local variable; this is a mistake and should be removed. If you wish to keep your dialogue variables in line with global variables, use "[VA_SETGLOBALVARIABLEBYNAME_globalVar_localVar][VA_LOADGLOBALVARIABLE_globalVar]" OR "[VA_SETGLOBALVARIABLEBYNAME_globalVar_localVar][VA_SETVARIABLEBYNAME_globalVar_localVar]"

    Keep global and local namespaces separate please.

    Second function, loadGlobalVariable.
    It's directly called from a trigger and external functions.

    It attempts to pull a variable from DialogueActions's memory. The else case handles the situation where that variable is not available; if that's the case then an error is displayed. If the variable IS available... it applies the variable from SDT via the VariableManager and the function setVariableValueViaSDT. It explicitly not uses the value variable to support numerics. I wonder what I did wrong.
    The setVariableValueViaSDT function sets the variable via SDT. It does so by creating a new object (that's the {"set":{"variable":"value"}} section of a dialogue line) and passes it to SDT.
    However, DialogueActions unhooks the variable setter, instead acting as a filter for certain variables. So before SDT gets this object, DialogueActions receives it and passes it through onVariableWrite which passes it to the VariableManager, function variableWrite.

    The variable write function...
    Code:
    public function variableWrite(variables:*) {
    			var varname:* = null;
                var value:* = null;
                for (varname in variables)
                {
                    //g.dialogueControl.advancedController.outputLog("Variable " + varname + " found");
    				//g.dialogueControl.advancedController.outputLog("rest" + variables);
                    value = variables[varname];
    				var result:* = setVariableValue(varname, value);
    				if (result != undefined) {
    					continue;
    				}
                    if (value is String && !isNaN(Number(value)))
                    {
                        if (!g.dialogueControl.advancedController._dialogueDataStore.hasOwnProperty(varname))
                        {
                            g.dialogueControl.advancedController._dialogueDataStore[varname] = 0;
                        }
                        if ((value as String).charAt(0) == "-")
                        {
                            g.dialogueControl.advancedController._dialogueDataStore[varname] = g.dialogueControl.advancedController._dialogueDataStore[varname] + Number(value);
                           // g.dialogueControl.advancedController.outputLog(varname + ": " + "decrement by " + Number(value) + " = " + g.dialogueControl.advancedController._dialogueDataStore[varname]);
                        }
                        else if ((value as String).charAt(0) == "+")
                        {
                            g.dialogueControl.advancedController._dialogueDataStore[varname] = g.dialogueControl.advancedController._dialogueDataStore[varname] + Number(value);
                            //g.dialogueControl.advancedController.outputLog(varname + ": " + "increment by " + Number(value) + " = " + g.dialogueControl.advancedController._dialogueDataStore[varname]);
                        }
                        continue;
                    }
                    //g.dialogueControl.advancedController.outputLog("Storing " + varname + " = " + value);
                    g.dialogueControl.advancedController._dialogueDataStore[varname] = value;
                }
                return;
    		}
    
    Iterates over each property of this object (each "variable" section of the set object), then for each iteration...
    Gets the value and passes it to the function setVariableValue, together with the name. This is the interception layer of DialogueActions: If you were to write to a color element of a piece of clothing (da.clothes.tops.r for instance), it passes the value on via here. But that's not the case here, so we'll move on. variableWrite then checks if the variable set was processed by the interception filter; if it was not, we continue setting the variable.
    If the value is a string, and converting it to a number does NOT give an error, we...
    - Check if the variable already exists, if not, create it and set it to 0.
    - Check if the first character of the value is "-", if so, add the number to the current value (3 + -2 = 1, 3 - -2 = 5. Don't be a fool like me, thinking someone wrote a bug here). If not, check if the first character of the value is "+", if so, add the number to the current value.
    - Then go to the next variable in the object.
    Guess what happens when you pass in the string "10". It's a string, it's a valid number, it does not have + in front, it does not have - in front. Yep... it doesn't get set. Whoops. I made a mistake.
    This mistake however is NOT the fault of setVariableValue. Don't go haxxing in there: SDT natively ignores {"set":{"variable":"10"}}, and DA shouldn't support that. Interfere as little as you can when messing with unhooked functions, as other mods might rely on this functionality.

    If the whole statement "value is a string, and converting it to a number does NOT give an error" is false, we just set the value as normal.

    How to fix?
    Option #1: Check if number and positive, if so add a +. This has as a downside that if the current value is 10, and you do a load, you'll get 20. Not good.
    Option #2: Cast to number. This means the "value is a string" will get bypassed. Then the value will be set as normal, but properly.
    Option #3 (Yours): Use setVariableI. This means... what?

    setVariableI checks if the variable's value starts with +=. If so, strip the +=, and use setVariableValueViaSDT with Option #1 to support numerics.
    If the variable's value starts with -=, strip the -=, multiply the variable by -1 (10*-1 = -10, -10 * -1 = 10), then use setVariableValueViaSDT with Option #1 to support numerics.
    If neither of those checks succeed, check if the variable's value is a valid number. If so, use setVariableValueViaSDT with Option #2 to support numberics. If it's not so, pass it as normal.

    What does this mean?

    Option #1 is plain bad. It does the wrong thing; it can mean you'll end up with different values than intended.
    Option #2 is pretty good. It allows interceptions to still occur (god knows what evil you're up to if you use a special variable as a global... ... maybe an external charcode?).
    Option #3 is decent, but comes with side effects. If you have a variable that contains += or -= at the start, fun stuff will happen. That is, things that you didn't expect.

    So the proper fix here would be to cast to Number, if the variable is a number.

    Suggested Implementation of these two functions:

    Code:
      public function setGlobalVariableByNameI(name:String, value:String):void {
       variables[name] = m.getVariableManager().getVariableValueViaSDT(value);
       //don't save to a local variable; if you want to store an intercepted variable for later use (charcode? Dynamic dialogue loading?), doing so ruins it
      }
      
      public function loadGlobalVariable(name:String):void {
       var value:String = variables[name];
       if (value != null) {
        var valueAsNumber:Number = Number(value);
        if(isNaN(valueAsNumber)){
         m.getVariableManager().setVariableValueViaSDT(name, variables[name]);
        } else {
         m.getVariableManager().setVariableValueViaSDT(name, valueAsNumber);
        }
       } else {
        m.displayMessageRed("No global variable " + name + " is known. (on trigger: [VA_LOAD_GLOBALVARIABLE_" + name + "]");
       }
      }
    

    Nothing you did was particularily bad; you did remove a pretty powerful function though, and introduced a weird side case where variables with += and -= in them at the start would be treated weirdly.

    That powerful function is this:

    restart:"I'm up for some kinky stuff.[nextDialogue]"
    nextDialogue:"[VA_LOADGLOBALVARIABLE_da.dialogue.load][VA_SETVARIABLEBYNAME_da.dialogue.load_normalNextDialogue]" {"style":"Thought"}

    That snippet does the following:
    - Tell the player about a scene switch on a restart
    - Go to the nextDialogue line
    - attempt to load the global variable da.dialogue.load, which will load a dialogue. Like this, you could have an easy way for a player to link a dialogue together.
    - If that fails, load the dialogue you'd normally load. (Dialogue lines are stopped when a dialogue is loaded)

    All cases I can think of where you'd use something like this work better when you use separate variables to store the things, but if you badly want more performance you can use this to cut out a character of delay (you'd have to do a load global and then a set versus a load global... a trigger takes 1 character to execute, so +1 character performance like this.)

    I hope you learned something of this long post (and I don't mean that in a bad way like "don't mess around in things you don't know", more like "hey, you wanna know how the DialogueActions mod works internally?").
     
  19. WeeWillie

    WeeWillie Casual Client Content Creator

    Joined:
    Nov 8, 2013
    Messages:
    339
    Likes Received:
    13
    Discussion continued in http://www.sdtmods.com/index.php?topic=5876.0 since this has drifted far form the low FPS auto-clean :)