Changes in data after game was inactive - iphone

I'm starting to work on an app similar to tamagotchi (virtual pet kind of stuff) in the Corona SDK. I got absolutely stuck and am out of ideas on how to get one part.
How can the game character, lets say "pet" change its status, e.g. become hungry or die while the game is inactive? Or maybe its possible to make the changes as the player enters the game the next time, maybe to bind it to the global time (still no idea of how to do it)?
I would appreciate any help.

The simplest I can think is to keep all relevant data in a file. The first datum would be a time stamp of the last time the game was turned inactive.
Every time the game is first activated it reads the file along with the time stamp. After a specific time length has passed the pet becomes hungry, tired, etc. If an extraordinary long time has passed the pet dies.
You can go further by putting a time stamp next to each datum like "last fed", "last watered", etc. and then you can make individual attributes expire at different times, including death by boredom by keeping the global "last active" time and if a long time has passed without running the game the pet dies.

I actually created an application like this. I created a number of states in a enum and then in a checkMoodState method I hardcoded the values that decided the state of the mood.
e.g.
timeSinceLastPlay
timeSinceLastFeed
or whatever.
Either write the dates to a plist for each variable you want to track and on each check or store them in NSUserDefaults(one function to write them all, one to load them all), subtract the current time from it. You will be left with a negative number, and you can just get its absolute value.
You decide whenever you want to check the last time since whatever it is you are checking, e.g. feeding. Create an NSTimer with the duration of the time between checks and in the method called by the timer, you do you checks and update the mood as you need.

Related

Different Pseudo Clock for groups of Facts

