React ECS
A declarative Entity Component System for React.
An ECS, or Entity Component System is a design pattern popular in simulations, visualizations and game-development. It eschews rich objects and complex inheritence hierarchies.
An ECS, or Entity Component System is a design pattern popular in simulations, visualizations and game-development. It eschews rich objects and complex inheritence hierarchies.
Instead:
- Entities: A simple bag of facets.
- Facets: Simple data-only objects.
- Queries: Track entities which have specific facets.
- Systems: Process the facets of entities matched by queries.
React ECS helps you build your simulations and games using this pattern, in standard React JS fashion (hooks, components, etc)
What does it look like?
Let's make a simple simulation that updates a cube based on a Spinning facet, using React ECS' ThreeJS integration @react-ecs/three.
|
First define a Facet
This facet just tracks how much its entity should spin.
class Spin extends Facet<Spin> {
amount? = new Vector3(1, 1, 1);
}
Then define a System
Systems use queries to track the entities they work upon.
This system uses a query to find entities with both the ThreeView
and Spin
facets. ThreeView
is facet provided by @react-ecs/three to visually display entities in a ThreeJS scene.
This system updates the entity's 3D rotation based on the Spin
facet:
const SpinSystem = () => {
const query = useQuery((e) => e.hasAll(ThreeView, Spin));
return useSystem((dt) => {
query.loop([ThreeView, Spin], (e, [view, spin]) => {
const rot = view.object3d.rotation;
rot.x += spin.amount.x * dt;
rot.y += spin.amount.y * dt;
rot.z += spin.amount.z * dt;
});
});
};
Now put it all together
Now we can create a component to tie it all together. For more information see our documentation and examples.
export const SpinningCubeStory: FC = () => {
const CoolSim = () => {
const ECS = useECS()
useAnimationFrame(ECS.update)
return (
<Canvas>
<ECS.Provider>
<SpinSystem />
<Entity>
<Spin />
<ThreeView>
<Box />
</ThreeView>
</Entity>
</ECS.Provider>
</Canvas>
)
}