Search Unity

Floating origin and multiplayer

Discussion in 'Scripting' started by nicespace, May 28, 2015.

  1. nicespace

    nicespace

    Joined:
    May 28, 2015
    Posts:
    5
    I'm working on a space game. (Yes I know, but just stay with me for a minute) I've already done the researching on Floating Origin and have a working single player experience and dedicated server.

    I have three scale levels, Galaxy, Solar System, and Sector. Each one keeps the player + objects inside 5k distance to keep floating point problems away. This all works great for single player.

    However, I've been trying to work out how to make it multiplayer. Things get very ugly fast with all the options I've researched.

    Option 1) Independent physics layers

    This option puts a unique sector on each physics layer and disabling (via project settings) interaction between layers. All objects on the layer can interact as normal. They all are at origin 0,0,0 so no floating point problems. Once they leave the sector, a new sector is loaded into that layer.

    Pros:
    + Able to use full physics (raycast, OnTriggerEnter/Exit, etc.)

    Cons:
    - Limited to ~20 layers and thus only 20 players per server.

    Option 2) Manual GameObject disable/enable

    This option involves creating a tree of objects. Each sector would then contain all objects and be activated/deactivated one at a time each frame. IE:

    sector[id].SetActive(true); sector[id].BroadcastAll(“Update”); sector[id].SetActive(false);

    To allow scripts to function using Update(). Testing of this seemed to show Fixed update doesn't work this with this method even when using Rigidbodies.

    Pros:
    + No practical limit on number of layers/sectors so many more players supported

    Cons:
    - No physics, no OnTriggerEnter/Exit work. However, Raycast inside Update() do work
    - No use of velocity, impulses/explosions, etc. without extra manually created code

    Option 3) Let the client do physics/AI/etc.

    Pros:
    + Server only needs to keep track of object and player locations.

    Cons:
    - Way too easy to cheat
    - Who runs AI? First player to a sector? What happens if they disconnect with other players in same zone?
    - Lots of objects and AI can slow down client's computer.

    Are there any other options I've missed? How would you handle multiplayer?
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    It's gonna be ugly no matter what you do; this is not really a situation that Unity was designed for.

    If you don't need the heavyweight features of PhysX (e.g. if you aren't writing Kerbal Space Program), you might consider looking into an alternative physics engine. Check out uPhysicsPro on the Asset Store, for example. Since you'd have access to much of the source code of the physics engine, you might be able to modify it to allow an arbitrary number of physics 'zones' (like option 1 without the limit based on layers). There's an active thread on the forums about this asset, you could probably ask the dev if this engine is suitable for your problem.
     
  3. nicespace

    nicespace

    Joined:
    May 28, 2015
    Posts:
    5
    I looked over uphysics manual and couldn't find anything about layers or similar... will have a go at contacting dev.

    I think the core features that are most needed are raycasts (so need working colliders) and triggers (OnTriggerEnter/Exit/Stay). But again, I'd end up having to code/simulate things like object collisions and forces which isn't ideal either.

    Makes it hard with having only one running scene at a time with the floating point problems.
     
  4. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    You also have the option to ignore physics between specific objects:
    Physics.IgnoreCollision
     
  5. sluice

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
    @nicespace, I don't really like saying so, but Unity is not the only option out there, you might want to search a bit on other engines... Forget about Unreal as it runs PhysX also, but maybe Cry Engine? I don't know..

    If you prefer Unity, I would probably go with Option #3.
    There is no way for you to go fully Authoritative if you are using PhysX. Each client will run their own physics simulation.

    Still, the host should be the one responsible for things like the AI. He's the one that will send info to the other client.
    Thus the AI behaviour will be replicated on clients on the host's order. He would be the one that sets the physics on every client. Think of it this way: Every client are playing in a parallel universe/dimension of each other. What you see is a "simulation" of what others sees. Player A and Player B are looking at the same Cube. It looks like the same cube, but in fact it's not. If Player A moves the Cube, that info needs to be sent to Player B, etc.

    You can still use an Authoritative approach and code in a way the clients ask permissions to the host for most things.
    And Remember that many popular multiplayer games are not even Authoritative because as much as it helps against cheating, it impacts performance and remember that there will be cheaters no matter what the approach is.

    For the Cheating, you could start with the Anti-Cheat Toolkit: https://www.assetstore.unity3d.com/en/#!/content/10395

    Here's a perhaps relevant read: http://kotaku.com/5869564/networking-how-a-shooter-shoots
     
  6. nicespace

    nicespace

    Joined:
    May 28, 2015
    Posts:
    5
    @sluice, It's not just cheating as you run into the same floating point problems with option 3.

    Example. Sector 1 (players A and B)

    A gets to sector first, so he creates the AI (enemy) and asteriods/etc. Player B then arrives and is told by master server that A has the real objects. A issues RPC to B and spawns clones of A's objects. Things are okay for the moment, but then A moves 4k from center (0,0,0). B moves 4k in other direction. Now A and B players are 8km apart.

    If you assume that the world max radius is 5k, then the distance from center of A (say 4000,0,0) to B (say -4000,0,0) would be -9000,0,0) (4k + 5k) At that range floating point issuse are already becoming a problem. And since A is acting authoritive in that model B is getting his data from A.

    And does every player who comes to sector 1 have to then get everything sync from A? Option 3 really is nasty option I only listed for sake of completeness. :)
     
  7. nicespace

    nicespace

    Joined:
    May 28, 2015
    Posts:
    5
    I guess there is one last option, but it's very ugly too... don't use unity for server and replace the physics and networking.

    So maybe C++ server, bullet physics and some networking subsystem that will work in unity as well. At that point unity will only be running as a dumb client. So just like an MMO at that point. :eek:

    Seems the only two choices are 1) 10-20 players max on layers or 2) MMO.
     
  8. mattis89

    mattis89

    Joined:
    Jan 10, 2017
    Posts:
    1,151
    hello! Did anyone come to a solution?
     
  9. dwatt-hollowworldgames

    dwatt-hollowworldgames

    Joined:
    Apr 26, 2019
    Posts:
    104
    adding pos += _CameraPosition; to line 329 of the shader seems closest but clouds still are in a slightly different place after shifting.