Hi, new to ECS (and the forums).
I’m trying to build something that isn’t typical of the ECS examples (large groups of identical objects) given in talks, both to exercise the claim that anything can be built in ECS and become familiar with the concepts. I’m essentially building a board game, with many unique pieces.
I’m trying to understand the best way to handle shared data structures. In this case, the Board.
Many of the systems in the game need to ask questions like:
“is space (a, b) occupied?”
“which piece is in position (a, b)?”
“is (a, b) → (c, d) a valid move?”
“is (c, d) on the board?”
One more concrete example, is that the movement system needs to know what terrain a piece is currently standing on, and what terrain it will be moving into, to calculate whether or not it’s a valid move. The point is, sometimes a system that handles the set of Pieces needs to know about arbitrary Tiles, and vice versa.
Coming from an OOP mindset, one simple solution would be to have a Board object that exposes Maps of Position → Tile and Position → Piece, and then systems would check that dictionary for whatever purpose.
But it doesn’t feel like the ECS way of handling the problem - since these objects (Tiles/Pieces) have a wealth of different components that are required by different systems, they would need to be Entity references, and systems would have to call some Get Component method on that entity reference that can be expected to fail in some cases, unless I want to have a dictionary for each tile/piece component.
One “ECS” option I have explored, is that systems that require this information could instead declare and inject a second group - for example the Movement System could add a group of (Tile, Position, Terrain) as well as it’s original (Piece, Position, Movement) group, but this just yields arrays of tile data, which still needs to be converted into Maps in order to avoid iterating over the entire array to find the tile with the correct position, and this has to be done frequently, because tile data changes. Which seems wasteful compared to the solution in OOP.
Does anyone have any intuition as to how this type of shared data should exist in the ECS world? Perhaps the “wasteful” solution is in fact not as wasteful as it seems?