Device clock... do processes keep running when an app is inactive?
tatiang
Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
I'm wondering if there is any way to harness the device clock to determine how much time has passed between making an app inactive and then active again.
I was able to make an app keep track of the amount of time between closing/quitting an app and opening it again, and I can certainly track time while an app is active (every 1 second, add 1 second to game.timer), but when I switch apps and come back to the app, I can't figure out a way to keep track of the time that has passed. I can't use a timer because the app isn't active (in the foreground) and when I switch back to the app, my rules don't re-trigger because they've already run.
Am I out of luck?
I tried a simple test:
Change Attribute game.deviceMinutes (real) to game.Clock.Minute
DisplayText game.deviceMinutes --> works "once" when the app is first launched but does not update again until the app has been force-quit and re-opened.
DisplayText game.Clock.Minute --> always shows the current minute of the device's internal clock
Both of those DisplayText behaviors work as I would expect in the iOS Viewer (they both update when the app is made active).
Attached is the very simple project file I used to test this after I figured out what the issue was.
I was able to make an app keep track of the amount of time between closing/quitting an app and opening it again, and I can certainly track time while an app is active (every 1 second, add 1 second to game.timer), but when I switch apps and come back to the app, I can't figure out a way to keep track of the time that has passed. I can't use a timer because the app isn't active (in the foreground) and when I switch back to the app, my rules don't re-trigger because they've already run.
Am I out of luck?
I tried a simple test:
Change Attribute game.deviceMinutes (real) to game.Clock.Minute
DisplayText game.deviceMinutes --> works "once" when the app is first launched but does not update again until the app has been force-quit and re-opened.
DisplayText game.Clock.Minute --> always shows the current minute of the device's internal clock
Both of those DisplayText behaviors work as I would expect in the iOS Viewer (they both update when the app is made active).
Attached is the very simple project file I used to test this after I figured out what the issue was.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Best Answer
-
RThurman Posts: 2,880@tatiang -- I don't recall anyone ever asking this before. A brand new question!
I don't have an answer but can ask a few questions. Is this an issue of the device clock or is it an issue of determining when an app comes back into focus?
Do processes keep running when an app is inactive? That is -- do things keep moving/spawning/updating when an app is inactive?
If processes stop when the app is inactive, could you make a pseudo clock by spawning an actor every 10th of a second and have that actor increment a global attribute. Then when the app goes dormant -- and then later reactivates -- it would resume tracking the spawn count where it left off. (Destroy each spawned actor after it has incremented the count.)
Just some questions and an idea.
Answers
And yes, thanks for boiling down my wordy post so efficiently:
"Do processes keep running when an app is inactive?" I think not, but I hope so!
After I posted this, I tried a variation of your suggestion (I hadn't read your response then, but I'll try the spawn count). I tried updating the device seconds every one second and comparing it to the device clock using load/save attribute behaviors (too confusing to explain it all here!) to see if it increased more than a second or two -- which would indicate that the app had been inactive for a period of time. It didn't work, but I had that same thought, so maybe there is a way.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
I kind of hope that processes don't keep running in the background of an inactive app. For example, if an actor quits moving when the app goes inactive, and then starts moving again when the app is refocused -- then you could use it's position as a time-stamp of sorts.
Yeah, the save/load attributes thing is making my brain hurt. I feel like I have the right idea but no idea how to perfect it. Time will tell (ha!).
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Back to the spawn thing. If you record the begining time (at the same time as spawn count = 0). Then when the app resumes, you check the difference between device time and spawn time (er.. count). The difference is the time that the app was inactive.
Edit: I'll be pretty embarrassed when someone answers with a simple solution to this. (Rather than slapping some rube goldberg workaround together.) Its probably something blindingly easy.
But okay, the tricky part is where you say "when the app resumes, you check the difference between device time and spawnStartTime." Sounds good in theory but... how? You can't just say Change Attribute game.elapsedTime to game.deviceTime-game.spawnStartTime. You'd have to wrap it in an every 1 second timer or something. And so how do you know when the elapsed time is due to an inactive app and when its due to time passing while the app is active?
(re: your earlier point about an actor moving, I did check and an actor interpolating its position will pause and resume movement).
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
Edit: hmm, maybe I can use that after all.
When attribute self.Time < game.timeStampCurrent - game.timeStampStart - [some number of seconds]
.....[the app was reactivated]
The way I've started thinking about it is this:
Imagine you have an app that pauses itself at random times and then unpauses itself at random times. You have no access to the pause/unpause behaviors to know when they occur. How do you determine how long the app is paused for?
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
My GameSalad Academy Courses! ◦ Check out my quality templates! ◦ Add me on Skype: braydon_sfx
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
I should have explained better about the file. I scrapped the previous idea (of spawning timers) in favor of @FryingBaconStudio's great hint. He indicated that self.time pauses when an app suspends. He said to compare self.time to overall time (um... game.time) to see when discrepancies arise. I assumed that he meant that any discrepancy between self.time and game.time could supply two pieces of information: 1) that there was a pause --or an inactive period, and 2) how long that inactive period was.
The file I submitted does show that this is true when a game is officially paused. My question is -- does it also work when an app is suspended and reactivated? I am not currently in a position to do an adhoc test to see if works when an app is suspended and then resumes. I was hoping someone could test it out.
@RThurman that was exactly what I was thinking.
Guru Video Channel | Lost Oasis Games | FRYING BACON STUDIOS
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Thanks for taking time to test it out.
Set deviceStart to # of seconds since January 1, 2013
Constrain deviceNow to # of seconds since January 1, 2013
When selfTime < deviceNow - deviceStart - 1 + timeStamp
.....Amount of inactive time elapsed = deviceNow - deviceStart - (self.Time-timeStamp)
.....Change timeStamp to self.Time
.....Change deviceStart to # of seconds since January 1, 2013
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
When someone completely quits an app i.e when it is no longer running in background.
To:
The next time they open the app.
Is that right? If so they have to come to the first scene when launching the app from being closed. So you could add some attributes that track when the first scene to be opened is scene 1. (so they have not navigated there from another scene)
e.g when going from scene 2 to scene 1:
change game.CameFromScene2 to true.
and in scene1 (in one of the last layers):
change game.TimesOnScene1 to game.TimesOnScene1 +1
Then if game.CameFromScene2 is false
And game.TimesOnScene1 is 0
You know they have come to scene1 because the app was launched, not because they navigated there from any other scene.
So at that point you could could take snapshots of the device clock, save them and compare the difference.
Unless I have misunderstood?
Launch app -----> switch -----> resume -----> switch -----> resume
Between the switch and the resume above is the time I'm interested in. I think I have it... stay tuned.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Thanks guys! I have a headache now. @-)
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
And thanks for posting a nice solution to your own question. I think this will come in handy for many GS developers.
I wonder if anyone will be able to develop more optimized solution? Let the contest begin!
Okay, sorry for digging this one up, but it's a nice thread and it's exactly what I need for my new game.
I used the template @tatiang made. It's very good and works adhoc when inactive and using an other app for example, but my main question is, and I really can't seem to find any thread where the answer lies.. what if the app gets closed down completely and restarted. The way @tatiang made it.. it will not count inactive seconds, this will stay 0.
Very curious for this one since I want my hero to lose life energy when people close this app and come back after for example 24 hours.
I was thinking like. A save time attribute every minute in the game.
When game starts > load time attribute. Make a rule that says current time attribute - loaded time attribute = certainnumberhere. And make certain rules that comply to this certainnumberhere, like for example when someone is gone for 22 hours.
When attribute currenttimeattribute-loadedtimeattribute = 22, attribute energy - 50.
But these rules make me rather dizzy then really giving me comfort, not sure if Im thinking right. Not such a math wonder.
Goodboi Gamestudios | Monster Jumper now on the App Store
Unless I'm mis-remembering, @tatiang's template does exactly what you're after @BasGoodboy. It doesn't matter if the game is inactive or completely closed.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
Correct, @Armelline, my template counts both the time that has elapsed during app use and the time elapsed while the app is backgrounded or closed. The file I posted above is incomplete, though, since it was an early attempt at all of this.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
@tatiang do you maybe have a complete file you would like to share? I would like to use it as a basic for my new app, sort of tamagotchi thing, where the hero actor will lose life when not on the app for like some hours.
EDIT: I noticed this is a template in your shop.
Goodboi Gamestudios | Monster Jumper now on the App Store