ES question(s)

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
I'm trying to get a little deeper into understanding the ES and optimizing exactly how to use it so I thought I'd toss a thread here for some questions - only really expecting Immortius to have the answers but I figure it might be insightful in general for it to be in the forum :)

Starting off I've long wondered how come placing a portal block creates two spawner-bearing entities. Only one of them becomes a "valid" Spawner (requires that it also hold either a Block or Location component) and actually spawns stuff - and actually the one entity is both where I thought a block would be a block (integer position) and a model would have a location (float position).

Here they are via dumpEntities:

Code:
    {
      "id": 95,
      "parentPrefab": "engine:blockType",
      "portals:Spawner": {
        "minDistance": 0,
        "timeBetweenSpawns": 5000,
        "rangedSpawning": false,
        "range": 20,
        "maxMobsPerSpawner": 16,
        "playerNeedRange": 10000,
        "lastTick": 0,
        "types": "RedTeamLAS",
        "needsPlayer": false
      },
      "engine:PlaySoundAction": {
        "volume": 1.0,
        "relativeTo": "Instigator",
        "sounds": "portals:spawn"
      },
      "portals:Portal": {},
      "portals:Holding": {
        "queenMax": 5,
        "queenThreshold": 10,
        "queenCurrent": 0
      },
      "engine:BlockType": {
        "block": "portals:portal"
      }
    },

Code:
    {
      "id": 96,
      "parentPrefab": "Portals:portal",
      "engine:Location": {
        "position": [
          -3.0,
          138.0,
          7.0
        ],
        "scale": 1.0,
        "rotation": [
          0.0,
          0.0,
          0.0,
          1.0
        ],
        "replicateChanges": true
      },
      "portals:Spawner": {
        "lastTick": 153096
      },
      "engine:Block": {
        "position": [
          -3,
          138,
          7
        ]
      },
      "engine:Health": {
        "nextRegenTick": 0,
        "regenRate": 2.0,
        "horizontalDamageSpeedThreshold": 100.0,
        "currentHealth": 10,
        "maxHealth": 10,
        "waitBeforeRegen": 1.0,
        "fallingDamageSpeedThreshold": 20.0,
        "excessSpeedDamageMultiplier": 10.0
      }
    },
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
The first entity is the "block type" entity. There is one of these for each type of block, and it is primarily used by the bulk "block loaded/unloaded" events when chunks are loaded/unloaded. Perhaps ultimately these will become prefabs. These do not represent blocks in the world, and there should only ever be one (not one every time a block is placed).

The second is the entity for a block in the world. It has a Block component identifying it as a block and where that block is placed (and we could put more into here like a reference to the block type). I also included a Location component marking the center of the block for the use by other components/systems that use location - such as mesh rendering. This means you can have an invisible block with a mesh or skeletal mesh component and that will be rendered. I've also been tempted to try giving torch blocks a Light component and removing their "block" based lighting.
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
Ahh! I remember the block type discussion now, just hadn't seen it in action yet. Thanks! :)

Would it then be safe to only ever look for LocationComponent and ignore BlockComponent, with the assumption that all placed Blocks also have Locations? Turns out I was actually seeing double from finding the same spawner first from its Location then from its Block, not because there were two entities (which makes sense with one entity being the type)

Another ES question also then, from EntityManager:

Code:
Iterable<EntityRef> getEntitiesWith(Class<? extends Component>... componentClasses);
What's the reasoning behind this (and similar methods) returning an Iterable rather than a Collection of some sort?
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Ahh! I remember the block type discussion now, just hadn't seen it in action yet. Thanks! :)

Would it then be safe to only ever look for LocationComponent and ignore BlockComponent, with the assumption that all placed Blocks also have Locations? Turns out I was actually seeing double from finding the same spawner first from its Location then from its Block, not because there were two entities (which makes sense with one entity being the type)
Yes, this would be safe.

Another ES question also then, from EntityManager:

Code:
Iterable<EntityRef> getEntitiesWith(Class<? extends Component>... componentClasses);
What's the reasoning behind this (and similar methods) returning an Iterable rather than a Collection of some sort?
I consider an iterable to be all that is typically required. It leaves it open whether the implementation will gather everything into a collection, or provide some sort of streaming, which leaves room for future work on thread safety or other features. The consumer can generate a collection from the iterable if desired.
 
Top