I tried doing some digging around and going through the documentation without much success but I might be missing something.
What’s the best way to implement Many to Many relationships through Entities?
I’m aware that Entities will be used to define the relationships, but I’m asking about a good tool to implement them.
I’ll try giving a generic example: neural nets (following something like the NEAT algorithm)
Let’s say I have Node Entities holding a previousValue and a presentValue. I also have Connection Entities each holding an InputNode Reference (to the Entity), and an OuputNode Reference. In my case, we’ll say that there can be any number of connections exiting and entering a node (no pre-definite number of connections per node). Nonetheless, we will have a high number of Nodes and Connections.
Might be good to add the specification that NO connections would ever have the same OuputNode and the same InputNode.
Each frames, I need to read the previousValue of the InputNode, and add it to the present value of the OuputNode (which has been reset to zero at the start of the frame by another system).
I figure it might be a good idea to separate the Read System and the Write System, maybe by adding an InputValue to the connection which first gets copied from the inputNode’s value using ComponentDataFromEntity in the Read System.
However the Write System seems a lot more complex given the ‘‘undefined number of entering connections’’ premise. A few Ideas I looked into and their potential problems I thought of:
- Using ComponentDataFromEntity in write mode:
This would allow to keep the read and write system together (or not), but we would have to ensure thread safety ourself, which can be tricky. Basically we would have to make sure that all Connections that have the same OutputNode are executed in the same Job, which I’m not sure how to do. Furthermore this could be difficult because we don’t know how many connections would reffer to that node. Could be one, could be ten, maybe could be a hundred?
- Using the EntityCommandBuffer :
If my undestanding is correct, this would allow to keep the read and write system together again, but considering we have a high number of Nodes and Connections and that this would need to run every frame, the ECB might be a specifically bad tool for the job.
- Using A SharedComponentData for the OutputNode Reference:
To my undestanding, this would group Connections with the same OuputNode together in the same chunks, maybe allowing us to use IJobChunk to ensure thread safety and that no connections writing to the same node would run in parallel, although I’m not sure if there could potentially be two chunks writing to the same Node (let’s say the number of entering connections is greater than the chunk’s maximum length. I also don’t know what would be the impact if the opposite happen and that most Nodes have very few entering connections, most chunks would contains one or two entities and we would have a lot of chunks, potentially nullifying the effects of ECS’s memory optimisation. My guess is that the latter is most likely and a low number of connections would potentially have the same Outputnode (<=10 maybe).
I know I’m probably missing some tools or knowledge, I’m just wondering how you would implement such a system and what kind of pitfalls I’m maybe overlooking/forgetting? Also, are there some additional limitations we could impose on the premise (max number of connections with the same OutputNode, or something like that) to make a specific tool/solution better?
Thanks a lot in advance, I’m pretty new to the world of ECS and slowly learning.