I am new to drools / fusion (7.x) and am not sure how to solve this requirement. Assume I have event objects as Event{long: timestamp, id: string} where id identifies a physical asset (like tractor) and timestamp represents the time the event fired relative to the asset. In my scenario these Events do not arrive in my system in 'real-time', meaning they can be seconds, minutes or even days late. And my rules system needs to monitor multiple assets. Given this, when rules are evaluate the clock needs to be relative to the asset being monitored, it can't be a clock that spans assets.
I'm aware of Pseudo Clock, is there a way to assign Pseudo clocks per Asset?
My assumption is that a clock must always progress forward or temporal functions will not work properly. Take for the example the following scenario:
Fact A for Asset 1 arrive at 1:00 it is inserted into memory and rules fired. Then Fact B arrives for same Asset 1 at 2:00. It too is inserted and rules fired. Now Fact Z arrives for Asset 2 at 1:30 (- 30 minutes from clock). I'm assuming I shouldn't simply progress the clock backwards and evaluate, furthermore I'd want to set the clock back to 2:00 since that was the "latest" data I received. Now assume I am monitoring thousands of assets, all sending data at different times...
The best way I can think to address this is to keep a clock per asset and then save the engine state when each assets data is evaluated. Can individual KieSession's have different clocks, or is it at a container level?
Sample rule: When Fact 1 arrives after Fact 2 for the same Asset.
You're approaching the problem incorrectly. Regardless of whether you're using a realtime or psuedo clock, you're using a clock. You can't say "Fact #1 use clock A, and Fact #2 use clock B."
Instead you should be leveraging the metadata tags for events, specifically the #timestamp tag. This tag indicates to Drools that a specific field inside of the event is actually the timestamp for the Event, rather than the actual time the fact enters working memory.
For example:
import com.example.SampleEvent
declare SampleEvent
#role( event )
// this field is actually in the object, it's not the time the fact was inserted
#timestamp( createdDateTime )
end
Not knowing anything about what your rules are actually doing, the major issue I can foresee here is that if your rules rely on the temporal operators or define an expiry (#expires), they're not going to work and you'll need to redesign them. Especially for expirations: once an event expires, it is removed from working memory; when your out-of-band events come in any previously expired events are already gone and can't be worked against.
Of course that concern would be true regardless of whether you use #timestamp or your original "different psuedo clock" plan. Either way you're going to have to manage the fact that events cannot live forever in working memory -- you will eventually run out of resources and your system will crash. Events must be evicted at some point, so you'll need to design around that in both your models and your rules.

Is this the best way to set CoreData entity variables to 0 every day at 24:00?

I currently have a coreData entity called CalorieProgress, which I would like to reset all variables (calorieProgress, fatProgress) to 0, every day.
I am still quite new to SwiftUI, and the only method I thought of as of now, is to add a Date Created variable to this entity called created, and when the user opens the app, to check if that date was yesterday. If so set all values to 0 etc.
Is there a more efficient way to do this?
Thanks
Your design is good and simple, and a reasonable choice if you're getting started.
It can have trouble, however, when people move between time zones. It is even possible for people to move to previous days this way (most dramatically when they cross the date line). There is no single answer to that question. Your app has to decide what it means by "today" when strange clock events happen. (Users also sometimes change their clock, and you want to behave "reasonably" in those cases, even if it means the data is wrong.)
Having built several of these, my suggestion is to just store raw, immutable, data records, and work out things like resetting values when you're running queries. For example, to work out how many calories someone has burned "today" doesn't require that you set any value to zero. You can just perform a query for records that occur after some time and sum their calories (you can even do this with aggregate queries directly on Core Data).
Core Data can be very fast, but if these queries become too slow, you can store daily aggregation records in Core Data. But keeping the original raw data means that those are really just caches and you can throw them away and recompute any time you need to.
Assuming that a new day starts as midnight (I've worked on apps where days started "when the user wakes up in the morning" which is much more complicated...) you should also be aware of significantTimeChangeNotification which is posted at midnight (and a few other times). You can't use this to launch your app or do processing in the background, but it's very nice for updating your UI if the user has the app open.

How do I get the time spent for a particular agent (from MHL) at a particular node?

I am interested in capturing the time a particular material handler(AGV in my case) spends at a particular node before it is released. Is there a way to do so?
This works in general, since I don't know anything about your model (there are many other ways depending on what you are doing):
Create a variable and make it equal to time when your AGV arrives to the node:
timeWhenArrivesToNode=time();
Create another variable and make it equal to the amount of time it spent in that node... This code should be executed at the moment when the AGV leaves the node:
timesWhenItIsReleased=time()-timeWhenArrivesToNode;
Of course the answer will have the time units of your model.

In Maximo, how do I get in between workflow process whether data in the table has been modified?

I want to show a different option to the user in workflow through input node, depending upon whether the user has modified the record or not.
Problem is if I would use a condition node with custom class to detect whether object has been modified by some person or not in between the workflow process then as soon as the person clicks on route workflow the save is automatically called and isModified() flag gets false, How do I get in condition node whether some person has modified the record or not.
I have to show different options to the user if he has modified and different option on routing workflow if he have not modified.
Sounds to me like you need to enable eAudit on the object and then to check whether eauditusername on the most recent audit record for that object bears the userid of the current user.
It's a little hokey and tempts fate, but if your condition node is early in the workflow's route when this button is pressed, you could try and check to see if the changedate on the object (assuming you are working with one of the many objects that has one) is within the last 5 seconds. There is a gap where the record could be routed twice within a few seconds, but the gap is fairly hard to hit. There is also a gap where if the system slows down at that point and takes more than 5 seconds to get to and run your condition, then it would appear to be not modified. You can play with the delay to find a sweet spot of the fewest false positives and negatives.

GameKit turn timeout

GameKit allow us to end a turn with a timeout for the next participant in the match. However, I couldn't find a way to set a timeout for the first participant for its first move. Is there anyway to do that?
EDIT
It started to make sense to me why Apple would leave this out from GameKit. When you just join a GKTurnBasedMatch you will always be in turn so there's no need for a timeout considering that it was added to avoid frustration on players while waiting too long for their turn. The thing is that my use case for a timeout is different. I'm designing a tournament and a timeout means that you lost the match, no matter it's the first turn or not. So I always need to have the ability to timeout the current turn. I'm afraid I'll need to implement this on the server which just sucks.
Might be a little late on this one, but Game Center TBM timeouts don't work like that.
When you call endTurnWithNextParticipants you must provide a list of players that will receive the turn if the previous one times out. If you want a player to lose the game when he/she times out, you must implement this e.g. on the client of the next player that receives the turn, Apple serves won't do this for you.
Based on what you're aiming for, I think the best implementation would be to check for the time the latest turn was played, or the match creation time in case it's the first turn, compare it to the current system date and time and programmatically end the match if time is over.
Like you point out, as player1 on turn1, there aren't any other players yet, so I suspect that's why GC doesn't give us an interface to set the timeout for player1.
How about setting an NSTimer to the desired timeout, and then ending the turn when it fires?
If you're looking at a long timeout, say a few days, where the user might leave and then rejoin after the timeout, you could calculate the desired deadline by adding the timeout interval to the match start time, and store that in NSUserDefaults. On each game startup, check if the deadline has passed, and end the turn when appropriate.