Component System and Minecraft

Already had that thought and agreed.

If you want to see an example of this kind of thing in C#, I wrote a simple one a few years ago:

Isn’t that exactly what you tried to avoid? Discussion: Components, TypeComponents for Entities by jacklin213 · Pull Request #132 · SpongePowered/SpongeAPI · GitHub

Has the idea of using a marker interface or type components been discarded?

The Vanilla model can be an enum because nobody should be able to extend or change it. If they want to create their own models, they can just implement the ModelComponent on their own :wink:

1 Like

well done :smiley:

Some questions/comments:

  1. ComponentHolder still exists in ComponentManager
  2. There is no way of adding Components to Entities (in releation with 1.?)
  3. Why ComponentSystem and ComponentManager have a generic type <H>? Should be <H extends Component> but, why should Systems, Managers process only one Component? And why H, for Holder?

Current class diagram:

I wrote a little Tutorial:

Thanks to @Zerot for his help.

TypeComponent should be removed (or renamed to ModelComponent, RenderComponent, ViewLikeComponent).
Developer can to easliy abuse it, e.g. to find all Zombies.

I think this could replace the limited Bukkit Metadata System.

Components for any Game Object!

ComponentManager<Entity>
ComponentManager<Block>
ComponentManager<World>

Just one important question: Should Block and World extend Entity?

We have now a name conflict,
Did you mean cs.Entity or mc.Entity.

But.

NO

Nothing should extend a cs.Entity (or an cs.Entity?)
A cs.Entity is only a UUID

@Zidane
Maybe rename cs.Entity to ComponentEntity

Two

Notes:
General Blocks are not planned to be part of the Component System for performance reason, with some exceptions:

Ok, so that means “Entity” really just is a name or uuid, and can be anything (a mob, a player, a world, a chest, a named item, a book item) depending on the attached components?

I understand that handling every block in a world as an entity doesn’t work (one object for every block), but it could be a hybrid system:

//returns a fresh Entity instance (just an uuid, you can store it in the minecraft save, nbt...)
Entity blockEntity = world.getBlockEntity(int x, int y, int z) 

//creates the material component when you ask for it
blockEntity.get("material",MaterialComponent.class).getID() 
// ---> "minecraft:chest"

//add a custom metadata component
blockEntity.add("owner",new CustomOwnerComponent(ownerPlayer))

1 Like

An Entity is a UUID.
What an entity is depends on the Components.
A name nornally depends on the component set …
Maybe take a look at my tutorial:

That is actually the plan. There won’t be metadata classes, instead you will be able to attach components to everything. Book items? Just attach the pages and stuff. Snow blocks? Just add the layers component. If I got that correctly that is.

I too thought that it originally was only meant to be for entities, but @Zidane plans to do it that way - and I quite like the idea :wink:

2 Likes

I read that. The name “entity” is just misleading. You should define what an entity can be depending on components. A mob, a book, a block, a world, a custom type.

There will be metadata components. You can just make your own class that implements Component, and stores custom data, or not?

Will custom/removed component changes persist across server restarts and whatnot? Or will it be dependent on plugins to keep track of entity UUID and re add/remove components when the server starts back up.

In regards to custom components, how will the component system know how to react to custom data? Say I have a RPG stat component with various stats and modifiers. How do I tell the ComponentSystem to take those values into account when manipulating health, damage, and such.

Earlier in the thread, I was talking about making a EntityBuilder, rather than use factories to create entities. Taking into account comments so far, I think something like the following Gist should give an idea as to what I meant:

I’ve only written this quickly, so it might have a couple of syntatic errors in it (I haven’t got my IDE to hand yet). However, it should show the basics of how someone might create an entity itself - and how you could validate such a created entity.

Remember, such a builder is a template of an entity that could be created - so could also be used to create multiple copies. We’d have to be careful to clone the components though, otherwise we might actually share one reference to a component to multiple entities.

Based on what has been said so far, you could create a creeper using this builder in the following way (this is not necessarily how components work/will work, just making a point):

HealthComponent comp = new HealthComponent();
comp.setHealth(10);
Entity e = EntityBuilder.forEntity("minecraft:creeper").with(comp).build();

The with method would replace the previous health component (if it exists), and the build method could do all of the required attaching to various classes. You could potentially use a fluent interface for entities themselves, but in that case, validation would need to be done during modification.

I must stress that this is not a completed builder system, I’ve only written it to the extent where it should give you an idea on my thoughts on entity creation. It’s main advantage would be to ensure that an entity would be created correctly, and won’t create an entity that is missing vital components (that’s what the validator is for - and the validator can be shared amongst multiple entities).

Regardless of whether what I’ve said is useful or not, I’d hope having such a entity system should hopefully make it much easier to work with entities - looking forward to see what comes out of the work!

An cs.entity can by everything … a block, a zombie, a particle, a player

Components have no logic, Componets are only data container (maybe if that your defintion of metadata) …
But metadata normally groups data … but you need no metadata (like a string for zombies), because the set of components (the aspects) are enough metadata …

You need to implement a CustomManager (init, load, addd Entites and Components) and CustomSystem (process all, here the actions happen)

I see this as a feature :wink:
.

One thing I don’t understand is which class stores the components that belong to an entity?

Why are the methods for adding, removing and getting components in the entity class?
I think they should be in the ComponentManager class, and the ones in the Entity class should just be convenience methods, right?

I’m asking because the getter method is missing in ComponentManager:

<C extends Component> C getComponent(H holder, ComponentKey<C> key);

That is a good question. For that you would need to extend or replace the damage systems that are in effect. Most likely in sponge there will be only 1 damage system that will handle all the normal incoming damage(e.g. hits, lava, fire ticks, etc). To apply your own calculations, you would override that damage system so it would take your rpg stats into account.

Why not write your own system?
But, yes …
How can we inject existing systems?

You cann access it over the system (manager store it):
https://github.com/SpongePowered/SpongeAPI/blob/component-system/src/main/java/org/spongepowered/api/component/ComponentSystem.java#L78
ComponentSystem

Collection<H> getAll();

I’m sorry, but the system does not store the components. It just works with them. The ComponentManager or the ComponentHolder (not quite sure yet) stores the instances.

That’s not right, “H” refers to “holder”, it’s just a collection of entities, not components.