Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring objects (entities) #14751

Open
appgurueu opened this issue Jun 12, 2024 · 4 comments
Open

Refactoring objects (entities) #14751

appgurueu opened this issue Jun 12, 2024 · 4 comments
Labels
Discussion Issues meant for discussion of one or more proposals Maintenance Tasks to keep the codebase and related parts in order, including architectural improvements

Comments

@appgurueu
Copy link
Contributor

appgurueu commented Jun 12, 2024

My thoughts so far:

Separate "object refs" into "player refs" and "entity refs" (with "object ref" remaining a common base class). Deprecate calling player-only methods on entities and vice versa. I think this point, while a good chunk of work, is in principle straightforward.

What's less straightforward is how to deal with objects, long-term. Objects are currently effectively a "god class": They bundle a bunch of different responsibilities. This only gets worse as we add more and more features. I suggest we try to separate entity concerns.

A simple visual entity for example unnecessarily carries physical information such as a collisionbox, and is full of methods which are not of any interest.

Or perhaps for a more extreme example, an entity used just as a "joint" in an attachment chain to apply a transformation carries effectively all information except for its local transformation unnecessarily.

Furthermore, we might want to add convenience APIs (e.g. to facilitate writing mobs) in the future, which again many entities will not want to be "bloated" by.

Adding more entity "sub"classes would be too inflexible, since it wouldn't allow "mixing" these. We need something like an "entity-component-system". Entities would start out very barebones, just as points. Properties like visuals or physics would all be optional "components", managed separately.

What do you think?

@appgurueu appgurueu added Maintenance Tasks to keep the codebase and related parts in order, including architectural improvements Discussion Issues meant for discussion of one or more proposals labels Jun 12, 2024
@BluebirdGreycoat
Copy link
Contributor

I can't talk about Minetest's entity code specifically, but I just want to mention my own experience in ECS from working on my unpublished pet projects: entity systems don't really start to shine until you have a large collection of highly game-specific entities that you can mash together, with a full message-passing/event system for internal communication that allows maximum decoupling.

I should think that from an engine perspective, physics and visual is really all you need to deal with. Wouldn't ECS be better in Lua? For example, in C++ I haven't (personally) found any benefit in separating "point" into its own class, because literally everything needs it. Often, physics and visual are needed as well. Keeping them separate starts to feel like over-engineering.

However (and I'm just spitballing here), if the problem is that the object class is turning into a dumping ground for member datums, one can solve this (without a full-blown ECS) by extracting related datums into structs. The object class would then keep pointers to these structs, and these structs would only need to be allocated if the relevant APIs get called on the object. This could help to keep the memory footprint of the main object class low ...

Ignore me if I have no clue what I'm talking about.

@appgurueu
Copy link
Contributor Author

appgurueu commented Jun 16, 2024

Thanks for your input!

You are right that we don't have that many "components" since we are not a game. (Though having a "full-blown" ECS might provide a solid foundation for games to work with.)

However (and I'm just spitballing here), if the problem is that the object class is turning into a dumping ground for member datums, one can solve this (without a full-blown ECS) by extracting related datums into structs. The object class would then keep pointers to these structs, and these structs would only need to be allocated if the relevant APIs get called on the object. This could help to keep the memory footprint of the main object class low ...

I would conceptually consider this a special case of ECS; the structs being the optionally present static set of components. But you are right that it is not a "full-blown" implementation, where you keep external mappings from entity to component, and potentially have a dynamic set of components.

Something like this seems like a feasible way forward to me. I think we should probably refactor and start using std::optionals of structs - even if we don't end up going with pointers.

@BluebirdGreycoat
Copy link
Contributor

Quick note: std::optional stores its type as part of its footprint, so you wouldn't save memory that way. Pointers (raw or smart), or something like int handles, are the only way AFAIK.

@appgurueu
Copy link
Contributor Author

Quick note: std::optional stores its type as part of its footprint, so you wouldn't save memory that way.

I'm aware. This issue is not just about saving memory however, it's also - if not primarily - about refactoring. An optional helps with consistency. If an object isn't physical at all, you shouldn't be able to work with some gibberish collision box.

And when interacting with the Lua side of things, we could save memory and time, because users could more specifically get/set the "components" they are interested in rather than all the properties in one big table. (Arguably we could also look into :get_property(name) and :set_property(name, value) methods.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion Issues meant for discussion of one or more proposals Maintenance Tasks to keep the codebase and related parts in order, including architectural improvements
Projects
None yet
Development

No branches or pull requests

2 participants