Advertisement

Server+Client Physics VS Client Only Physics

Started by March 17, 2018 05:40 AM
9 comments, last by hplus0603 6 years, 8 months ago

I'm having a problem coming up with the best solution to whether the server or client, or both should handle physics in my procedural generated multiplayer game. I don't think I need to handle the player's x, and z position on the server besides passing it to other players untouched since players on remote machines just move from their last x/z position towards the latest x/z position received.

The main problem I'm having is with vertical positioning while supporting the ability to jump, while not having server side physics. I don't want to have server side physics since there would be a lot of map chunks I'd have to process physics for. Passing the jump command from one player to another shouldn't be a problem since the client has physics data and can tell if the other players on their machine are on the ground which is required for jumping. But, I still don't want players to be able to fly since the server is authoritative on combat and other actions between players/AI.

The other problem is AI positioning. The AI should pretty much always be pasted on the ground, but this becomes a problem with caves, and overhangs and the like. Not sure how I would accomplish this without server side physics.

Any solutions I could use without server side physics?

 

If you don't want to allow client cheating, then you need to have some kind of physical security against hacking on the client, which means using a console, or building PC games that go into specific locations (like game halls or whatnot.)

If this game is for users to play on their phones or home computers, then letting the client be authoritative will open you up to cheating, no matter what you do. All is not lost, though; if your game is not that big and important to people, there won't be very many people who want to cheat. (On the other hand, if the community is small, even a single cheater may ruin it and prevent growth.)

Also, I don't see how you think that x/y is not important from an anti-cheat point of view. If there's a door or other obstacle in the way, if I can set my entity to be on the other side, I have effectively teleported through the obstacle. All the other clients have no option but to show the player going through walls -- else, your game will de-sync. (And de-sync happens even to legitimate players if you let other clients reject data from the authority.)

The solution is to run the simulation on the server as well as the clients, or to accept that your game probably doesn't need strong anti-cheat design, and live with that decision.

enum Bool { True, False, FileNotFound };
Advertisement

I guess I'll have to have server side physics. Kinda sucks since it will limit the amount of map chunks I can have loaded, unless I have map chunks loaded in a cloud or something. Cloud hosting is not really something I think is feasible at the moment since prices can skyrocket if the server has a ton of map chunks it needs to launch in a cloud. Maybe an option for the future.

it will limit the amount of map chunks I can have loaded

How big is a map chunk, in megabytes?

How many players per map chunk?

How would you create enough map chunks to fill up the memory of a server?

enum Bool { True, False, FileNotFound };

Currently each map chunk is around 8MB with only terrain, trees, and rocks. That size is only going to grow when buildings, and other things are added. Players will be spread out through map chunks most of the time, so at worst, I'd have to have 9 map chunks loaded for each player, since chunks surrounding the player also need to be loaded for smooth transition between chunks. With 8MB chunks, and say 2GB available for map chunks, that would only be 256 chunks able to be loaded.

Players can move pretty fast so It's not unreasonable that I'd need 9 chunks loaded for each player. Each chunk is 800 meters in length and width, and I can't really make 'em bigger since it increases chunk load time by a significant amount.

 

You don't need to load textures or render geometry for terrain. Maybe that's already calculated in the 8 MB, though?

800 meters squared times 256 chunks is 12.8 * 12.8 kilometers. This is larger than any current FPS or similar game. It is also large enough that simple float-32 based physics simulation will be unstable and jittery towards the edges.

And how will you build all this terrain? That is a truly huge amount of data to create, especially if you want the data to be rich enough to require 8 MB per chunk.

How fast do players travel, and how fast are chunks to load? With flash drives, I'd expect you to be able to load at least 100 chunks per second, and if a player travels 400 meters in a second, that's ... very fast! You'll probably do enough with 4 chunks loaded (the closest neighbors to the chunk quadrant each player is in.)

And what do you do for remote players on the local player's machine? Load all the chunks on the local machine? Not show or simulate them if they're more than a kilometer away? Why is the game multiplayer then?

Finally, a modern server has 256 GB of RAM or more. I don't think you can buy servers with only 32 GB anymore (although that seems to be the upper limit for regular laptops, and Apple is behind at 16 GB.) You can certainly rent fractional servers with much less RAM, though. Then, you may have to worry about CPU availability instead. In general, though, I wonder about the size of your levels, and where that content is coming from.

enum Bool { True, False, FileNotFound };
Advertisement

Yeah I don't have a height map or render data loaded. With just collision data and terrain patch, tree, and rock positions loaded the chunks are 8MB. I might be able to make map chunks smaller in memory size if I just use one huge patch for map chunks instead of 100x100, 8x8 meter patches.

The players are re-positioned when they reach a map edge, along with the map chunks on the client. Playable area is within 0-800 meters in x/z dimensions. Although remote players can be within -800 to 1600 meters on the client end. On the server end, the maps are on different layers and stacked vertically, so once a player reaches the map edge the can be swapped to the corresponding layer/map chunk stack.

Map chunks are partly procedural and randomly created, the terrain is created with 2 passes of perlin noise with seeded randomly placed hills/mountains/valleys for each map chunk. Trees and rocks are randomly placed too. I'm still working on making interesting procedural map chunks though so load time will probably increase.

Not all chunks will be loaded for each player on the client.. Just the 9 that they occupy. There is multiplayer content, but from my experience most players like to solo level or level with a friend or two, that's why I'm thinking of the worst case scenario of every player needing their own 9 chunks.

A server with 256GB of memory is more than I can afford atm. I might try to get crowd funding once the game nears completion. If I can't do that I'll just have to deal with a smaller play space, until I can get some sales.

 

you could use lower resolution terrain and bounding-box-only collision for the server and allow an error of like 5cm. also limit player speed to like 10m/s, which is about as fast as humans can possibly go. 

on the client there is no point in just loading 9 chunks per player - if players' chunks aren't connected, loading them would look silly. maybe do like minecraft does and just keep loading chunks until you reach max-draw-distance, but prioritize chunks near players. 

for AI i'd generate a simplified path-map per chunk. take care with the transitions between chunks though. you could use that for player checking on the server-side too.

I think the only option to decrease memory by a worthwhile amount is to decrease the resolution of the terrain patches since those use mesh collision. The trees and rocks already use box colliders, so not much I can really do there besides reduce the number of them which is already low enough to hardly be a concern.

I guess I didn't explain it well enough... 9 map chunks are only loaded for the client player on the client app, not for each remote player on their machine. The map chunk stacks are only loaded on the server end until they run out of the desired float precision, then another physics instance can be launched.

I'll keep the suggestion about AI pathing in mind but I might have to use something more simple.

16-thread, 122 GB instances are $1/hour on Amazon. Or you could blow $13/hour for a 1900 GB server with 128 threads :-)

By the time you have enough players that you need more than 8 GB of RAM or whatever, you probably also have enough subscribers to pay for the servers to run it.

How does a player on tile X shoot/collide/interact with a player on tile X+1 if they are vertically stacked on the server? Do you teleport any projectile, and not use any raycast weapons? Maybe there are no player collisions that matter across tile edges?

Anyway, I don't see why you couldn't just load each tile on the server for now, and keep an eye on memory consumption of tiles, and by the time you have enough content and players that it matters, go for something with more RAM.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement