Apologies if this question has been answered before, but after relentless searching I couldn't find anything.
As many, I've recently jumped on the ECS-bandwagon, and I am currently killing some time by making a modest ECS-game. The game is a somewhat simple 2D-platform game. It is programmed in plain JS.
The layout of the game is essentially as following:
The core of the game is the Engine, the Engine runs the game-loop and holds an EventManager, responsible for raising events, and an EntityManager, responsible for containing all components of all entities.
All logic is done by systems. The systems registers event-handlers (i.e. member-functions) with the EventHandler for specific EventTypes, which gets called when an event of that type is raised.
For example:
this.eventManager.registerHandler(EventType.EVENT_RENDER, this.render, null, this);
I recently switched from calling all systems relevant functions explicitly in the Engine to this pattern.
But over to my problem and question.
For rendering I have a RenderSystem. This system contains references to several type of drawable/animatable-components which it, you guessed it, renders.
Until recently, this system also contained a reference to another system, MapSystem, which spatially indexes all entities. The reason for this reference was to be able to call a function along the lines of
mapSystem.search(frame_bound);
effectively pruning away all entities not needing to be rendered.
So I have a couple of questions regarding this:
Is it very bad practice for systems to communicate directly? Something about it just doesn't smell right to me.
I see how it might severely complicate your code if you have say 100 systems, and each system holds references to many of the other systems. Hello O(n^2).
If I am not to hold inter-system references, how do I perform communication like described above?
My initial thoughts was to create an entity whose primary purpose were to hold the necessary information (i.e. all entities currently in the frame). Then let MapSystem write to and RenderSystem read from this entity.
But this also seems to be rather unclean to me. Especially as MapSystems search function might be useful to call in many different contexts. Creating an entity per calling-context doesn't really seem like a good way to go about it either.
TL;DR: Is it bad for systems in a ECS-game to communicate directly and hold references to each other?