Search Unity

Feature Request My thoughts on the Unity Game Services suite

Discussion in 'Unity Gaming Services General Discussion' started by CameronDWills, Jul 16, 2022.

  1. CameronDWills

    CameronDWills

    Joined:
    Feb 26, 2021
    Posts:
    91
    I've spent the last month or so diving into the Unity Game Services suite and have spent an extensive amount of time in the dashboard and learning the API's. Previously I was using Playfab and Photon for my networking/backend components so that's what I have to compare to. Here are some thoughts on what I think could make this platform even better!

    UGS Dashboard
    • Cloud Save
      • Navigating through player data is clunky and it's really inconvinient that the only way to see player data is by searching the exact playerID. If I have testers for example, I'd have to build something into the game and rely on them to log it and send it to me. It'd be much better if there was a way to browse through exisiting data without any searching required (playfab does this
        • There should be a way to filter/search for users by saved variables. This way we could implement our own username system and find players by specific variables without having to do an Analytics implementation as well
    • Cloud Code
    • Economy
      • Please add a way to import items with a spreadsheet! Or at least a way in the dashboard to bulk-add without having to add each item one by one.

      • Economy should be better linked with Remote Config and/or Cloud Save, because right now there's no way to avoid having multiple copies of the same data in different places (at least for my use case). For example, if I have an in-game shop and I want to generate a list of items for sale, the best way seems to be to store the values in a Remote Config key which stores the items values like name, image, description, price etc as custom data.
        But during gamplay when the player is actually going to use those items, I have to load them from Economy but I still need many of those same values. So data that already exists in my Remote Config key has to be duplicated to exist in my Economy items.
        • Maybe there should be a way to return the database of Economy items, then I could just leave the data on the items themselves and not in Remote Config.
      • Say you have 50 items to add to your game, all of which are also for sale in a virutal shop. Now you also have to make 50 virtual purchase entries in Economy. The time it takes could easily be cut in half here by having some sort of toggle or option to make an item available for sale all in the same form. This + bulk adding via spreadsheet or UI would be huge time savers.

      • Running off of the example from the last point, now you have 100 item entries in your Economy dashboard, with no way to filter or even search to find what you're looking for. You have to just keep paging through everything until you get what you need. Even worse if any of these items also happen to be available for sale as a real money purchase, because you'll have to make yet another 50 entries into the dashboard.
    UGS API's
    • Netcode for Gameobjects
      • Having two seperate API calls for client/server/host was pretty confusing to get at first. Having to make conditional statements to determine who the player is, and then triggering the right RPC call with the right options seems clunky. Photons RPC's were a lot simpler, it was just one RPC type to rule them all that had a toggle (send to: All, Client, Host, Server, Buffered/NonBuffered) etc.

      • There's some basic functionality that seems really hard to do, unless I just don't understand the API yet. For example, if I want to get a specific GameObject by a playerID, it seems like I have to have the spawn manager return me a list of all of the spawned network objects and then search through that list and check if theres an ID match. Seems like this should be a built in function as I find myself needing it a lot.
    • Relay + Lobbies
      • I ran into a bit of trouble when testing what happens when players win/lose, disconnect, and the game ends. There should be some function that terminates everything when the game is over... closes down the lobby, ends the relay, clears the requests etc. I was getting an error when trying to create a new lobby/game after the first had ended, where it was saying there could only be one request at a time (the old request was never cleared).
    • Economy
      • There needs to be a way to return the database of game items (for example when you need to generate a list of items to display in a shop) instead of having to duplicate data into Remote Config
    • Authentication
      • Documentation for implementing logging in with 3rd party platforms is basically nonexistant or wrong.

      • Please add a way to have our own username/password system. Right now you either have to use a 3rd party platform to sign in, or you have to make users sign in anonymously. Some people don't want to connect thier 3rd party accounts and it makes the experience overall less immersive. There's no good way to setup account recovery becuse of this. Which segways into my last and most important point...
    • Cloud Save
    Overall, I like the platform and I'll probably stick with it and find quirky ways to work around the things it's lacking. It still feels like everything is in beta though, and doesn't feel like a solid product offering yet especially in comparison with competitor platforms. Many of the documentation links are either incomplete or link to pages that don't exist.
    The convinience of integrating with everything Unity is great, so I hope the platform continues to get regular support and updates!

    P.S.
    Please let me in to the push notification beta :)
     
    Last edited: Jul 16, 2022
  2. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    Hi @cameron_unity37,

    Thanks for sharing your extensive and detailed feedback.

    We really appreciate you taking the time to do this, your input is really valued. I'm pleased to hear that you like the new gaming services.

    The team are working really hard on lots of exciting new features and improvements to some of the existing ones. Several of the points that you mention are things that we are already working on but we will review each in detail and may reach out to you for clarification if any aren't clear.

    We'll post further information on some of the specific points in this thread over the coming days.

    Thanks,
    Laurie
     
    erika_d and CameronDWills like this.
  3. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    This is something that we are aware of and the product team have been considering. The ability to search for players based on values in their data would improve the 'Find A Player' workflow and reduce the need to seperately capture the playerID.

    There are a couple of workarounds that might be worth considering in the meantime.

    1) You can use the Analytics - SQL Data Explorer to search for a playerID based on the player's data.
    e.g. If I had a custom event called myCustomEvent recording the player's nickname

    Code (CSharp):
    1. select EVENT_JSON:unityPlayerID::STRING
    2. from events
    3.   where event_name = 'myCustomEvent'
    4.     and EVENT_JSON:nickName::STRING = 'Laurie'
    5.     and event_date = CURRENT_DATE
    6. group by 1
    Top Tip! Use the where clause in your query to narrow down the dataset and improve query performance, search for specific events and parameters within a restricted time period, rather than searching over all events.

    2) Some games use a 'Contact Us' button to send an email revealing playerID and other useful information for debugging. You could use this sort of mechanism to inform you what playerID testers are using.

    Code (CSharp):
    1.     // Send Contact Us Email
    2.     private void SendContactEmail()
    3.     {
    4.         string email = "somebody@email.com";
    5.         string subject = EscapeURL("Contact Us request from my App ");
    6.         string body = EscapeURL(string.Format("Player Nickname : {0} \r\nPlayer ID : {1} \r\n Platform {2}"
    7.                 , player.nickname
    8.                 , player.playerId
    9.                 , Application.platform)
    10.             );
    11.  
    12.         Application.OpenURL("mailto:" + email + "?subject=" + subject + "&body=" + body);
    13.     }
    Hopefully those workarounds will keep you going for now.
     
    erika_d likes this.
  4. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    Cloud Code

    Yes, this is also a feature request that we are aware of and have been investigating, I have added your voice to the feature request list. At the moment it is only possible to call other functions within the same script file. But opening that up to allow you to include functions from other modules would be a valuable addition.

    I've added a feature request for this. You may also want to take a look at the new Experimental Cloud Code JS Authoring package, it lets you author you Cloud Code Scripts in your favourite IDE and deploy them to the Cloud Code dashboard through Editor.
     
  5. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    You won't be surprised to hear that you're not the first to ask about Leaderboards, we totally recognise the importance of them and should be able to share more information before too long. We would definitely be interested in undertsanding which specific Leaderboard use cases and features you are looking for.

    On the more general point of 'Accessing Other Player's Data', there is something you can do already :D.

    It's not well documented yet, but it is possible to access other player's data from Cloud Code.

    The
    context
    object contains an
    accessToken
    that can be used to call other Unity Game Services SDKs as the authenticated player.

    The Context object documentation needs to be updated to show that there is also a
    serviceToken
    that can be used to call other Unity game services SDKs as a different player, by their playerID.

    So, if you were to setup a Cloud Code script code with a required input parameter of
    otherPlayerId
    you could allow the authenticated player to run the script and have it access the Cloud Save data of the other player.

    e.g.

    Code (JavaScript):
    1. module.exports = async ({ params, context, logger }) => {
    2.  
    3.   const {
    4.     projectId,
    5.     playerId,
    6.     serviceToken
    7.   } = context;
    8.  
    9.   // otherPlayerId should be present as input parmameter
    10.   logger.info("Script parameters: " + JSON.stringify(params));
    11.  
    12.   // Service Token used to Authenticate as another player
    13.   const api = new DataApi({ accessToken: serviceToken});
    14.  
    15.   // Attempt to get other player's data from Cloud Save
    16.   const otherPlayerLoad = await api.getItems(projectId, params.otherPlayerId, ["<Cloud Save Key>", "<Another Cloud Save Key>" , ...]);
    17.   const otherPlayerLoadResponse = JSON.stringify(otherPlayerLoad.data)
    18.   logger.info('Other PlayerData Load result ' + otherPlayerLoadResponse);
    19.  
    20.   // Use the other player's data in Cloud Code, or return it to the client  
    21.  
    22.   // Return the JSON result to the client
    23.   return {
    24.     OtherPlayerId: params.otherPlayerId,
    25.     OtherPlayerData: otherPlayerLoadResponse
    26.   };
    27. };

    Look out for documentation and examples of some of game mechanics that this unlocks and please let us know if there are particular use case you would like to see covered.
     
    erika_d likes this.
  6. joonarahko

    joonarahko

    Unity Technologies

    Joined:
    Jul 9, 2018
    Posts:
    71
    Thanks so much @cameron_unity37 for your feedback. It is super valued. I incorporated your feedback on the focus mode yesterday so you should have a little better experience now :)
     
    CameronDWills likes this.
  7. CameronDWills

    CameronDWills

    Joined:
    Feb 26, 2021
    Posts:
    91
    Friends list would be the first thing that comes to mind! That way players could send and receive friendrequests, and then using the relay/lobby services easily send invites to private games
     
    erika_d and calebatwd like this.
  8. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    Thanks for sharing, I'll add your comments on 'Friends' functionality to our feature request list.

    There are some apsects of Friends functionality that you could implement with the current UGS feature set

    Some pointers on using the existing functionality.
    • Cloud Save could be used for storing individual player's Friend List. You could store up to 16KB of friends as an array of
      playerId
      in a slot named
      Friends
    • The Lobby API contains a Player object with
      id
      and
      data
      parameters that could be used to communicate playerId and Nickname for adding a player to your Friend List whilst in the Lobby
    • In-Game, you could implement messagging and social features directly with the players in the same multiplayer session.
    • For offline friends functionality, the Cloud Code
      serviceToken
      method described in the previous post could be used for storing friend requests against other player's Cloud Save state.
    Hopefully this will provide a few useful pointers. A more complete set of Friends and other Social features, all wrapped up in a neat easy to use package, would definitely be something we would be interested in gathering more community feedback on. Please feel free to share any further suggestions here or in the Unity Gaming Services Roadmap
     
    CameronDWills likes this.
  9. CameronDWills

    CameronDWills

    Joined:
    Feb 26, 2021
    Posts:
    91
    Thank you for all of the responses, good to see the platform is supported and actively being improved. I noticed a few changes on the dashboard, most notibly being able to see player data without having to search by their ID; thank you!

    I have some more comments regarding Economy that seems to be a little frustrating, but maybe I'm doing something wrong you tell me.

    Here's my use case:
    The items in my game are all consumable (think potions, bombs, etc) and players can purchase these items with currency in-game, they can also be obtained through gameplay and loot boxes. The items should be stackable in a players inventory, showing a "quantity" of how many they have of each.

    • My Economy items 'CustomData' stores nothing (anymore)
    • My Economy purchase items store 'itemID' and 'Quantity' in the 'CustomData'. I use itemID to cross reference my RemoteConfig entry to pull titles, descriptions, sprite paths etc, and 'Quantity' to store how many of this item the itemshop can sell at maximum (I use logic to generate a random number between 1 and 'Quantity'
    • My PlayerInventoryItem 'InstanceData' stores 'Quantity' which tells the player how many of that item they currently own.
    • My RemoteConfig entry stores the other item data for all of my items as JSON

    Originally I thought I would store the item data on the Economy item itself in the form of CustomData (this would be things like item title, description, sprite path, item stats). But then I ran into a problem when I went to implement the item shop, because when you make a call for a purchase it only returns the purchased items ID, but doesn't give me access to the CustomData. I thought maybe I should store the item data I need on the Economy purchase item, but the CustomData you can store on those is limited and I'd only be able to access it during purchase and I'd have duplicate data (the same data living on both the item, and the purchase item).

    Eventually I just figured the best place to store item data was in a Remote Config entry. This just seems inefficent because I have to make a call to Economy, and then another called to Remote Config to cross reference the item ID with the Remote Config entry. Is there a more efficient way to do this?

    And then for my second hurdle, I needed a way to keep track of the quantity of an item a player has. Originally I was just having them get the item through either a purchase call, or an add inventory item. I thought maybe I should just count how many duplicates of an item exist and then update the game UI to display the count as the quantity. This seems inefficient though, and the getInventory call is limited on how many items it can return at a time (default 20, up to 100). This also makes looking at players inventories a headache in the dashboard because there's so many duplicates, and seems like a waste of resources.

    So instead, I decided to use the InstanceData of a players item to store a 'quantity' count. How I have this working is a cloud code script for a loot box that checks the players inventory first, and if the item ID already exists, it updates the instance data, otherwise it adds that item to the players inventory. The problem with this, is now my item shop implementation won't work, because I'm using the purchase helper to make an item purchase which adds the item to the players inventory. So now I'll have to first start by pulling the players inventory items, then running a check to see if they already have the item, and if they do then decide to either run the purchase call or update existing instance data... which defeats the purpose of having an Economy purchase functionality and purchase items, doesn't it? And then once the player has the item in their inventory... should I still be cross referencing the item data with Remote Config since I had to place the data there for my purchase use case? But it seems it would be more efficient to be able to access the CustomData of the item itself instead of making an extra call to Remote Config.

    I hope that makes sense... it just seems like I have to do a lot of cross referencing and make a unneccesary calls that should be able to be eliminated since the data all exists on the same platform. What's the most efficient workflow here? How should I manage players inventory and purchases, and access the data associated with those items and their quantity, in the most efficient way?

    If you needed a way to manage item titles, descriptions, sprite paths, stats, shop price, and quantity to have access to them with in-game UI and gameplay... where would you store those?
    • What data should be stored on an Economy items 'CustomData'?
    • What data should be stored on an Economy purchase items 'CustomData'?
    • What should be stored on a players inventory item 'InstanceData'?
    • Is there any combination of these that could be used to avoid calls to Remote Config?
    To me, it would make the most sense to store ALL of the data related to a particular item on the Economy items 'CustomData" because that's the common denominator being accessed in each scenario. And then when making a purchase call, or an inventory call, I can just reference that item and its associated CustomData, with InstanceData also being able to be accessed for the player-specific data like quantity. It doesn't seem like this is possible currently.
     
    Last edited: Jul 21, 2022
  10. Recon03

    Recon03

    Joined:
    Aug 5, 2013
    Posts:
    845


    Well thought out, I been using it myself as well , I have used Photon Bolt, Pun, and many others.... Now I have no plans to switch, as far as networking library I really like TNET.

    Great write up. I think its spot on, and I bet others would agree with alot of what you said. Nicely done.
     
    CameronDWills likes this.
  11. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    One note, Remote Config would not allow you to store information per user. It's basically only for settings that are system-wide, or per audience type (Android, iOS, country, etc)
     
  12. FabriR

    FabriR

    Unity Technologies

    Joined:
    Mar 9, 2021
    Posts:
    16
    Hi @cameron_unity37 thanks for the feedback on Economy. A couple of notes on future plans

    This is in the plans for the service. We have two items in our public roadmap. One is in the works, and it's Public Admin APIs, and the second one is an import functionality from the dashboard.

    I also see your further clarification and I see your problem. We are looking at a functionality to automatically add the custom data in the configuration to the purchased item as Instance Data, while still giving you the ability to add other Instance data when you need to. This item is in our public roadmap too. Would that solve your problem?
    Stackable items are a good suggestions, I'll add it to the feedback we collect.

    Usually we suggest to use custom data in the configured item to store "immutable" item properties (like the asset they are linked to, attributes, etc) that are not specific to the player instance. For player specific property of the item, we suggest to use InstanceData.
     
  13. CameronDWills

    CameronDWills

    Joined:
    Feb 26, 2021
    Posts:
    91
    Is it possible to use the service token to update another players item data? I've been trying but with no luck. During a 1 vs 1 match, instead of making a cloudcode call everytime an item is used to update each players remaining item quantity, I was trying to batch it all up into a list and then pass both players used items into the winners cloudcode call. This code would then update both players item data.
    I wanted to do it this way incase the losing player disconnected or quit, they wouldn't be able to log back in later and still have all of the items they used (and the winning player will still be around to make the item changes)
     
  14. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    Hi Cameron,

    Yes, you should be able to achieve that use case from Cloud Code with a service token. It would look something like
    • Client makes cloud code script call with parameters that contain otherPlayerID and playersInventoryItemId to transfer
    • Cloud code script checks that the source player own playersInventoryItemId and retrieves the instance data for it
    • Cloud code script uses service token to make a call to the Economy API to update the other player's inventory by addingt a new item and setting any instance data

      EDIT
      - I spoke a bit prematurely on that point! Economy doesn't support service tokens yet, but ultimately it will. But Cloud Save does. So, the workaround would be to drop the item details into to the other player's Cloud Save for them to retrieve themselves.

      e.g. think about putting the item into a safe and handing the other player the access code as opposed to handing them the actual item.
    • Cloud code script removes the item playersInventoryItemId from the player's inventory
    This is a great use case, I'll update this post with an example in the coming days, using the Intermediate Cloud Save method and will update with a 100% Economy version when it has service tokens too.
     
    Last edited: Sep 22, 2022
  15. CameronDWills

    CameronDWills

    Joined:
    Feb 26, 2021
    Posts:
    91
    Ah, makes sense then why I couldn't get my cloud code script to work. I kept getting an error that didn't really provide much insight into why it wasn't working, and using service tokens doesn't seem to be something you can do from the cloudcode dashboard. Looking forward to seeing your implementation
     
  16. Eloren

    Eloren

    Joined:
    Jul 17, 2019
    Posts:
    24
    Wow, it turns out that people like this service, and the devs are working on improving it. I'm surprised. Because I hate how Unity advertises Gaming Services. Their marketing campaign is just terrible. I thought it was some kind of another crap for investors.
     
  17. joonarahko

    joonarahko

    Unity Technologies

    Joined:
    Jul 9, 2018
    Posts:
    71
    There definitely is a passionate team doing their best to build services to empower creators to build amazing games. Please let us know how you find the offering so we can continue to make it better.