0
\$\begingroup\$

I'm making an idle game with semi-multiplayer. My game uses Unity as a client and as a server Unity Gaming Services (UGS) C# Cloud Code Modules with UGS Cloud Save, this server is non-persistent, basically a REST API, which also means that as soon as the server returns a reply, the instance dies and all information is lost.

Players click "start" which then starts idle/automated combat on the client. Players get experience and items from combat. I want this to happen real-time on the client, it takes too long to pre-generate all the combat and loot on the server. But I want my server to check everything so there's no cheating.

The reason pre-calculating everything on the server is too slow is because there's a lot of random number calculations. Damage is random between the players min and max damage, item drops are random, item stats are randomized. The server, being non-persistent, would have to calculate all of this, save it to Cloud Save and only then it's able to return the values to the player, which causes a delay of a few seconds, maybe just 0.5 or 1-3 seconds, but that's too much.

I want to prevent cheating because trading items between players will be a big part of the game.

My plan at the moment is the following:

  1. player starts the game and sends a request to the server for a Random Number Seed (RNS)
  2. server generates the RNS and stores it in Cloud Save then sends it back to the player
  3. player clicks "start" and combat is processed real-time using the RNS, items are also generated using this
  4. on significant events, for example level up, every 10 seconds or on an item drop, the client pings the server to let it know something important happened
  5. the server then re-calculates all the combat up to that point and if everything checks out it saves all the rewards to Cloud Save
  6. the server then generates a new RNS that will be used after the next event (to prevent players calculating rewards a long time up front)
  7. on the next event the client pings the server again and then starts using the new RNS
  8. repeat from 5

My main concern with this is that I have duplicate combat code, not exactly, but I need to ensure the combat logic is exactly the same on client & server. Is there any way to manage this sort of thing? I have no clue. The code won't be identical either, because the client is showing lots of visuals that the server won't have to for example.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Visuals and combat logic are not the same. You can have the same underneath combat logic on the client / server with no visuals on the server. And idle games usually have fixed progress, in one minute the character can deal 500 dmg, which is enough to kill 10 enemies. You can fast forward combat on the server too when it is done by fixed rules (as idle games usually are) if your game is significant different, you should discribe more about how you imagine the combat \$\endgroup\$
    – Zibelas
    Commented May 4 at 15:16
  • \$\begingroup\$ If it's too slow to use server side only calculations in general, how do you imagine step 5 operating in practice? You're still doing the same amount of server side calculations, but now instead of spreading them out over gameplay, you're bunching them up. \$\endgroup\$
    – Pikalek
    Commented May 4 at 15:52
  • \$\begingroup\$ Updated the post, the main reason pre-calculating things on the server is too slow is because it's non-persistent, so as soon as it returns a value to the client the instance dies, meaning it would have to first save all the data somewhere, which takes too long. \$\endgroup\$ Commented May 5 at 5:42
  • \$\begingroup\$ The server, being non-persistent, would have to calculate all of this, save it to Cloud Save and only then it's able to return the values to the player, which causes a delay of a few seconds, maybe just 0.5 or 1-3 seconds, but that's too much. I doubt that a waiting time of 0.5s is perceived as too long for a player. A loading screen usually is several seconds and you can periodically check with the server to make sure everything is in sync. (This won't be noticed by the player during the play). And if the player wants to validate a weeks worth of offline progress, they will wait. \$\endgroup\$
    – Zibelas
    Commented May 5 at 10:35

1 Answer 1

1
\$\begingroup\$

In highly multiplayer contexts (such as this), it's best to keep as much logic on the server as possible. If I understand your explanation correctly, the important logic happens on the client with regular validation by the server. That is, the architecture looks like this.

 ┌─────────────────────┐ 
 │                     │ 
 │ ┌──────────┐        │ 
 │ │Game Logic│        │ 
 │ ├──────────┤ Client │ 
 │ │ Graphics │        │ 
 │ └──────────┘ ┌──────┤ 
 │              │ ping │ 
 └──────────────┴─▲──┬─┘ 
                  │  │   
 ┌──────────────┬─┴──┴─┐ 
 │              │ ping │ 
 │ ┌─────────┐  └──────┤ 
 │ │Validator│         │ 
 │ │& Logic  │ Server  │ 
 │ └─────────┘         │ 
 │                     │ 
 └─────────────────────┘ 

The issue with this architecture is that it requires a lot of communication between the client and the server, and logic has to happen both on the client and in the server. It also provides a vulnerability where, if the validator has bugs/issues, the player could cheat. Instead, using a system like this could be better.

 ┌───────────────────┐ 
 │                   │ 
 │ ┌────────┐        │ 
 │ │ Inputs │        │ 
 │ ├────────┤ Client │ 
 │ │Graphics│        │ 
 │ └────────┘ ┌──────┤ 
 │            │ ping │ 
 └────────────┴─▲──┬─┘ 
                │  │   
 ┌────────────┬─┴──▼─┐ 
 │            │ ping │ 
 ├──────────┐ └──────┤ 
 │  Game's  │        │ 
 │  Logic   │ Server │ 
 ├──────────┘        │ 
 │                   │ 
 └───────────────────┘ 

The benefit to this architecture is that the logic all happens on the server, and the graphics all happens on the lcient. Therefore, the user only has to send their inputs (not neccessarily keystrokes and mouse clicks--they can be processed more than that) to the server, and the server only has to send the client minimal relevant information pertaining to graphics so that the graphics logic can all happen server-side.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .