Hello denizens of the internet, this is KLabGames infrastructure engineer kensei. Today I’m going to talk about how we notify players when their health (or “HP”) has fully recovered in our mobile games.
The idea of “HP” is strongly tied to mobile games these days. Players receive a limited number of play tickets (a.k.a. “health” or “HP”) used to play the game. When these are used up, the player must wait until their health recovers on its own, or use some sort of in-game item to recharge their health. Naturally, many players choose to wait until their HP recovers before playing again.
What if there was a way to let players know exactly when their HP was fully recovered? It would certainly improve the overall gaming experience, saving both time and effort for the player.
One of the ways we let players know when their HP has fully recovered is to send them a message via local push notifications.
Think Global, Act Local
According to Apple’s Documentation, local notifications are scheduled for sending by the application itself.
As long as the app isn’t running in the foreground, a notification, icon badge and sound is sent to the user when the clock strikes the preset time. If the app is running in the foreground, users will be alerted with a simple notification.
Android implements local push notifications via AlarmManager and NotificationBuilder.
The most important part about sending HP recovery notifications is remembering to cancel unnecessary notifications. Smartphones are always multi-tasking. There’s no telling when a player will pause the game to switch to some other task before picking up where they left off.
What happens if you send a local push message via timer in this situation? If you don’t cancel the process, the notification will hit the player in the middle of their game after they've resumed gameplay.
What happens if a player uses some of their HP, or uses an item to recover all of their HP? If you don’t cancel the notification, you’ll end up sending a recovery notification when their HP isn’t fully recharged or long after it’s fully recovered.
Canceling Requests: Timing is Everything
So, when should you send cancellation requests?
For KLabGames’ titles, we always run cancellation processes at the three points mentioned below.
When the app is launched.
The number of seconds the HP needs to fully recover is retrieved when the game first makes contact with the server and is stored on the device. A cancellation is processed if this number is already at 0.
If the time it takes to reach full HP > 0 seconds, a cancellation request is sent just before the local push timer is set.
Here’s the logic behind each of the points listed above.
There’s no need for a notification when the app first starts up, so the notification is canceled.
The second time the app connects to the server, multiple APIs are used to calculate the amount of time it will take to fully recover the HP on the server side. The result is then returned to the app.
Notifications can be canceled when a player uses an item to recover their HP, or recovers their HP by leveling up.
For the third point, in order to keep the local notification timer constantly updated, a cancellation process is run right before setting the timer for the local push message.
By keeping only one timer set and up-to-date at all times, you can be sure not to send any false alarms, avoiding any unnecessary “whoopsies” and other slip-ups.
When sending full HP recovery notifications, the most important thing to remember is to make sure you’re only setting one timer, and that you’re constantly updating it. Wait, what? That’s two things...
I made a few samples which run on iOS and Android.
So here I’ve got a game that only lets players use and recover their HP. Perhaps in some twisted universe, you could call this program a game. I made it in a hurry so I apologize if it’s a bit buggy.
Quick Overview of the Program
When the app is launched
When the HP use button is pressed
When the HP recover button is pressed
Pause recovery time (when the app returns from running in the background)
Calculate the amount of time passed while the timer was stopped. Leave the amount of time passed for HP recovery up to the update function.
Processing the Local Push Notification
Create the client plugin, then encapsulate the different processes to be run per platform. Initialization, local push notification settings and local push notification cancellations are all bridged via Unity’s native code.
On iOS, local push notification processes are set to Unity standards.
LocalNotification l = new LocalNotification();
l.applicationIconBadgeNumber = 1;
l.fireDate = System.DateTime.Now.AddSeconds(10);
l.alertBody = "test";
However, you can’t do really complicated things like sending local push notifications that repeat themselves.
That’s why I decided to use the native code from the start to implement my local push notifications. Additionally, local push notifications for iOS8 require permission from the user. In order to get the user’s permission, I’ve extended part of the UnityAppController we imported.
The native code for each platform is initialized on startup.
Local Push Notification Settings
Call native code.
Create an instance of UILocalNotification, then pass it to UIApplication.
Create an instance of intent we’ll use to pass to the receiver. Set intent so that it receives LocalNotificationReceiver.
Set the time you plan to end the event in your Calendar instance. The end time is set in seconds in the sample I made.
Set the intent and Calendar you created inside AlarmManager.
Receive information from intent.
Create Notification and notify the player.
Cancelling Local Push Notifications
Call native code.
Receive all of UILocalNotification from UIApplication.
Cancel anything that matches with notificationId.
Retreive the Action that matches the PendingIntent.
Send a cancellation request to AlarmManager.