Search Unity

How to create custom world???

Discussion in 'Entity Component System' started by illinar, Apr 17, 2021.

  1. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    Why is that so obscure? The documentation is impossible to find. Only outdated posts from 2018.

    I create custom world with
    new
    . I create systems with
    CreateSystem();
    Then update never happens wen I run
    world.Update();
    and none of the systems show up in entity debugger.

    No google search gives any useful information. Please help.
     
  2. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    Started to find bits and pieces of code. Mostly associated with ICustomBootstrap. Ended up with this code:

    Code (CSharp):
    1. public class WorldCreator : MonoBehaviour
    2. {
    3.     World World;
    4.  
    5.     void Start()
    6.     {
    7.         World = CreateSimulationWorld("BattleSimulationWorld");
    8.     }
    9.  
    10.     public World CreateSimulationWorld(string name)
    11.     {
    12.         IReadOnlyList<Type> systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
    13.         List<Type> simulationSystems = new List<Type>();
    14.  
    15.         for (int i = 0; i < systems.Count; i++)
    16.         {
    17.             if (systems[i].Namespace != null && (systems[i].Namespace.Contains("UnityS") || systems[i].Namespace.Contains("BattleSimulation")))
    18.             {
    19.                 simulationSystems.Add(systems[i]);
    20.             }
    21.         }
    22.         Debug.Log(simulationSystems.Count);
    23.  
    24.         var world = new World(name, WorldFlags.Live & WorldFlags.Simulation);
    25.         DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, simulationSystems);
    26.         ScriptBehaviourUpdateOrder.UpdatePlayerLoop(world);
    27.         var simulationGroup = world.GetOrCreateSystem<SimulationSystemGroup>();
    28.         return world;
    29.     }
    30.  
    31.     void Update()
    32.     {
    33.         World.Update();
    34.     }
    35. }
    It finds 20 systems. Two of them are my custom systems, the rest are a modified unity physics and transforms systems.

    I can see my two, but not the other ones.

    Edit: Silly me, the transform systems were nt showing because of Show Inactive was false, now true. But the physics systems are not showing up...
     
    Last edited: Apr 17, 2021
    Songerk likes this.
  3. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    If anyone has any ideas about why half of the systems don't register amd don't show up in update loop, please tell me.

    Physics systems are in
    simulationSystems
    list, but are not visible as part of the world.
     
  4. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    866
    I think that custom worlds do not show in entity debugger. For me when I UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP I do not see anything.

    The world and systems do exist. Did you check if onUpdate is getting called in your systems using debug.log?

    I forget exactly but ScriptBehaviourUpdateOrder.UpdatePlayerLoop is not needed since you are manually calling update,
     
    Last edited: Apr 18, 2021
  5. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    All systems that I add are there I checked. But none of the physics systems show up in the debugger. I think I can still work with that, but would be good to see them.

    ScriptBehaviourUpdateOrder.UpdatePlayerLoop(world);

    Adds the systems into the update loop in a way that makes them visible in entity debugger. However I didn't realize that it causes them to actually automatically update. So I will have to remove that.

    So now I'm back to not knowing how to show my systems in the debugger. Not a huge deal, but I'd love to know how to see them there without making them a part of the loop.

    @TheOtherMonarch Thanks for the tips.
     
    Last edited: Apr 18, 2021
  6. Rupture13

    Rupture13

    Joined:
    Apr 12, 2016
    Posts:
    131
    Is there a reason you don't want to use the ICustomBootstrap to initialise your custom world? Doing so has worked perfectly for me, with systems properly being added and the world (and systems) being properly shown in the entity debugger.

    I found the documentation on ICustomBootstrap still a bit fuzzy, but if you would want to go down that road, I and others here could probably help you.
     
  7. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    866
    1: ICustomBootstrap does not allow easy manual updating / easy network synchronization. You have to update from a monobehaviour.

    2: ICustomBootstrap happens when the game first starts. If you have a loading menu scene etc. It will happen then rather then in the true game. So ICustomBootstrap kind of breaks mult-scene games.
     
    Last edited: Apr 19, 2021
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    I don't understand this at all? What does a monobehaviour have to do with ICustomBootstrap

    What you should be doing is setting up your default world in the custom bootstrap while caching the list of systems you need for each other world that you can create at later points (look at netcode for example.)

    The trick is actually to only have 1 world in the update loop with all other worlds updates called from the default world groups.

    This is how netcode works and if you look at it's bootstrap, when it creates the server/client worlds it gets the core groups in the server/client worlds then adds them to the base groups in the default world.

    Code (CSharp):
    1. // server world
    2.  
    3. var initializationGroup = world.GetOrCreateSystem<ServerInitializationSystemGroup>();
    4. var simulationGroup = world.GetOrCreateSystem<ServerSimulationSystemGroup>();
    5.  
    6. //Pre-create also all the necessary tick systems in the DefaultWorld
    7. var initializationTickSystem = defaultWorld.GetOrCreateSystem<TickServerInitializationSystem>();
    8. var simulationTickSystem = defaultWorld.GetOrCreateSystem<TickServerSimulationSystem>();
    9.  
    10. //Bind main world group to tick systems (DefaultWorld tick the client world)
    11. initializationGroup.ParentTickSystem = initializationTickSystem;
    12. initializationTickSystem.AddSystemToUpdateList(initializationGroup);
    13. simulationGroup.ParentTickSystem = simulationTickSystem;
    14. simulationTickSystem.AddSystemToUpdateList(simulationGroup);
    15.  
    Code (CSharp):
    1. // client world
    2.  
    3. var initializationGroup = world.GetOrCreateSystem<ClientInitializationSystemGroup>();
    4. var simulationGroup = world.GetOrCreateSystem<ClientSimulationSystemGroup>();
    5. var presentationGroup = world.GetOrCreateSystem<ClientPresentationSystemGroup>();
    6.  
    7. //Pre-create also all the necessary tick systems in the DefaultWorld
    8. var initializationTickSystem = defaultWorld.GetOrCreateSystem<TickClientInitializationSystem>();
    9. var simulationTickSystem = defaultWorld.GetOrCreateSystem<TickClientSimulationSystem>();
    10. var presentationTickSystem = defaultWorld.GetOrCreateSystem<TickClientPresentationSystem>();
    11.  
    12. //Bind main world group to tick systems (DefaultWorld tick the client world)
    13. initializationGroup.ParentTickSystem = initializationTickSystem;
    14. initializationTickSystem.AddSystemToUpdateList(initializationGroup);
    15. simulationGroup.ParentTickSystem = simulationTickSystem;
    16. simulationTickSystem.AddSystemToUpdateList(simulationGroup);
    17. presentationGroup.ParentTickSystem = presentationTickSystem;
    18. presentationTickSystem.AddSystemToUpdateList(presentationGroup);
    And that's how you get them to show up in the entity debugger
     
    Last edited: Apr 20, 2021
    Lukas_Kastern likes this.
  9. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    866
    I create a two new worlds with Start() update them with Update() and Dispose with OnDestroy(). Works really well. I can still reload the loading menu scene and get fresh worlds.

    Unity's netcode is very different from how my networking works. I have lock-step hybrid using a low level transport layer. I really not sure why I would want a list of systems I am reusing worlds using CopyAndReplaceEntitiesFrom. I don't have a client / server I have a delayed deterministic lock step world and a predictive world both running on each computer. I still have a reconciliation server but only to compile inputs and that is in monobehaviour land with fixed point math.

    Since I need to control when, how and how often the the "main" lock step world is updated and when to roll back the predictive world "the world you see" and resimulate calling updated using a monobehaviour is critical. All of my prefab entities also live in the same monobehaviour.

    Remember DefaultWorldInitialization.GetAllSystems will get you all systems that are not tagged with [DisableAutoCreation]

    It would be nice to have a working entity debugger but I have found it not to be need.
     
    Last edited: Apr 20, 2021
  10. Rupture13

    Rupture13

    Joined:
    Apr 12, 2016
    Posts:
    131
    So it really depends on the project you're making when deciding for ICustomBootstrap or another custom solution (like your manual MonoBehaviour). If the requirements of your project don't exclude ICustomBootstrap workflow, I would recommend using it so you can see your world and systems in the Entity Debugger.