Add entity component system in cocos2d-x

yes, that is the option that I’m evaluating at the moment.

like Apple’s approach? What would you do with the Renderer and Physics systems?

The renderer doesn’t need to change. Add a geometry component that uses BatchCommand or whatever the Sprite3D is using.

Add a physics component that works with the other components.

All of the other nodes will work as is. You can even mix and match them if you want. I wouldn’t add components to existing nodes, but only Node.

This is all dependent on an in Node messaging system to coordinate things. Components need to know when things are added, removed, updated, yadda yadda. I am still thinking of the signals and slots idea, or you can think of it like a old fashioned phone switch board, where you connect people using cables with jacks on the ends.

I would probably have 2 arrays, one of signals which can have a list of slots, and an array of slots, which have a std::function callback. You can wire these 2 arrays together however you want. A component can allocate a signal or slot quickly since they are preallocated, so you grab the next index, or maintain a free list. A signal could have a max number of slots, and you can chain them together if you run out. This would be super fast, have good locality, and never allocate/release memory.

I read all the articles, including the additional ones about plugins and multi-threading. Very interesting read.

If we add it in Node will be useful for the rest of the node hierarchy… like Sprite and others. Let’s discuss it in person.


Regarding Apple’s approach, I re-read it today, and noticed that they didn’t implement an complete ECS… there are no “systems”… the behavior is the Component and not in the System. If I missed something, please let me know.

For the limitation of entity-x you mentioned, You can simply ignore the “System” part of the library.
There is no need to implement the whole thing.

I agree with it.
I think now we should separate engine and game logical.
In engine side, we should use CBA. Game codes can use ECS as they want, they can use sprite as a rendering component as Ray Wanderlich did.

About cocos2d-x itself, we can first put all related codes into a component to remove all #ifdef codes. But i have not idea about rendering codes.

It sounds interesting. What component should be added? And how does these component work? Will you please describe it in more detail? Some pseudocode will be better.
Thanks.

Yep, i just post a link that collects many useful resources. I don’t mean we should research all posted engine codes. Indeed, there are many useful links in the same site.

And thanks for the link. I will read more of it.

@Dredok
It is an interesting idea in Building a Data-Oriented Entity System. All components are hidden in corresponding manager.

The benefit is that, all components can be stored in continuous memory. It is good for performance. But it requires components only contain data. In the design, there is even not a Component type. Different managers just handle different part data of entity.

yes, thats the core of a pure ECS and the proposed implementation is solid.

I like this, non-disruptime steps in v3.x and let’s see if a pure ECS is a good fit in v4.

Current design of Node and Sprite makes really hard to mantain backwards compatibility due to huge amount of “protected” stuff and other “coupling-incentivation” material in the engine. I would agree with @iQD and break compatibility at some point

@zhangxm

As the first thing to do, what about creating a LuaComponent, or JSComponent, or perhaps a ScriptComponent (instead of the Physics2d component) and that component will send all the events to Lua/JS.

Instead of hardcoding the JS/Lua callbacks in Node, just move it a component.
We should have the update, onEnter, onExit a few more.
And the idea is to see if we can create a game in Lua / JS using it as component.

Benefit of Lua/JS as component:

The interface is cleaner. Right now, when you subclass an Sprite in JS, you are not really subclassing it… you can only override certain methods, not all of them.
But creating the component, it is cleaner which messages you can receive.

Also, it will be cleaner from a GUI point of view… you just right click on an Node and say “attach script / callback”… in that sense is cleaner.

Cons
if could break compatibility… if so, we can’t do it for v3.x but it is a good starting point.

BTW, the Cocos Studio guys should be involved in this discussion since having that feature in the GUI is a must. Could you ask them to join this thread? thanks.

yeah. But you may consider other scripting as clear start too, say Ruby, Python…

@winipcfg

we are not considering adding new languages at the moment, but yeah, if we solve it correctly for Lua/JS, it will be possible to add it for more languages easily.

But we already uses event to communicate between c++ and lua, take this one as an example:

ScriptManager works more or less like a component.

@Owen takes charge of GUI.

I don’t understand it. Is component something related with subclassing or component can resolve it?

Hi all,
We have done some research on:

  • pure ECS/CBA framework, such as GamePlayKit, entity-x.
  • game engine implemented by CBA: Unity
  • read many articles that explain the concept of ECS/CBA

I think we know the concept of ECS and CBA. Because our target is to make engine extendable, so i think add a framework like GamePlayKit on top of engine is not a right way. Developers can implement it if they want. I think Unity is a better target though it is not a pure ECS.

I think research on real engines other than pure ECS/CBA framework is more valuable. So i will do some research on Unreal in following days. And i will do some research on other known engines that implement ECS/CBA if there is any.

I felt that, we can make physics2d and rendering as a component, but i don’t think we can keep 100% compatibility.

You have to forget what we have today.
What we need is to associate scripts with visual objects. How can we do that?

I want to drag & drop a sprite into Cocos Studio, right click on it, and change its behavior ?
how can you do that with our current scripting model?

If the scripts are just components of nodes, you just drag & drop the node, and then add the script as a component.
The major problem is that Cocos Studio is doing just a Scene editor and the Cocos Code IDE is just building a tool to create games using Lua/JS… but nobody is thinking how to have them working together.

Well, I think that having scripts as components will definitely help… I’m assuming that the Cocos Studio team will support “add script” to nodes feature.

2 Likes

But our target is to keep compatible.

The things you said that have a script component is much different from current implementation:

  • one is to add a script component to do some operation on c++ object
  • one is totally using script to develop a game

If we have the two together, then developers may be confused.

yes… or no.

But you haven’t answered my question:

  • What we need is to associate scripts with visual objects. How can we do that?

(please answer that question. don’t skip it… how do you plan to solve that issue?)

In any case, we need to this component to test the component framework. We need a real-world example to test it… and this will be. Whether we include it in the final version or not, is just another question.

So, we need this script component to test the component framework… basically we don’t need to remove the current code… just add a this component.

What did you mean associate scripts with visual objects? What can the scripts do?

Current, there is a c++ object associated with a script object. But this relationship is not obvious, the binding codes maintain it.

  • create a Sprite in Cocos Studio (just drag & drop it to the canvas)
  • While in Cocos Studio, right click on the Sprite and add a behavior… like "I want to do something on update()"

We need that use case… that’s how you prototype really fast.
How do you plan to solve that?

It depends on what you want to do in a call back function. If just make sure a function is invoked, then it is easy. If want to do more complicated things, such as create another Sprite, then it requires more binding codes. And i think it is binding code not component system to resolve it.

Yep, component can be used to invoke a script function.