0
\$\begingroup\$

I'm working on the server/client design for a game similar to Clash of Clans. I've read through dozens of articles and have some general parameters of what I'd like to accomplish.

  • Scalable (Probably will use AWS for load balancing and multiple instances and what not)
  • Secure - Server is authoritative
  • Fast - Make as much code run on client as possible.

So on the note about Fast/Secure. My game will have a save file. For the sake of argument, let's assume that the save file contains an array of buildings MapBuildings and the player's current cash amount cash. From my reading, the server should manage the save file. For example, the server will update the cash quantity every few seconds be taking the time difference between the last update, multiply by the cash production rate, then set the cash value. If the player taps "upgrade" on a building, it will send a request to the server "hey, the player upgraded building at (x,y)", then, the server will verify the player has enough cash, subtract it, and return the new cash amount. I also read that using a save file ONLY on the server isn't the best, because then the client will experience more latency because it has to wait for a server response for everything. So the client should have a save file too that's instantly updated, but verified against the server's response. So this is where I'm stuck, verifying and rectifying differences between the server's save file and user's save file. Here's my currently proposed solution, it has some holes, which I'm hoping you can fill in.

  • Game is launched, the client's save file is used to initialize the game state. The save file's values are NEVER updated by the client.
  • User has $100, and taps "upgrade" on a building (upgrade costs $50). Client checks cash (in game state, not save file), subtracts $50, and upgrades building to the gamestate immediately.
  • Cash is now $50
  • Client performs tick method, let's say cash production is $1/second. Client will take the time since last tick, and calculate the cash to add. Let's say client does this and now says the player has $51 dollars.
  • Client adds "building upgraded" request to the network queue
  • The queue is sent to the server every x seconds (I'm thinking 5 or 10 seconds?)
  • Server checks if the user has at least $50, they do, so the server subtracts $50 off, adds the upgraded building to the save file, internally calculates how much gold the player should have ($51, based off time) and returns the changed values to the client
  • Client receives changed values, overwrites save file (keep in mind, save file wasn't updated by the client), and saves the file to the file system.
  • Client then verifies the save file's values according to the game state, if they don't match, they need to be resolved.

Here are the holes I'm struggling with:

  • How do I account for latency between the client's calculated cash value and the server's? For example, the client will have generated a small fraction more cash, and the server's value will be x seconds behind, where x is latency. I want this to be really stable, I'll elaborate on this more in the next items.
  • How should I compare the game state and the save file? This would require quite a bit of code to make sure they match, is this performance friendly?
  • If the game state and save file don't match, should I make the user relaunch the game (to load initial values from save file again), or should I try to over-write the values in the gamestate? This could be challenging, because overwritting the game state could make the game appear really messed up to the user (buildings rapidly changing position, values jumping to different values). I'd lean towards forcing the user to reload, but as state in hole #1, this needs to be rock-solid so that a normal, non-cheating user will rarely experience a force reload dialog.

So, is my analysis model correct? Should I use a different model? How can I change my current model to fix the holes and verify an insync and clean networking interface between server and client? Also, if you have some resources, it'd be great if you can post them.

\$\endgroup\$
  • \$\begingroup\$ Welcome to gamedev.SE. I'm afraid you will need to break down your questions into simpler individual questions with a narrower scope for us to answer. As per the help sections ( gamedev.stackexchange.com/help/on-topic and gamedev.stackexchange.com/help/dont-ask ) There are too many questions, each question is a little bit too broad and for the most part answers would be opinion-based ("what is best?") and/or there are too many possible equally valid answers to some of the questions. \$\endgroup\$ – Stephane Hockenhull May 9 '18 at 0:35
  • \$\begingroup\$ A lot of it is on-topic. It just needs to be split up and narrowed down. Also try to make it so the answers won't be purely opinion based. I also recommend you spread your questions over time: The few volunteers with networking experience may not be able to answer everything at once and your questions might fall through unanswered. \$\endgroup\$ – Stephane Hockenhull May 9 '18 at 0:50
  • \$\begingroup\$ And at 20 reputation you will be able to participate in the chat where opinion on best practices and advice can be exchanged. Note that some of your questions might get flagged as "duplicates". A lot of networking Qs have already been asked on this site (eg: gamedev.stackexchange.com/questions/117954/…, gamedev.stackexchange.com/questions/114721/… ) so better do a bit of searching first or might get closed as dup if they're only a slight variation of the same problem. \$\endgroup\$ – Stephane Hockenhull May 9 '18 at 0:58
  • \$\begingroup\$ Thanks! Again, I'm at the design stage and haven't been able to find much info online. I can provide more specific questions as I begin to code it, but I'm trying to get it right from the start. \$\endgroup\$ – wdavies973 May 9 '18 at 1:14
0
\$\begingroup\$

The server should maintain and store the game state. It's never going to be secure if the user has access to a save file, and as you noted, the whole business of figuring out whose game state to believe is trouble.

So the server verifies transactions and saves the state - when the client connects he gets a bulk download of everything he needs for the GUI. The real game state is always what the server says, but for the sake of convenience things the user tries to do (like spending money) can be reflected immediately in the GUI and then replaced when the server supplies a new authoritative value.

If there are many things that ought to change as a function of time, make the server broadcast a "game time" token, and let the client deduce and display all the changes independently of the server. Verify that they're still in sync by generating a hash of all the state variables and comparing the server and client values.

\$\endgroup\$
  • \$\begingroup\$ Good suggestions, thanks. Like I said, the local save file is only for fast initial loading and the game state will be immediately changed. I think the hashing solution will work well for the comparison. Thanks! \$\endgroup\$ – wdavies973 May 9 '18 at 1:15
  • \$\begingroup\$ the amount of state and attendant delay loading ought to be trivial compared to the lag getting the server's attention and a new client set up. \$\endgroup\$ – ddyer May 9 '18 at 3:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.