question

Nicolas C avatar image
Nicolas C asked

Dedicated server / Multiplayer server or Cloud Scripts?

Hi,

I'm building a game with an authoritative server structure that checks all client requests to prevent any kind of cheating. This includes:

- Setting player cards in their deck

- Changing from a character to another

- Asking to upgrade a card

- Changing from a tutorial step to another

- Granting items

And many more...

Basically, all changes made to the player save are verified by the server and sent back to the client.

Should I use Cloud Scripts or PlayFab multiplayer servers (dedicated servers) for this? There is no plan for matchmaking in my game so I would not use the PlayFab matchmaking feature.

It seems heavy for Cloud Scripts to handle the entire server logic.

Also when I upgrade the app version of the game, I want to upgrade progressively so for instance with PlayFab multiplayer servers I could upload a new build on one server and redirect the players who downloaded the new app version there while the others would remain on the servers still running the previous version.

Thanks

CloudScriptmultiplayer
10 |1200

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

Nicolas C avatar image
Nicolas C answered

Update: I found a solution.


I extracted the game server code from the project containing Main() to a new class library project.

By compiling this new project I get a .dll that I then add as a reference to the main project.

Main() is now able to call different game server builds by switching from one referenced .dll to another using external assembly aliases.

10 |1200

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

madmojoman avatar image
madmojoman answered

I would recommend going the server route. CloudScript has some restrictions on not only time allowed for methods to process, but the number of functions that may be called at once. You're right thinking it would be too heavy for CloudScript. It would work up to a point, but as you're checking more complex logic and wanting to run more processes at a time for complex functionality, it'll probably require a server of some kind. Best just to get into it now than have to convert things up and have some on CloudScript and some on servers.

10 |1200

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

Seth Du avatar image
Seth Du answered

It depends on the game design of your game. If the gameplay is near-time, Cloud Script/Azure function is preferred and if it is real-time, dedicated server will be required. In addition, since PlayFab doesn’t support single value being written by multiple players at the same time, when it comes to Multiplayer games with 3 or more players in a match, dedicated server will be preferred. However, please note that PlayFab Multiplayer Server is designed for session-based game, like MOBA, PUBG. Long time running Online games like MMORPG is not suitable in this scenario.

The Cloud Script/Azure function can handle 10s execution runtime, which is enough for most cases even though there are plenty of verifications. You can also separate features in distinct functions if you understand the pricing metering and frequency limits.

For the differentiating players by client versions, it is not natively supported by PlayFab but there can be simple workarounds.

11 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.

Nicolas C avatar image Nicolas C commented ·
@SethDu Most verifications include using both the current PlayerDataand many TitleData key/value pairs.Using Azure Functions:
  • I need to fetch the PlayerData each time an azure function is called to process the verifications using the current player save. Then update the PlayerData accordingly. This makes for 1 read and 1 write of PlayerData per call.
  • I can implement a static cache system for TitleData while keeping in mind that I have no guarantee the same server will be used from one Azure Function call to another.

Using a dedicated server I could open a session for the Player and keep their PlayerData in a cache during the entire session. That would make for 1 read of the PlayerData and the same number of writes as with Azure Functions.

However, our game is not a session-based game like PUBG. The player can keep playing the game for hours and remain in the menus, modifying their cards/decks/characters/inventories, etc. From what you describe the Azure Functions would still be better for that use case.

Could you elaborate on the simple workarounds for differentiating players by client versions?

Thanks

0 Likes 0 ·
Nicolas C avatar image Nicolas C commented ·

For differentiating players by client versions, with a dedicated server I would simply have to redirect the new client versions to servers that have the new server build related to the latest client version.

What I'd like to avoid is adding client version checks in the server codebase.

0 Likes 0 ·
Nicolas C avatar image Nicolas C commented ·

Also, could you provide more details on this? I'm not sure to understand in which situation this could happen.

> since PlayFab doesn’t support single value being written by multiple players at the same time

Again, thanks a lot

0 Likes 0 ·
Seth Du avatar image Seth Du ♦ Nicolas C commented ·
  • differentiating players by client versions

For different client versions, you may create several server builds. There should be a Title Data to maintain, where Build ID and client version match is stored. When the client or server call RequestMultiplayerServer API, there should be a table for reference. As the version upgrades, there are increased server builds defined in your title, it is also the reason I don't recommend this.

  • single value being written by multiple players at the same time

Consider a raid boss in MMORPG, the HP of the boss is decreasing via players' attack. This is something easy to implement if there is a dedicated server. However, if you use Cloud Script/Azure Function, it is barely possible because all the attacks will trigger a data update. Since PlayFab doesn't support queued or cached updates, there can be conflict errors by concurrent updates.

1 Like 1 ·
Nicolas C avatar image Nicolas C Seth Du ♦ commented ·

To clarify, the way it's implemented is that we only have one Azure Function called Main() that handles all the logic. We send messages with many different types to Main() and the function processes different logics depending on the message type, returning a server response associated with the sent message type.

If we change some logic on the client & server in a new app version, Main() would change and the previous client version would not work.

Several server builds would work for dedicated server but how would this work for Azure Functions ?

I'd need the new version of Main() to be accessed by the new client version and the previous version of Main() to be accessed by the previous client version. Both should be able to access the player data.

I'm not talking about matchmaking at all here.

0 Likes 0 ·
Show more comments
Seth Du avatar image Seth Du ♦ Nicolas C commented ·
  • The player can keep playing the game for hours and remain in the menus, modifying their cards/decks/characters/inventories.

Based on your current information, it seems CSAF will be enough to handle the game logic. Please note that when it comes to PVP, dedicated server sometimes is still required. (if the game logic is simple, you can implement without it -- Using Shared Group Data - PlayFab | Microsoft Docs) Considering Hearthstone, players idling on the menu doesn't require dedicated server, while when match found and game started, the hosted server is used to make sure the fairness of the game.

1 Like 1 ·
Nicolas C avatar image Nicolas C Seth Du ♦ commented ·

For PVP we will use dedicated servers indeed

0 Likes 0 ·

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.