question

laurentiumarianivan avatar image
laurentiumarianivan asked

Spawn random items in the shop every 24 hours

Hello everyone!

You've always been helpful in the past, so I've come again, needing some help. I have a shop in which I want every 24 hours (for testing purposes this will be set to 5-10 minutes) to spawn 3 different items in the shop for each player to buy. Players shouldn't all get the exact same items spawned in the shop (if possible).
The players know what those 3 items are, and they have the option to buy any of them, if they want to.
(BrawlStars is a perfect reference, as that is exactly what I am trying to do. I don't want a loot crate system, I just want to offer them every day 3 random items in the shop which they can buy if they want to).

There are generation rules for each item spawned (items have rarities). I've set up 4 helper drop tables containing all my items for each rarity (common, rare, epic legendary). Then I've set up 3 drop tables, which will be used to get the items every day.
The questions are:
1. How do I implement the timer? I guess that by using Scheduled Tasks, but just wanting to be sure.
2. What cloudscript function do I call every 24 hours?
3. How do I display the item in the Unity game? I mean, I probably have to get the dropped items from the table, and then display the correct item based on the returned item ID.
4. How do I check, in Unity client, if the user already has that item (so that I disable the buy functionality on that item and display an "OWNED" label over it)?

Sorry if there are too many questions, but any help is greatly appreciated

CloudScriptIn-Game Economygame managerscheduled tasks
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Seth Du avatar image
Seth Du answered

Surely Scheduled Task is able to handle this job, however sometimes it is not cost-efficient. For now, I have 2 workaround solutions you may refer to, but the main idea is very similar.

  • Each player will have different generated items, and it means it is player-specific data, which shouldn’t be store in a public resource. The best place is Player Read-Only data, with a permission of Private, or Entity Objects with specific policy (if you don’t want players to see others’ store items).
  • Create a Cloud Script/Azure Function, where EvaluateRandomResultTable API will be called for 3times (for 3 items). The result will be stored in Player Read-Only Data. I will also suggest you to store a timestamp, along with discount price.
  • That Player Read-Only Data will be used for daily store items. You may need to create another Cloud Script/Azure Function for purchase, where verification can be done before the purchase.
  • If using Scheduled Task. Basically, every day will run the function in step 2. However, it is not recommended running this function for All Players (will have more cost). You may define a segment for active players.
  • My preferred suggestion will be defining a task on the client side. Every day, the first-time login will do this “refresh” job with the function in step 2. This is an event-triggered system, which should be a preferred design in the usage-based pricing model. Of course, one time refresh shouldn’t be enough, you may add multiple event-triggered refresh on the client side and also combine with time-triggered refresh. As long as there is a timestamp in the value, there won’t be multiple regenerations for items.

>> How do I check, in Unity client, if the user already has that item (so that I disable the buy functionality on that item and display an "OWNED" label over it)?

Simply add a flag in Player Read-Only Data I have mentioned above.

7 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

laurentiumarianivan avatar image laurentiumarianivan commented ·

Thanks a lot for the fast and detailed answer!

What I am building is an MVP, so I am not necessarily looking for the most cost-efficient solution, as I won't have many users. I have a few more questions regarding the first approach:
1. Why do I need a timestamp on the stored items, if I am running the Scheduled Task 3 times every 24 hours? Also, I won't have any discounts (and I don't know if it matters, but these items are bought with in-game currency, not with real money. With real money you can buy only the in-game currency).
2. If each players has the items stored in its read-onlly data, why do I need a new Cloud Script function for purchasing? Can I not use just PurchaseItem on the client, with the item id stored in the Player-Data?

1 Like 1 ·
Seth Du avatar image Seth Du ♦ laurentiumarianivan commented ·
  1. Timestamp won't be necessary if it is a scheduled task. Specified price will simply provide more flexible usage.
  2. You will need a verification step. PurchaseItem API will only require item ID, VC and price. If a player keeps that information, they can directly purchase them via API call, which means your daily random items will not work. Cloud Script function for purchasing doesn't mean calling PurchaseItem API, and what the function does is to subtract the VC for players and grant the items directly.

PS. I have noticed some developers in the community shares the idea that they won't define any Prices of items, if there is a "store" feature in their game. Instead, they will only define the price in "Stores" feature of Catalog, which can avoid the issue in my answer of the 2nd question.

0 Likes 0 ·
laurentiumarianivan avatar image laurentiumarianivan Seth Du ♦ commented ·

Thanks a lot! Another question, if you have time:
I am trying to do a test cloudscript method for setting into each player the generated items, but it doesn't seem to work, could you help me?

handlers.getRandomDropTableItems = function (args, context)
{
    var first_item = server.EvaluateRandomResultTable({"TableId" : "item_slot_one"});
    var second_item = server.EvaluateRandomResultTable({"TableId" : "item_slot_two"});
    
    var data = {};
    data["item_one"] = first_item;
    data["item_two"] = second_item;
    
    server.UpdateUserReadOnlyData({"PlayFabId" : currentPlayerId, "Data" : data});
    
    
    return { messageValue: first_item };
    
};

I tried using it by doing to things:
1. Called it from the client, and the return message is good (I can see that first_item is generated correctly). On the success callback of ExecuteCloudScript (so on ExecuteCloudScriptResult) I tried getting the read only user data, but it's always empty (I also checked it from the PlayFab game manager and it's still empty)
2. I set an hourly scheduled task for the same cloudscript function, it says that it successfully completed, but there is still no read only player data on my players.

1 Like 1 ·
Show more comments

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Error rendering WebPanel (widgets/consolidation-widget.ftl): org.hibernate.hql.internal.ast.QuerySyntaxException: AvailableConsolidation is not mapped [from AvailableConsolidation up where up.node = :node]