Search Unity

SubScenes for tiles world

Discussion in 'Entity Component System' started by Bokus, Jul 19, 2021.

  1. Bokus

    Bokus

    Joined:
    Apr 28, 2014
    Posts:
    16
    Hello,

    I have a game in DOTS that use tiles (prefabs) to randomly generate map.
    Issue is performance since converting 20+ tiles to ECS is slow, so for that reason I was looking at SubScenes.
    Problem is I can't load same SubScene twice it seems.
    upload_2021-7-19_20-59-55.png

    Is there a way to achieve this with SubScenes or this is not a good use case?

    Thanks!
     
  2. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708
    Curious what is slow about the tile conversion
     
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,778
    We need profiler here.
    20+ how many is it? 100, 1000, 10k?
    What tiles generation involves and how is written?
     
  4. Bokus

    Bokus

    Joined:
    Apr 28, 2014
    Posts:
    16
    I'm using default Convert to Entity component.
    Tile is a prefab that contains some low poly object like trees, rocks, etc.

    I would choose to create a map let's say 15x15 tiles with selecting random tile prefabs.

    If I use Convert to Entity it takes about 5minutes for game too load. It gets stuck on EnterPlayMode.
    upload_2021-7-20_9-20-19.png

    Here is the stats of loaded scene. Lot of Verts...
    upload_2021-7-20_9-11-24.png


    If I remove Convert to Entity component from the tiles, game loads almost instant.

    I read somewhere that individual conversion is slow and that recommended way of doing this is using SubScenes, but I don't see how can I achieve with them this random maps where some tiles (SubScenes) would repeat.
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,778
    You got something wrong going there.
    I use entity conversion for hundreds of entities, including hierarchies. That takes startup of few se seconds. Slow means, shouldn't be executed at runtime, as it could generate game slowdown in some cases. But you need have many of conversions happening, or massive hierarchies.

    So in your case, you must have something going badly.

    Here is a thing for you to try.
    Disable all objects, which need be converted. You have done that.
    Enable one of go to be converted. Check load time.
    Enable second. Check runtime.
    Repeat untill all enabled.
    Look for Go which cause conversion issue.

    I could suspect, you maybe have some components on go, which cause the issues.

    Can you show use your hierarchy of GOs, which you convert?
     
  6. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    Are your prefab reference (rock/tree/...) in each tiles ? Or did you build a "tile type" dictionary ?
    If each tile reference 100 identical prefab I'm not sure the conversion pipeline is able to optimize and detect that it already converted that same prefab earlier. You may end up with 15x15x100 conversion.
     
  7. Bokus

    Bokus

    Joined:
    Apr 28, 2014
    Posts:
    16
    You are right!

    It's not a conversion that it is slow, but the system that I have which is ran on each converted Entity.
    When I was testing it there was couple of tiles only and I didn't notice performance issues.
    I concluded that SubScenes approach is working faster because for SubScenes everything is already an Entity so my system would run only once since all tagged entities are there.

    I created this system to scan grid when entities are converted which is now slow for lot of tiles.
    Is there a way for me to know when all Convert To Entity are finished so I can run grid scan only once?

    One way is to run it with Invoke with some delay but timing can vary on different devices and callback would be better option.
     
  8. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    One thing worth mentioning is you don't want multiple sub scenes, sub scene per tile is (very) wrong. A sub scene is a container, or more specifically you have the SubScene component that references the entity scene, and your tiles would go inside that entity scene.

    You really need to read the conversion flow documentation *all of it*. Most people I'm afraid don't and miss some fairly key bits. Like the fact they create a headless Unity instance for each sub scene. If the fact that it's a container isn't enough of a clue to not have a lot of them, the instance per sub scene should be.

    You also have IConvertGameObjectToEntity and IDeclareReferencedPrefabs. So there are different tools for prefabs vs scene gameobjects. Ie you could have a single GameObject in your sub scene that just references a bunch of tile prefabs in the hierarchy. So if you wanted to dynamically instantiate a random set of tiles when loading a scene, you would want to use IDeclareReferencedPrefabs along with just loading the sub scene on game start. And then instantiating tiles from entity prefabs in code.
     
    Bokus likes this.
  9. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    What about for world chunks which contain terrain data, many objects, etc?
     
  10. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    Isn't the headless unity instance created only once and used for all subscenes and only when there is something to convert ?
     
  11. Luxxuor

    Luxxuor

    Joined:
    Jul 18, 2019
    Posts:
    89
    That is incorrect, neither does it mention that in the documentation nor is that what you can observe in practice. There is only one instance that is doing the conversion in the background, so having many SubScenes is nothing you should avoid.

    That being said, conceptually SubScenes are similar to scenes only that they contain Entities instead of GameObjects so the same kind of limitations apply to them. Maybe instead of loading certain scenes multiples times you should instantiate prefabs (that you can pre-convert at build time by having them in a SubScene, kind of like a "prefab collection").
     
  12. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Ya you guys are right it's a single headless instance, it's just multiple console hosts.

    Sub scenes do have overhead though and being containers I see no gain from having multiple of them scoped to a scene on average, maybe for very heavy scenes in some cases.

    The per sub scene loading overhead is fairly substantial, that's in a build. It's around 80ms on my setup which is quite average. I was converting some custom binary serialization flows to sub scenes where I knew exactly what the costs were and where. I think most of it is actually the scene loading. So a lot of sub scenes loading at once will add up quickly.
     
  13. Bokus

    Bokus

    Joined:
    Apr 28, 2014
    Posts:
    16
    So for my issue how to find when all GOs are converted to Entities, since I didn't find any callback, I changed how my system works.
    I run the system every X milliseconds and if any converted entitles (with a tag) are found I would do a grid scan.

    That potentially opens possibility for loading more tiles later on and they would be automatically scanned.