*| [JavaECS](../../README.md) | [docs](../overview.md) | [system](./dir.md) | System[]().md* # System | **In this section** | |-| | [About](#about) | | [Implementation](#implementation)| | [Examples](#examples)| | [Notes](#notes) | ## About >A system is a functionality that is executed regularly by the game engine. The [SystemManager](./SystemManager.md) ensures that the system has an up-to-date list of entities that the system would act upon. This is performed by comparing the system's declared required components with the components of a potential entity. An entity containing all required components is added to the system's list. A system does not explicitly require any entities to be registered; but it can make more sense to directly perform such operations in the game loop. `TODO` There is a single layer of inheritence in this design, which is the overriden `init()` and `update()` functions. This allows each system's `update()` to be called in a uniform way. ## Implementation All systems should extend [ECSSystem](./ECSSystem.md), which implements the entities list as a simple set. This can be overriden if there are certain requirements for the order of the entities (e.g. a Render System might require the further-most elements to be drawn first, to ensure the correct z-ordering) ``` java class ECSSystem{ Set entities = new HashSet<>(); } ``` ``` java class NewSystem extends ECSSystem{ void init() {} void update(/* any required parameters*/){ /* implementation */ } } ``` ## Examples ### System that operates on entities with multiple components ``` java public class PhysicsSystem extends ECSSystem{ ECS gameEngine; public PhysicsSystem(ECS gameEngine){ this.gameEngine = gameEngine; } void init() {} void update(double dt){ for (Integer entity : entities) { // Get entity components Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class.getName()); RidgidBody ridgidBody = (RidgidBody)gameEngine.getComponentData(entity, RidgidBody.class.getName()); Gravity gravity = (Gravity)gameEngine.getComponentData(entity, Gravity.class.getName()); // Add the result of the accelerative forces to the ridgidbody's velocity ridgidBody.xdot += ridgidBody.xAcc * dt; ridgidBody.ydot += ridgidBody.yAcc * dt; // Gravity is a force of acceleration as above, but is generally considered to be constant. if (gravity.terminalX < 0 || Math.abs(ridgidBody.xdot) < gravity.terminalX){ ridgidBody.xdot += gravity.x * dt; } if (gravity.terminalY < 0 || Math.abs(ridgidBody.ydot) < gravity.terminalY){ ridgidBody.ydot += gravity.y * dt; } // Finally, move the vec2d by the new velocity pos.x += ridgidBody.xdot * dt; pos.y += ridgidBody.ydot * dt; } } } ``` ### System that operates on a single component ``` java public class LogVec2DSystem extends ECSSystem{ ECS gameEngine; public LogVec2DSystem(ECS gameEngine){ this.gameEngine = gameEngine; } void init() {} void update(double dt){ for (Integer entity : entities) { Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class.getName()); System.out.println(String.format("X: %.6g, Y: %.6g", pos.x, pos.y)); } } } ``` ### System that operates on no components Note that it does not require a reference the the `gameEngine`; no component data is accessed. ``` java public class FrameRateSystem extends ECSSystem{ void init() {} void update(double dt, double idleTime){ System.out.print(String.format("dt: %.3g (%.3g idle) ", dt, idleTime)); } } ``` ## Notes