Skip to content

Component added to a prefab after first instantiation is invisible to instances (regression in v4.1.0) #2239

Description

@TheAxeC

Describe the bug
Adding a component to a prefab after it has been instantiated leaves the component invisible to instances — including instances created afterwards. The (IsA, base) table-graph edge appears to be cached and not invalidated when the base gains a component, so whether a new instance receives the component depends on whether its source table's IsA edge already existed. Regression in v4.1.0 (v4.0.5 is correct).

To Reproduce

#include "flecs.h"
#include <stdio.h>
int main(void) {
    ecs_world_t *w = ecs_init();
    ecs_entity_t C = ecs_component(w, {.entity=ecs_entity(w,{.name="C"}), .type={.size=4,.alignment=4}});
    ecs_entity_t T = ecs_entity(w, {.name="Marker"});
    ecs_entity_t P = ecs_new(w); ecs_add_id(w, P, EcsPrefab);

    ecs_new_w_pair(w, EcsIsA, P);          /* caches edge {} --(IsA,P)--> {(IsA,P)} */
    ecs_add_id(w, P, C);                   /* prefab gains C AFTER that */

    ecs_entity_t f1 = ecs_new_w_pair(w, EcsIsA, P);           /* same source table {} */
    printf("from empty table    : has=%d owns=%d\n", ecs_has_id(w,f1,C), ecs_owns_id(w,f1,C));

    ecs_entity_t f2 = ecs_new(w); ecs_add_id(w, f2, T);
    ecs_add_pair(w, f2, EcsIsA, P);                            /* different source table */
    printf("from {Marker} table : has=%d owns=%d\n", ecs_has_id(w,f2,C), ecs_owns_id(w,f2,C));
    printf("prefab has C        : %d\n", ecs_has_id(w,P,C));
}

Output on v4.1.6:
from empty table : has=0 owns=0
from {Marker} table : has=1 owns=1
prefab has C : 1

Expected behavior
from empty table : has=1 owns=0
from {Marker} table : has=1 owns=1
prefab has C : 1

Both instances should receive C (has=1), since both are created after the prefab gained it. On v4.0.4/v4.0.5 both instances see it. If mutating an instantiated prefab is no longer supported, it should throw as v4.1.6 already does for children of an instantiated prefab (Throw error when changing children of already instantiated prefab) rather than silently produce instances that differ by source table.

Additional context

  • Checked on v4.0.4, v4.0.5, v4.1.0, v4.1.1, v4.1.6, change in behaviour starts from v4.1.0
  • macOS arm64, clang, distr/flecs.{c,h} amalgamation, default build.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions