Skip to content

Timing problem with inter-entity operations when two entities are created at the same time #23

@Schwarzbaer

Description

@Schwarzbaer

Practical example: wecs.panda3d.prototype, PhysicsWorld and PhysicsBody:

  • entity_a is created, and PhysicsWorld is added. The addition is deferred.
  • entity_b is created, and PhysicsBody(world=entity_a._uid) is added. The addition is deferred.
  • Deferred updates are flushed, processing entity by entity.
    • By chance, entity_b gets processed first. prototype.ManageModels.enter_filter_physics(entity_b) is called.
    • It tries to attach entity_b[PhysicsBody].node to entity_a[PhysicsWorld].world
    • entity_a doesn't have a PhysicsWorld yet, though, since the entity's deferred updates haven't been flushed yet.

As things are now, it seems to be an unstated rule that enter_filter_* functions may only modify the entity itself, or entities that are guaranteed to be in a working state (meaning that it's safe for the entity to be referenced by other entities for the working state's intended purpose; Here, attaching physics bodies). However, that is not guaranteed to be the case in a scenario where entities are created at the same time, which ís kind of the intended use pattern when populating a world on starting a new game, loading a saved game, or synchronizing with a network server.

Several solutions come to mind:

  • Declare this to be an invalid use case; inter-entity modifications should not be done in enter_filter_*, only in update(). That would probably incur a linear and small overhead per entity each time the system is run, checking whether each entity needs to be updated. At the same time an approach like that leads to some flexibility, e.g. swapping an entity over from one physics world / streaming terrain region / etc. to another.
  • Flushing should be a two-phase process, first flushing the entities by themselves, then triggering inter-entity modification. This would probably lead right back to the same problem once three entities are involved.
  • Flushes should happen system by system, instead of entity by entity. Probably they should even happen filter by filter. This is pretty much guaranteed to lead to messy flushing code, and might bring up other unexpected architectural problems.

Metadata

Metadata

Assignees

No one assigned

    Labels

    designProblems with how we do ECSshowstopperThis is of fundamental importance for further progress

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions