I want to implement ECS in my game. The more I read the more insecure I get.
The current available Components for a Entity processed by the RenderSystem are:
- RenderComponent (mesh, texture, normalmap, etc.)
- TransformationComponent (position, scale, rotation)
- LightComponent (light color, brightness)
- CameraComponent (view Matrix)
Let's assume that my EntityManager has a methode: getEntitiesByComponents(Class[] components): List and is a singleton.
Here is my pseudocode with the issues I have:
cclass RenderSystem {
EntityManager em = EntityManager.getInstance();
Renderer renderer = new Renderer();
update(float dt) {
//This one contained only RenderSystem related components
RenderSystemComponents rsc = em.getRenderSystemComponents();
// Try to get the Camera
[CameraComponent,TransformationComponent][] cameraArray = rsc.getComponentByType(TRANSFORMATION,CAMERA);
// Check if Camera is avaible
if(cameraArray.length != 1) {
// Do some error Stuff here
// Not sure if I should allow more then one Camera
// e.g. MiniMap
}
// lights
[TransformationComponent,LightComponent][] lightArray = em.getComponentByType(TRANSFORMATION, LIGHT);
// 'default' entities
[TransformationComponent,LightComponent][] entityArray = em.getComponentByType(TRANSFORMATION, RENDER);
renderer.render(cameraArray,lightArray,entityArray);
}
public enum ComponentType {
RENDER, TRANSFORMATION, LIGHT, CAMERA
}
}
This implementation could work if my method getEntitesByComponents is fast enough. But the floor is literally the floor. The Terrain has seen from the component's point of view no difference but the RenderEngine should know that it is processing an Entity ( box, tree, player, mob, ... ) or a terrain (different shaders). This isn't a only RenderSystem problem even the Collision detection has to know if it's a terrain or an entity.
This is my first problem understanding how I detect differences. The second problem is the method getEntitesByComponents. Current this peace of code doesn't exists in a way I would use it. The basic concept I current use is the one here. The Structure is a
Map<String, Map<Id, Component>>
. The String is the Component class, which maps to a Map with the EntityId as key and the actual component as value.
if you want to get the components from an entity you ask map.get(Component.class).get(Entity#getId())
but you can't direct ask this structure to get all entities who refer to certain components without looping throw the map. So I need a proper management for the objects.
My first idea is to modify the entity class with a new attribute map and give each Component a unique static Id. So you can easily loop throw the entities and check with something like map.keySet().conatains(x) and y without checking one entity multiple times. But this seems not to be a common implantation. I often see a 'ComponentManager' but unfortunately the article I read doesn't describe the inner datastructure.