Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> A popular one is to group your entities by "archetype"- you have two arrays of Point2Ds, one for those without a Z coordinate and one for those with a Z coordinate. Now if you want all Point2Ds, you loop over both arrays; if you want all Point3Ds, you just loop over one. (This generalizes cleanly to larger numbers of "components.")

But now your Point2D code needs to be aware of the Point3D code. Violating the open-closed principle (which is an OOP principle, but one that's extremely useful in software engineering).

You NEVER want to change working code. That's the fundamental basis of the open-closed principle. Figuring out how to extend the code to new functionality ("open to extension"), WITHOUT risking any breaks on old code ("closed to modification"), is core to software engineering principles.

Any "solution" that relies upon changing Point2D is null-and-void to my software engineering brain. You cannot build libraries or reusable code if your solution is "rewrite the old code to support new functionality".



> But now your Point2D code needs to be aware of the Point3D code.

Not at all! You write the archetype management code once, and then the Point2D code just asks it for Point2Ds, nothing else, and that doesn't change no matter how you use Point2D elsewhere.


I'm having difficulty understanding how your proposal works.

In the beginning, there was one struct-of-arrays, the Point2D x and y arrays.

    int Point2D_x[];
    int Point2D_y[];
We also have a number of functions that use these two arrays. Point2D_foo(Point2D_index), Point2D_bar(Point2D_index).

Then, later, we discovered the need of Point3D code. Leading to the creation of one more struct-of-arrays (or 3-more arrays).

    int Point3D_x[];
    int Point3D_y[];
    int Point3D_z[];
Point3D_foo(), Point3D_bar(). Theres a 3rd function, Point3D_baz() that is specific to 3d code, but foo() and bar() are defined to be identical as the 2d versions. I haven't really figured out what parameters these 3d-versions of foo, bar, and baz would be like.

All "old" Point2D code was written only knowing about the first two arrays (Point2D_x and Point2D_y). The new Point3D code can be written knowing about all 5 arrays.

But I'm having difficulty seeing how you extend the old Point2D code to work on the new Point3d Arrays in the DOD case.


Here's a library in Rust that works this way: https://docs.rs/hecs/

You don't just have bare arrays sitting there. You have a separate part of your program that is responsible for managing them, playing a role similar to a relational database.

Now, to be clear, DOD/ECS/whatever doesn't mean "change all your Point2D methods to take an index instead of a `this` pointer." That gains you nothing on its own. If your `foo` and `bar` are just working with individual Point2Ds, then you can just write them that way- hand them a `Point2D* p` or `int* x, int* y` or something.

It's when you're working with large collections of these things, which exist as pieces of larger (conceptual) entities, that the arrays become important. And you can't know what that looks like until you have a particular operation in mind- are you stepping a physics simulation, or computing a shortest path, etc?

Now the trick is to write those larger-scale bulk operations in terms of queries, instead of direct access to the arrays. If your pathfinding algorithm is 2D, you can run it on all Point2Ds with a query for x and y components. If you later add a z component to some of your entities that already have x and y components, the pathfinding algorithm will keep working and just ignore the z component.


Hmm, I'll admit that this is the first time I've heard of the ECS pattern. So I'm not too familiar with your argument. From your description, and from various links discussing the pattern, it seems like an adequate solution to the problem I posed.

I would argue that an ECS is quite far removed from what the original article was talking about however. But perhaps the original article was too superficial in its discussion of DOD.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: