Failed to create world

Hello!

Currently playing with ECS and got to the point where I want to disable default bootstrap completely and create and configure my world manually. Im trying to keep thisng as simple as possible. Currently I have this

public class Game : MonoBehaviour
{
      private World _world;
     
      private InputSystem _input;
      /* +3 more systems */

      private void Awake()
      {
         _world = new World(gameObject.name);
         _input = _world.GetOrCreateSystem<InputSystem>();
         /* +3 more systems */
      }

      private void Start()
      {
         /* here I create a test entity with RenderMesh and stuff */
      }

      private void Update()
      {
         _world.Update();
      }
}

Also I have this at the top of the same script

// https://discussions.unity.com/t/696900/4
#define UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP

While it was working great with default world and bootstrap, now it is broken.

  • According to Entity Debugger, default world still exists and populated with my systems.
  • There are no systems in my custom world, only the enity I created
  • Nothing gets rendered on the screen.

It looks like I missed something obvious. Maybe there’s some example on how to disable all that magic stuff and create custom world being able to render a mesh in a simple and clean manner?

Finally, I’d like to have two worlds for simulation and game logic splitted to call simulation Update from Fixed update and logic and update from regular update. After that, I’d like to update the UI impleneted in monobehaviours. Is this a correct approach at all?

Is there a reason you are not using ICustomBootstrap?

1 Like

I want to learn how things works in first place. All what I’ve found on ICustomBootstrap is this forum topic https://discussions.unity.com/t/734379 (seems outdated) and this manual page https://docs.unity3d.com/Packages/com.unity.entities@0.3/api/Unity.Entities.ICustomBootstrap.html. I’m noth sure how to implement it? Also found nothing in ecs examples on github. Probably Im missing something obvious, that is the reason
I’ve tried it like the forum example, but it looks like in 0.3 the custom bootstrap can not be monobehaviour…

The manual about ICustomBootstrap is here : System Update Order | Entities | 0.3.0-preview.4

1 Like

It seems outdated. In the docs there’s

public interface ICustomBootstrap
{
    // Returns the systems which should be handled by the default bootstrap process.
    // If null is returned the default world will not be created at all.
    // Empty list creates default world and entrypoints
    List<Type> Initialize(List<Type> systems);
}

I’ve installed Entities 0.3 preview and what I’ve got is

namespace Unity.Entities
{
  public interface ICustomBootstrap
  {
    bool Initialize(string defaultWorldName);
  }
}

I’ve implemented it following my common sense

 public bool Initialize(string defaultWorldName)
      {
         _world = new World(nameof(Game));

         _input = _world.GetOrCreateSystem<InputSystem>();
         /* more systems here */
         _output = _world.GetOrCreateSystem<OutputSystem>();

         return _world.IsCreated;  // debugger says it's True here
      }

And default worlds disappeared, now there’s only one world in entity debugger, but there are no systems shown and no entities at all.

There’s a warning in the console saying

You are trying to create a MonoBehaviour using the 'new' keyword.  This is not allowed.  MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all

My game manager is set up as MonoBehaviour on active game object in the scene, but that Initialize method is invoked before scene load and Unity creates another instance of my bootstrapper without any game object (this.gameObject == null in debugger). Looks like I starting to undertand how it works, but more changes required to make my code do what I want.

Is there any more docs or examples with actual implementation or only outdated ones?

Also how to reference intial setup? I have some game options saved as scriptable object and my mono behaviour references it from scene. What would be best approach to this problem if I can’t use behaviour for game manager? Im thinking of using addressable currently, but I don’t see convenient way of doing it visually through some default editor workflow. Like a click there, drag that thing into this slot, settings changed, or something like this.

Also I probably need to add transformation and rendering systems manually since I’ve disabled default bootstrap? Maybe any docs for that or I should just look onto default world setup and do it likewise?

I’d like to dive into it as deep as possible.

The best docs for ICustomBootstrap are actually in the Changelog.

class MyCustomBootStrap : ICustomBootstrap
{
  public bool Initialize(string defaultWorldName)
  {
      Debug.Log("Executing bootstrap");
      var world = new World("Custom world");
      World.DefaultGameObjectInjectionWorld = world;
      var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);

      DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
      ScriptBehaviourUpdateOrder.UpdatePlayerLoop(world);
      return true;
  }
}

Once you have the list of systems, you don’t need to call AddSystemsToRootLevelSystemGroups. You can manually instantiate your systems and groups or insert them into multiple different worlds however you want.

UpdatePlayerLoop just grabs the InitializationSystemGroup, SimulationSystemGroup, and PresentationSystemGroup in the World and injects delegates for them into the player loop.

3 Likes

Thank you very much, this is exactly what I need. As for configuration, I just can catch up the world in mono behaviour and create entities according to config configured in the scene. This splits the initialization into two parts, and this make sense. I can create worlds and populate worlds and it is two different operations, nice