question

Robert avatar image
Robert asked

Working around response times.

During development I'm noticing that I need to make a lot of co-routines with pauses in them, just to account for the time it takes to get responses (i.e. I had to add a .3 to check the inventory and another .5 to get the account characters etc.) and I intend on using other systems that require data returned to the client. Is this the way I'm expected to do this, or is there a more efficient way?

apis
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

·
brendan avatar image
brendan answered

Adding a specific delay isn't a good idea, as the latency time for the player to get a packet to the region where the core services reside and then get a response is going to be based upon their distance to that endpoint and the quality of their internet connection (side note - you can see the average time the call actually took on the backend in the API Usage Details report in the Analytics section of the Game Manager). In some areas, that "last mile" is actually the largest part of the latency.

In general, our advice would be to use async tasks to query for the data, either aiming for ahead of when it's needed or populating the data in as it arrives, with some form of placeholder or previous data in the meantime. For example, many games use a "loading" animation of some kind, either for whole pages or just for individual sub-elements within the page. It's good to have a timeout for retry logic, but that should be on an exponential backoff - re-query after a couple of seconds, then after something like 8, then 30, etc. And don't block on this - wherever possible, allow the player to leave the screen in question and proceed to the main menu, at least.

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.

Robert avatar image Robert commented ·

I expected such an answer, but the problem lies when an inventory object needs to be interacted with, ie during a transaction or use, and I need to verify the inventory at that exact moment to be sure someone isn't cheating. As a precaution I had, before sending out the question, populated the account characters at a portion much earlier than needed as suggested. Just making sure I'm going about it the right way.

I'll have to simply find better timings for all the moments when this is needed.

0 Likes 0 ·
brendan avatar image brendan Robert commented ·

To handle something like that (checking inventory), you've basically got a sliding scale of complexity/cost.

If you get the inventory at the start of the game session and use it as the local authority, re-checking it against the service periodically, that's usually good enough for most casual games. It makes it easy for a hacker to cheat the data on the local client, but if your game doesn't have competitive elements, that may not concern you.

A better solution from a security standpoint is to have a Cloud Script handler that you call which performs any checks you need. That way, you're only waiting on one API call to the service, minimizing the delay due to the Web API call (potentially to another region).

The best solution in terms of both security and turnaround time is to use dedicated servers, running in each region where you have players. That way, players can connect to a server which is close to them, the server gets the players state info from the service once, and then the client is only talking to the server about updates (with that server periodically checking in with the core service).

1 Like 1 ·
Robert avatar image Robert brendan commented ·

Hopefully you don't mind me revisiting this; is there an event I can register a listen for, so that I can perhaps throw up a loading screen, my current issue is after login I'm gathering the player's character data and sometimes it's taking longer than expected. Is there and event fire I can register so after a request is made I can essentially wait for a response, or will a do()while() response == null work for this?

0 Likes 0 ·
Show more comments
Robert avatar image Robert commented ·

That is exactly what I'm looking for, but I'm using the Unity SDK and I don't see any Async methods in the client api nor is it showing up in intellisense.

0 Likes 0 ·
brendan avatar image brendan Robert commented ·

I'd recommend using lambda operators. Have a look at our samples - they show how to effectively use those to process the results when you receive them. For example: https://github.com/PlayFab/PlayFab-Samples/tree/master/Recipes/GoogleSignInSample.

1 Like 1 ·
Robert avatar image Robert brendan commented ·

Ahh, I see now, that's actually what I've been doing, but sometimes the results weren't fast enough and the game would hang for a second; but since it's marked as a system action I can then assign a custom method to it such as starting a login/loading screen before the request and having a custom method run the data as it comes in; rather than just the lambda for both result and error. Thank you very much!

1 Like 1 ·

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.