Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

Is there any way to calculate ingame time passed between script runs if game was saved/loaded?

Discussion in 'Programming Questions and Suggestions' started by krypt-lynx, Jul 7, 2017.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. krypt-lynx Apprentice Engineer

    Messages:
    175
    There is IMyGridProgramRuntimeInfo.TimeSinceLastRun, but it returns 0 after game load.
    Also description says "This property returns no valid data neither in the constructor nor the Save method.", so, I can't just save passed time in Storage variable.
     
  2. Malware Master Engineer

    Messages:
    9,510
    "Save" does not nullify this. The reason it returns 0 after game load is simply because there has been no measurements yet. There has literally been 0 time since the last time the PB was run. It has no concept of persistence. This is purely a runtime measurement, nothing else. The reason it doesn't return a valid value in Save is because the context has been lost: the save is not run in the normal PB context, it's run in the game's save context.

    You can, of course, store the value yourself to use in the Save method.
     
  3. krypt-lynx Apprentice Engineer

    Messages:
    175
    > You can, of course, store the value yourself to use in the Save method.
    Weeellll.... It means i need to make my script to run each logic tick ("TriggerNow") spam Storage variable. I don't want to. Even if will not kill performance I don't like this solution.

    Imo, the best solution is to add ingame clock variable (scaled ingame time passed from world creation) and make it accessible from scripts. It is simple and it is reliable. Is where a chance for it to be implemented?
    --- Automerge ---
    Also there is some weirdness with game saving and "TriggerNow" action (I'm creating bugreport about it right now), pribably part of the actions, triggered then saving happens, not going into savegame file:
    Part 1:

    Part 2:


    And also, some strange behavior with .TryRun, it is the next in the list.
     
    Last edited: Jul 7, 2017
  4. Malware Master Engineer

    Messages:
    9,510
    You can do that yourself by adding up the TimeSinceLastRun and... Oh, I forget what it's called, it times the actual run time of your script. I'm sorry, I'm not at "the right computer". You don't have to spam the storage variable, you do that only at the Save call. I agree it's not an ideal solution.

    The "chance for it to be implemented" is negligible I'm afraid, as you probably know Keen's priority for the PB is close to nil - for the foreseeable future at least.

    I don't contribute any more. I got too involved.
     
  5. krypt-lynx Apprentice Engineer

    Messages:
    175
    Thanks, it probably will enough. I need to start script periodically in periods with precision higher then a second and already have timer and ability to start it from the script.
     
  6. Regn Trainee Engineer

    Messages:
    74
    I don't normally like to use "Start" and "Trigger Now", but I had to do it now because it seems to be the only way of spreading numerous heavy iterations across intervals.

    PHP:
    static int interval 0;
    void Main(string a){
        
    interval++; if (interval 2147483647interval 0;
        if (
    interval == {
            
    // Do
        
    }
    }
    I count blocks, inventories, items, ores, ingots, and do all my procedures each in their own interval. E.g.

    PHP:
    // Update ores and ingots in intervals
    string[] abbrs = { "Fe""Ni""Co""Mg""Si""Ag""Au""Pt""U""Gravel""Ice" };
    for (
    byte i 0abbrs.Count<string>(); i++) {
        if (
    interval % (1) == 0UpdateIngots(abbrs[i], items);
    }
    The default "0" values are stored outside Main().

    I think this is the closest you can get to anything resembling DeltaTime, but I could be wrong.
     
    Last edited: Jul 28, 2017
  7. Martin R Wolfe Trainee Engineer

    Messages:
    80
    What I do when I need to keep track of an elapsed time or time passed since last run is something like this:-
    Code:
            DateTime LastRun;
    
            public Program()
            {
                LastRun = DateTime.Now;
                if (Storage != String.Empty)
                {
                    long ReadIntervall;
                    if (long.TryParse(Storage, out ReadIntervall))
                    {
                        LastRun += new TimeSpan(ReadIntervall);
                    }
                }
            }
    
            public void Save()
            {
                Storage = (DateTime.Now - LastRun).Ticks.ToString();
            }
    
            public void Main(string Arguments)
            {
                var TimeElapsedSinceLastRun = (DateTime.Now - LastRun).TotalSeconds;
                LastRun = DateTime.Now;
    
                if (TimeElapsedSinceLastRun > 0.001)
                {
                    //Do stuff once a milisecond
                }
                if (TimeElapsedSinceLastRun > 0.1)
                {
                    //Do stuff ten times a second
                }
                if (TimeElapsedSinceLastRun > 1)
                {
                    //Do stuff once a second
                }
            }
    
     
    Last edited: Jul 28, 2017
    • Like Like x 1
    • Disagree Disagree x 1
  8. krypt-lynx Apprentice Engineer

    Messages:
    175
    Well... Stuff was required for my Sequencer v2 script (you can found it in workshop). And all is much more complicated:
    https://github.com/krypt-lynx/SE-Se...quencer2/Script/neighbours/TimerController.cs
    P.S.: I see an issue in my code.
    --- Automerge ---
    Also, you cannot use DateTime.Now - LastRun. It gives you unscaled time. It works only while your simspeed is 1.0
    --- Automerge ---
    Well, known delay calculation obstacles:

    - Timer can tick with step of 0.16sec. Yes, you cannot wait exactly 1 sec. It is 1.12 sec.
    - "Start" does not work in "Program()" if "TriggerNow" was called right before game save.
    - "TriggerNow" usually does not work after savegame load. But sometimes does.
    - There is no direct way to calculate time passed since script load.
    - You cannot access TimeSinceLastRun from Save()
    - You cannot use DateTime class because of simspeed.
     
    Last edited: Jul 28, 2017
  9. Martin R Wolfe Trainee Engineer

    Messages:
    80
    The solution to this is to have the timer in it's actions to have both start the timer and trigger now. I usually put Start in slot 8 and trigger in slot 9 with the timer set at 1second. That way under normal conditions trigger now will fire the timer and under a game reload the regular countdown will trigger the timer and set the trigger now going again.
     
  10. krypt-lynx Apprentice Engineer

    Messages:
    175
  11. Regn Trainee Engineer

    Messages:
    74
    PHP:
    var format TimeSpan.FromSeconds(OxygenLeftInSeconds);
    This is about the only time-related thing I've used in Space Engineers so far that I know works, but I don't know if you can apply it to fit your needs in some way.

    I've never had issues with Start+Trigger Now, and I have roughly 600 hours on record. Maby I've just been lucky, who knows.

    Timer Block (1 second)
    1 - Programmable block
    2 - Programmable block
    8 - Trigger Now
    9 - Start

    But, like I said, I prefer not to do that because I feel like I'm spamming the server.
     
  12. krypt-lynx Apprentice Engineer

    Messages:
    175
    I'm ended with same timer configuration. But it looks like it works only because... "костыль" is used somethere in the code to make it work.
    "костыль" is "crutch" in Russian. Also it is IT-related slang, means some quick and dirty solution. This word have some negligent meaning. I don't know how to say it in English with same expression.


    Originally I tried to start timer from PB:
    Timer Block (value written by PB)
    1 - Programmable block

    It works until you does not calling TriggerNow.
     
    Last edited: Jul 28, 2017
  13. Regn Trainee Engineer

    Messages:
    74
    Is it possible to pass commands between PB's? If it is, then it is perhaps possible to count the number of times the commands was passed back and forth.

    "Hello, PB1!"
    "Hello, PB2!"
    "Hello, PB1!"
    "Hello, PB2"

    *shrug* I dunno. I should try it myself but it's 4 in the morning. I should get to bed :S
     
  14. krypt-lynx Apprentice Engineer

    Messages:
    175
Thread Status:
This last post in this thread was made more than 31 days old.