dominion-dev / dominion-ecs-java

Insanely fast ECS (Entity Component System) for Java
https://dominion-dev.github.io
MIT License
288 stars 17 forks source link

Bug with Inheritance #183

Closed ghost closed 10 months ago

ghost commented 11 months ago

Through my time of attempting to use this ecs I noticed one glaring problem. That problem being that this ecs does not play nicely with components that utilize inheritance. In the example below we create two entities where one uses the super class component and the other uses the subclass component.

public class Main {
    public static void main(String[] args) {
        Dominion dom = Dominion.create();
        dom.createEntity(new DemoA());
        dom.createEntity(new DemoB());
        Scheduler scheduler = dom.createScheduler();
        scheduler.schedule(() -> {
            System.out.println("ALL DEMOA COMPONENTS");
            dom.findCompositionsWith(DemoA.class)
            .stream().forEach(r -> r.onExec());
        });
        scheduler.schedule(() -> {
            System.out.println("ALL DEMOB COMPONENTS");
            dom.findCompositionsWith(DemoB.class)
            .stream().forEach(r -> r.onExec());
        });    
        scheduler.tick();
        scheduler.shutDown();
    }
    private static class DemoA {
        public void onExec() {
            System.out.println("A");
        }
    }
    private static class DemoB extends DemoA {
        @Override
        public void onExec() {
            System.out.println("B");
        }
    }
}

Now the expected result is that since DemoB inheriets from DemoA, when we query for compositions utalizing DemoA, the entitiy that has DemoB would be type casted into DemoA producing the result below:

ALL DEMOA COMPONENTS
A
B
ALL DEMOB COMPONENTS
B

However when the example is run it produces the following result:

ALL DEMOA COMPONENTS
A
ALL DEMOB COMPONENTS
B

Regardless of if this is a bug or the intended implementation by the author I believe that dominion needs to support inheritance as it is a must have in more complex systems that benefits from the ECS paradigm such as physics and graphics engines.

enricostara commented 11 months ago

Hi @liam-dev2021, this is exactly how ECS works. This design promotes composition over inheritance, and DemoB need not extend DemoA.

ghost commented 11 months ago

The example provided is simply a minimal reproducible example to illustrate the issue at hand. In a real world scenario complex engines such as a game engine with physics, graphics, and especially user scripting would need inheritance because we can not realistically account for every possible implementation that a user would need or possible would want implemented themselves. Another thing to note is that other ecs engines can support inheritance as shown by the extremely popular Unity Game Engine.

enricostara commented 11 months ago

There is no complex real-world scenario that cannot be handled using composition alone. This may require a change in how you abstract your code, but it comes with many benefits. Check this out: https://en.wikipedia.org/wiki/Composition_over_inheritance And, even more, in ECS composition over inheritance is a model that comes without any hack or unnatural design

enricostara commented 10 months ago

Closing the issue, thank you for your input