Multiple physics world support

I am toying around with having an ECS Server world which has multiple running worlds for different session simulations independent of one-another.
(A fix for this would be to potentially just run multiple Unity instances to circumvent these issues, but I am using this as more of a ECS learning experience atm)
Multiple Worlds
I am wondering if there is a proper way of updating multiple worlds?
I saw this thread as a reference ScriptBehaviourUpdateOrder.UpdatePlayerLoop() no longer support multiple worlds in 0.0.26
I am currently using a default world which has a system to manually update each world’s systems, which seems like an odd approach since I would like to toss this at a lower level like the PlayerLoop to have it manage all the worlds, or even somehow run them in parallel since their data is isolated to itself, but doing this would require being run off Unity’s main thread which obviously causes massive issues :(.

Unity.Physics (ECS)
There seems to be several references to World.Active inside the package which would cause issues with running multiple physics simulations in different worlds. I am wondering if this is a temporary workaround? Or is it intended to only work on the Active world only?

2 Likes

Yes right now, to toss it at a lower level, you’d either have to use reflection or modify the Entities source directly. Reflection is fairly straightforward. For example, to insert a SimSystemGroup into FixedUpdate.

static MethodInfo insertManagerIntoSubsystemListMethod = typeof(ScriptBehaviourUpdateOrder).GetMethod("InsertManagerIntoSubsystemList", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

public static void UpdatePlayerLoop(World world) {
    var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
    if (ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList != null)
        playerLoop = ScriptBehaviourUpdateOrder.CurrentPlayerLoop;
    if (world != null) {
        for (var i = 0; i < playerLoop.subSystemList.Length; ++i) {
            int subsystemListLength = playerLoop.subSystemList[i].subSystemList.Length;
            if (playerLoop.subSystemList[i].type == typeof(FixedUpdate)) {
                var newSubsystemList = new PlayerLoopSystem[subsystemListLength + 1];
                for (var j = 0; j < subsystemListLength; ++j)
                    newSubsystemList[j] = playerLoop.subSystemList[i].subSystemList[j];
                var mgr = world.GetOrCreateSystem<SimSystemGroup>();
                var genericMethod = insertManagerIntoSubsystemListMethod.MakeGenericMethod(mgr.GetType());
                genericMethod.Invoke(null, new object[] { newSubsystemList, subsystemListLength + 0, mgr });
                playerLoop.subSystemList[i].subSystemList = newSubsystemList;
            }
        }
    }

    ScriptBehaviourUpdateOrder.SetPlayerLoop(playerLoop);
}

I don’t have too much experience with Unity.Physics, but the conversion workflow right now also depends on hardcoded World.Active at the present. To deal with that, I had to write my own custom ConvertToEntity script which can setup which world it uses at editor time. Generally, it’s not bad since the current ConvertToEntity is not complicated and while writing my own I could re-use some existing functionalities (but yes Unity can do better by making more useful things public instead of protected and internal).

So I’m not sure if a similar approach can be taken when dealing with Unity.Physics and multiple worlds.

Hmm, I see that is quite unfortunate that this is not exposed at a higher level. I hope that Unity exposes this type of functionality eventually.

Sadly all the calculations are done inside the Unity.Physics package and there doesn’t seem to be a good way of changing it unless I forked it. However after looking at their road-map they have a 2D ECS physics which says that it intends to support multiple worlds, I hope they will be applying the same functionality to this one as well.
Another annoying bug I noticed is that all the systems in any new worlds created do not show in the Entity Debugger editor, this is quite annoying :eyes:

Worlds for client and server simulation is solved in the current netcode, take a look at it: https://github.com/Unity-Technologies/multiplayer/blob/master/sampleproject/Assets/NetCode/ClientServerWorld.cs

Physics doesn’t support many worlds yet. Once the new netcode is released I’m also expecting a solution for that.
So right now, use legacy physics or wait a while, it shouldn’t be that far off anymore.

1 Like

Can’t believe I missed it. Is it in the Unite Roadmap video? 2D ECS Physics is something I’m rooting for the most. Sadly info has been scarce.

They show up fine in the Entity Debugger for me (using the above reflection or using the official method). I think you may be a small tweak away from fixing that.

That is actually a very useful insight. So they are essentially reassigning the Active World each iteration of each world when each world updates. I would have though that some underlying Unity functionality would have disliked this approach, going to have to definitely toy around with this :slight_smile:

Using the approach method should fix the World.Active issue I was having, I was trying to leave the Active world as the main processing world that just updates all the other worlds. in loose terms a “Processor World”.

It is located in their official Unity Roadmap page in the “Development” section.
https://unity3d.com/unity/roadmap
From the road-map:
2D Physics
Multi-instance 2D physics worlds.
Ability to assign simulation group(s) to Rigidbody2D and simulate specific group(s) and/or calculate contacts for those group(s) only.
Expose contact processing allowing users to defer contact solving, enable/disable contacts etc.

Hmm, I might give it a try in the 2019 build (currently using 2020 preview), might make a difference. I have the systems added and they show in the debugger (Visual Studio) and they update when called, but they don’t show in the debugger. ¯_(ツ)_/¯

Oh AFAIK that’s not related to ECS/DOTS. It’s been in dev for a long time and a lot of it is available today. You can refer here for more info: https://discussions.unity.com/t/661750

Hmm I just noticed it on the road-map, I was assuming that multiple world support meant DOTS worlds :frowning: