1

I have a function in a SpriteKit Game that adds a "life" to the user every 5 minutes

startTimer = NSTimer.scheduledTimerWithTimeInterval(300, target: self, selector: #selector(GameScene.addLife), userInfo: nil, repeats: true)

But when the user closes the app this code is killed and there is no way to calculate the amount of life the users has to get when they open back the app.

I wondering how can I count the amount of time since the user closed the app so that I can calculate the amount of life to give.

I was thinking about using NSUserDefaults to store the time right before they closed the app and when they reopen calculate the amount of time from that but the problem is the user can change their time and thus get extra life as a "hack".

Does anyone know how to solve this?

Kervon Ryan
  • 684
  • 1
  • 10
  • 20
  • You cannot prevent the user from changing the device time. See http://stackoverflow.com/questions/12119845/preventing-time-change-cheating-in-game and http://stackoverflow.com/questions/11413616/is-there-a-clock-in-ios-that-can-be-used-that-cannot-be-changed-by-the-user for some ideas, such as using an external time server. – Martin R Sep 05 '16 at 08:58
  • Thanks @MartinR one question though. What if the user doesn't have an internet connection? – Kervon Ryan Sep 05 '16 at 21:55

1 Answers1

3

I agree with the Martin R comment. A good way is to use an external time server.

As explained many times during NSTimer discussions and in this SO answer, in Sprite Kit do not use NSTimer, performSelector:afterDelay: or Grand Central Dispatch (GCD, ie any dispatch_... method) because these timing methods ignore a node's, scene's or the view's paused state.

You can use SKAction to create your timer, if you have some difficult to do it try to take a look at this SO answer.

Community
  • 1
  • 1
Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
  • Well he actually wants to ignore the scenes pause state, so he has the right idea going, and NSTimer will work well when staying in the app, he just needs to handle leaving the app and handling time changes – Knight0fDragon Sep 05 '16 at 19:54
  • @Knight0fDragon how do you know that he wants to ignore the paused state ? – Alessandro Ornano Sep 05 '16 at 20:32
  • Because he wants life to replenish when the app is not active, so this means he wants it based on real time, not scene time – Knight0fDragon Sep 05 '16 at 20:33
  • Probably but we dont know his code and we dont know at which point in the game loop they are executed which can cause a variety of issues depending on what his code actually does so I think the best advice remains SKAction – Alessandro Ornano Sep 05 '16 at 21:00
  • No it isn't man, he wants his life to replenish every X minutes real time, you use an SKAction, then speed up the node, you no longer have X minutes you now have X/Y minutes where y is the speed of the node. Also, When the app closes, the scene pauses, so if he wanted it based on scene time, this question becomes irrelevant because 0 scene seconds happen from the time the app closes to the time the app reopens – Knight0fDragon Sep 05 '16 at 21:36
  • @KervonRyan then you need to make an executive decision, in my F2P model, I disable the replenish timer till an internet connection can be found, then they get the amount they would have received if connected online, up to double max, again, you have to make your own choice – Knight0fDragon Sep 05 '16 at 22:05
  • @Knight0fDragon You shouldnt speed up a node where you have launch an action timer, you could have need to know when the game is in start state and when the game is over to change lifes number if occurs, and this must be reflected to the action timer that change the life number to give a sense to these gifts – Alessandro Ornano Sep 05 '16 at 22:07
  • You obviously have no understanding of how scene time and real time works. Imagine creating a bullet time effect, how do you plan on doing that? You half the speed of the scene, double the speed of your player node. That would screw up the life replenish counter, and doubling the life replenish speed does not make sense logically, it is just a hack. – Knight0fDragon Sep 05 '16 at 22:12
  • @Knight0fDragon You dont understand my comment. Anyway you want to create two entities, the game and the timer, and for me it doesnt make sense according to the gifts you could give to the winner – Alessandro Ornano Sep 05 '16 at 22:16
  • I do, you are talking about adding more hacks and having to keep track of different node speeds to counter act scene time. You need to keep real time and scene time separate. Do not make hacks inside of the scene to simulate real time, you will just create situations where you will create bugs. I am not sure what gifts to the winner has to do with anything. We are talking about how F2P models work, where every X minutes in real time, a player is given a life so that they may play another round – Knight0fDragon Sep 05 '16 at 22:22
  • @Knight0fDragon You could create a bullet time effect starting from an SKNode because each node have speed property, it doesnt necessary to use skscene.In my games Ive just used this effect without slowly the intere scene. – Alessandro Ornano Sep 05 '16 at 22:23
  • Yes, there are lots of ways to do things, I was trying to keep it simple for you so you could understand why it is important to separate real time from scene time – Knight0fDragon Sep 05 '16 at 22:25
  • @Knight0fDragon What happened if i lost a match i lost a life but the timer fire a new life in that exact moment? You lose but win at the same time? I dont understand why you want to handle these situations without know the code, i think you should be based to the tradional game flows.. – Alessandro Ornano Sep 05 '16 at 22:30
  • You use your life before the game starts, not after you finish, lives in this case are like quarters you put into an arcade machine – Knight0fDragon Sep 05 '16 at 22:31
  • This could be done if you use only one life for match: what happened if you start an hard level, you playing for a long time and you lost the life but the timer give you another life 3 seconds before you lost :) the player can see he have 2 lifes but the game end ( im the devil lawyer eheheh) – Alessandro Ornano Sep 05 '16 at 22:42
  • @KervonRyan Martin R has your answer, I am just letting Alessandro know that this is not the time to be using SKActions, 9 out of 10, you want to do what he is explaining, you however have that 1 out of 10 scenario – Knight0fDragon Sep 06 '16 at 00:18
  • Sorry guys I read just now due to my time zone. Thank you both for the interesting conversation @KervonRyan Try to do an analysis on paper of all the circumstances that your game faces, after that choose your way. – Alessandro Ornano Sep 06 '16 at 06:50
  • @AlessandroOrnano, I do not think you are familiar with the F2P model. You never auto consume credit, you pop a message that says, you died, do you want to use another life. At this point the user can wait for a life to replenish, or buy lives. (Or, you create 2 credit systems like a lot of games do, and have the second credit replenish the first) – Knight0fDragon Sep 06 '16 at 13:33
  • @Knight0fDragon The F2P model is not restricted to your comment details, in fact in many games you can consume all lifes and if you want you can see some ads to gain new lifes or buy credits especially because many games like shoot'em up are games where you frequently die, i cannot imagine in a game like Metal Slug to see everytime a popup message like "do you want to use another life?" – Alessandro Ornano Sep 06 '16 at 13:52
  • no, in your example, the definition of "life" is not the same definition of "life" that the OP is using, that is why I used the term "Credit" not "Life". One "Credit" may buy you 5 lives, but if you run out of those 5 lives, then you should be prompted to continue to use a "Credit". Otherwise you will piss off a lot of consumers, because you are essentially stealing money(Credits are a form of currency) from them without there permission – Knight0fDragon Sep 06 '16 at 13:55
  • Ah ok, I agree with this definition. – Alessandro Ornano Sep 06 '16 at 13:56
  • I use NSTimer.scheduledTimerWithTimeInterval, and when the app goes in inactive, I save the goal data in NSUserDefault and iCloud. When the app restart, check all goal data, if is expired, increase life by 1, if not restart timer. – Simone Pistecchia Sep 07 '16 at 07:31