In my game, all content, mechanics, and systems will be modular, and based on OSGi bundles. One of these bundles is for an Entity. Entities are uniquely identifiable things in the game world. Examples would include trees, rocks, and characters. The game though does not necessarily have to have any of those. If the game doesn't need trees, it shouldn't have trees. If it doesn't need rocks, it shouldn't have rocks. The Entity is the unique identity other things are associated with. One of the things an Entity can be associated with is a Position. A Position is an (x, y) coordinate in the world. Positions are in a separate bundle than Entities. Positions are not inherently tied to Entities, and Entities do not inherently have Positions, even though they will likely be used together, depending on the game.
At this point, there are two bundles; Entity, and Position. To get more functionality out of these two, a third bundle is needed; EntityPosition, which provides a glue class (EntityPosition) which associates a Position with an Entity. ``` +------------+ +--------------------+ +----------+ | | | | | | | Entity | | EntityPosition | | Position | | | | | | | +------------+ +--------------------+ +----------+ | | | | | | | id: String +--->+ entity: Entity | | x: Int | | | | position: Position +<----+ y: Int | +------------+ | | | | +--------------------+ +----------+ ``` In this simple example, two bundles became three, in order to associate them. If I only needed to turn two into three, that wouldn't be so bad. But if I wanted to associate a name with an Entity, that adds another bundle. If I wanted to associate a sprite with an Entity, that adds two other bundles, one for the sprite, one for the EntitySprite association. This results in an explosion of small, but simple, bundles; each one only binding two things from other bundles together. - Entity - Position - EntityPosition - Name - EntityName - Sprite - EntitySprite - Sound - EntitySound This has always seemed off to me somehow. Even though the code is small, easy, and sharing a common pattern, the sheer scale seems overwhelming. Each one has to be built, tested, deployed, and referenced; all for the sole purpose of binding two things together. In order to try to avoid this explosion of bundles, a possible solution came to me. Each service registered in the framework service registry can have properties associated with it. Could I use these properties to provide the relationship between the services? In this example, we would have one Entity component configuration, one Position component configuration, and one of the properties of the Position configuration would reference the Entity that the Position belongs to. ``` entity.uuid.1: entity.id: tree position.uuid.1: position.for: entity.uuid.1 position.x: 0 position.y: 0 ``` My thinking is that the service properties can provide the glue, or associations, between components/services, reducing the need for a separate glue class. Additionally, if a Position needed to be associated with something other than an Entity, I still don't need to create a separate bundle, I can just change the `position.for` property to point to whatever the new thing is, assuming the service can be filtered. This way, the Position and Entity classes remain ignorant of the binding, and can be focused on only its x and y values, and if I ever need to know the Position of something, I can simply filter the Position services on the `position.for` property.
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev