Hi!
I am trying to implement a feature to show a user what missions their friends have been playing in the last week.
That is, suppose Bob plays Area 51 twice, and Liberty Island once; and Alice plays Area 51 once and Hong Kong twice.
I would like to show the user:
Area 51: 3
Hong Kong: 2
Liberty Island: 1
I have considered two approaches and would appreciate feedback on which is better, or if there is another option I have not considered.
Option 1
Use a leaderboard where the owner ID is a concatenation of the player id and mission:
Bob_A51: 2
Bob_LI: 1
Alice_A51: 1
Alice_HK: 2
And then I could use a custom SQL query to query the username instead of the owner_id.
ie)
FROM leaderboard_record
WHERE leaderboard_id = $1 AND expiry_time = $2 AND username = ANY($3)
The owner ID is still unique but this allows each user to have a separate leaderboard entry for each mission. This is a nice and flexible data layout, but I would prefer to avoid custom SQL if possible.
Option 2
I would use a standard leaderboard, and pack the per-mission data into Bob and Alice’s metadata.
Bob: 3 metadata={"Missions": {"A51": 2, "LI":1}}
Alice: 3 metadata={"Missions": {"A51": 1, "HK":2}}
This seems like a hackier approach to me and less re-usable for future features. However, it doesn’t require any custom SQL.
Thank you!
Hello @dludoff,
I’m not sure leaderboards are the best option, for Option 1, records aren’t indexed by username, so it may quickly become an issue. And for Option 2, the metadata would have to be updated with some custom SQL too, because the leaderboardRecordWrite API won’t overwrite the metadata on subsequent submissions.
Instead, you could have each user keep a Storage Object which keeps track of his own played missions throughout the week (e.g. {“map_id”: 1, “expiry_time”: “unix_timestamp”}) by setting an expiry_time as part of the object value too, which you set to some time in the future (when the current week ends) when you first create the object. Every time you update its existing or new counters, you’d check the expiry time, and if it’s due, you reset the values and recalculate the expiry.
You could then use the StorageRead API to fetch all the entries for your friends, skip any that have expired and programmatically build the ranked list to present to the user.
Hope this helps.
@sesposito,
Thanks for the response.
Fetching the storage docs for every friend sounds expensive to me - is it not?
Not really meaningfully more expensive than leaderboard records lookup, unless the stored json value is big, which incurs in some extra CPU time spent decoding the value.
Just be sure to fetch all records within the same StorageRead call.
1 Like