The player can earn a small number of daily bonus points by logging in each day to incentivise them to use the game regularly. I did this by saving the unix time when they claim the bonus points, and then checking if the current unix time is more than 86400 seconds higher than the saved value.
I added a calm royalty free background song. This starts once the game loads after the user clicks play and is looped. When opening a song card, the background music continued on top of the music for that song. I stopped this by pausing the background music when the large display card was active and unpausing when it was closed. This worked for the song cards, however it also paused the music when viewing an achievement card. To fix this, I only paused the background song when the ID of the card shown was outside of the achievement ID range.
The set songs and outfits in the shop weren’t saving and persisting through play sessions. To save the items in the shop, I used global variables to store the shop IDs when the songs refresh, and these are saved. When the game loads, each shop button uses the saved ID to find the correct item to display.
I then added a timer in the shop to display how long is left until the shop items refresh. If the time left is above 86400 seconds, it is divided by 86400 to calculate the number of days. The remaining value is then used to do the same with 3600 to find the hours, and 60 for the minutes.
I adjusted the gem rates depending on the player’s activity level tracked from the onboarding questions. The aim of this was to allow players with different levels of activity to earn gems at a similar rate, so that players who do much more exercise than the average user won’t be able to speed through the game, and players who do less won’t be at a disadvantage. This equates to 20, 50 and 100 gems per 5km when running.
Earning points from activities is largely based on trust that users will not try to cheat the system for more points. However, I implemented one anti-cheat measure to try to prevent some cheating attempts. If the player does a run of at least 5km, the average speed is checked. The 5km world record is 25km/h, so if the activity has a speed greater than that, it will be cheated such as tracking an activity in a car. Activities only give points if the speed is less than this.
I decided to set this at the world record speed instead of a relatively fast speed to avoid false positives of legitimate fast runs. Smaller distance runs were not checked in this way as they give less points, so there is less incentive to cheat shorter runs, and GPS glitches could have a significant effect.
I considered removing points for manual activities as they could be easily exploited, but decided not to as the manual activity feature is not well known about, and players who use it legitimately would be annoyed if they didn’t receive points.
I added a developer mode where XP, gems and quest progress can be given individually. This makes debugging easier and allows users to test parts of the game without having to do activities. The status of the developer mode is saved so that it remains active through play sessions if turned on.
When opening the final achievement, the information wasn’t being shown. To fix this I used the existing achievement display code and adapted it to work for the final achievement’s card ID.
A couple of the album names in the collection were partially covered by the cards, so I adjusted the text size and position to stop this from happening.
The outfit buttons could be selected when the menu to customise the shoes was over them, which I fixed by making the custom shoe panel a raycast target.
The help button in the settings could only be clicked on certain parts of it. I looked for objects in front of it and found that although the text for the achievement display was blank, the object was blocking it so I stopped it from being a raycast target.
If the player opened an outfit tab, bought an outfit and then went back to the wardrobe, the outfit count would not be updated. This was because the text would only be set when an outfit tab was opened. To fix this I set the outfit count to update every frame so that it is still accurate when more outfits are unlocked.
There were a couple of issues with the background music. Viewing an achievement worked, but when swiping between achievements the background music was paused. I changed the swipe function to exclude the achievement card IDs when pausing the background music.
When viewing a bonus song, the background song would play over the top of the selected song. This change was similar to the previous fix, but excluding the bonus song IDs when opening a song card. The bonus song page wasn’t opened when swiping between songs in the collection, so I added an edge case in the swipe navigation when the card ID is above the bonus song threshold.
The popup for completing the midnights quest would repeatedly appear so I changed the variable tracking the stage of the quest as soon as it was completed instead of when the player levelled up.
In the achievement displays, the elevation and distance data are floats, but this means they can sometimes show values to several decimal places, making the value extend beyond the display background. I rounded the values to the nearest integer for displaying this data, but kept the actual values the same so that they were stored accurately.
I also noticed that the progress for the total distance achievement was not increasing after recording activities. I looked at the API request function and realised that the combined distance was calculated by adding the total running, walking and cycling distances, but those individual activity distances weren’t being saved. I changed the function to update the totals for the individual activities before calculating the combined total.
I changed the fonts used in the game as it had previously been using the default Unity font. I used one font for headers, such as the title screen, collection and achievement and quest tabs, and a second one for the buttons and body text. I used simple fonts so that they were easy to read. The font for the headers is a bit more stylised as it is easier to read than if I had used that font for the body text. The song cards used a different font which I tried using in the rest of the game, but it didn’t fit as it felt too intricate for the text in the rest of the game, so I limited it to only the song cards. Changing the font misaligned some of the texts in the wardrobe so I adjusted the width of them so they didn’t overlap.
The guest mode option to bypass the API worked, however on subsequent plays the user could select the opposite button. It was unclear what functions ran when this was selected but it would have likely caused issues if the API request ran when previously the game had been started in guest mode, as there would be no authenticated Strava account to pull the request from.
I changed this to display both buttons when the game is first opened, but on subsequent plays, it checks whether a Strava activity ID has been saved. If it has, the API has been used, so it doesn’t display the guest button, but if there is no saved activity ID, the guest mode has been used so it only displays the guest button.
I had been using a reset button in the settings to easily test parts of the game repeatedly. I moved this to the developer mode panel and added a confirmation so players wouldn’t accidentally activate it. When the player confirms they want to reset, the game is closed as keeping it open only resets some parts of the game.
After resetting the progress, the developer mode remained active, so I changed the reset function to deactivate it.
The shop seemed to be resetting before it was supposed to. After buying different combinations of items in the shop, I found that the issue occurred when the cards were loaded between play sessions. I noticed that the new songs displayed were the songs after what should have been shown, which made me realise the card index wasn’t working. I changed the load function from using the remaining cards list to the all cards list so that the index wasn’t shifted. This bug has also been occurring with the outfits in the shop. I previously thought it happened after buying a lot of outfits, but tested it and found it was the same issue as with the songs. I fixed this the same way, but also had to change the card images as they are set separately.
When the three song cards had been bought in the shop, there was an error when the game loaded as it couldn’t find the cards to load. I found this while in the process of implementing the previous fix and thought they might be related. This issue persisted afterwards, but I used the same method by changing where it found the cards from the remaining list to the all cards list.
After fixing this, I was able to test buying every song and outfit in the shop. When there are a few songs left, it shows duplicates in the shop and greys out all the song cards when there are none left. However, when trying this with the outfits, the items bought were correct but the outfit cards shown in the shop were ones I had already unlocked. I realised that the outfit cards list was only being updated when buying a set outfit and not a random outfit.
To do this I created a copy of the outfit cards list in the outfit manager script. When an outfit is bought, the outfit is removed from the list using the same index used to give the outfit. A new function is then run to compare the shop object lists with this new list and remove the object that has a different name, which stops them becoming offset.
This worked in a single play session, but reopening the game created another mismatch as the list in the outfit manager wasn’t saved. I added a function to copy the updated list to the outfit manager when the shop is opened, so that I didn’t have to save or load this separately, which resulted in the outfits behaving the same as the songs when there are little or no songs left.