Defining your architecture is a really important decision you need to make before starting to code.
In Planet51Online and Thunderwheels, we used exactly the same architecture. Each game entity contains all its information within the entity itself. That means that if you need to obtain the position of the player you will need to ask for the player entity in some kind of playerManager.
I wondered whether there were other different architectures. While researching on the Internet I discovered a thesis written by Jeff Plummer at the Arizona State University. Jeff focuses on the flexibility of and expandability from the specific architecture that he created. That thesis got my attention and I read it completely, so I started to think about how I can make a new architecture for my personal projects.
Some year after reading that thesis, the knowledge that I got from him came back again. That´s how I started to write a new architecture based on the “Blackboard pattern” which I will explain.
Basically the “Blackboard pattern” is a collection of little subsystems which works together on a common data structure. One of the main purposes of this architecture is to allow the different subsystems to work independently from each other, and only to communicate data using a shared structure.
This approach is really valid for the game development. If you analyze the code you are working on, you will discover that the 90% of your entities information is using the 90% of the game loop time. Probably, that information will be:
… whatever else you consider
As I said, this information is shared by different subsystems in the game. For example, the position is used in my case by the perceptionSystem, PhysicsManager, AIManager, Task related to Behavior Trees, layers used in the Editor, etc…
So, from any point of the code you could ask for the pointer to the structure, which contains basic information that belongs to one entity without adding dependencies to the entity itself. That is cool, because, for example, in your Task, that belongs to logic side in your BehaviorTree library, you will only have to know the basic information about one threat and not the threat itself. Therefore you can manage a little piece of information and keep your BehaviorTree library portable to other projects.
Hereby I write a little resume about how this architecture worked in my last project.
Basically you have one WorldObjectDataCenter managed by a singleton pattern, where you can obtain all the information from all your entities. With that pointer you can modify information which will be read in other point of the code and used to some other processes ( AI, Physics, etc… ).
Finally I provide you with the link to the Jeff Plummer thesis. I highly recommend you to read it :)