React Entity Component System
An ECS hook for React to make games or other interactive components.
yarn add react-entity-component-system
Play Breakout Demo
Why
It's fun to build games with React, and people have become successful at it. The ECS pattern is well known and battle tested for game development. This library is a loose implementation for React. You can check out the Breakout storybook story to see a fairly complex example.
Usage
import React from 'react'
import useEntityComponentSystem from 'react-entity-component-system'
ECS has three basic concepts:
-
Entities
represent every "object" in a scene -
Components
are data structures, composed to create entities. -
Systems
are functions that operate on entities during every update
In this implementation, an entity is defined as a plain object with at least a Renderer
property (a React component). Other properties are components
that will be passed as props to the Renderer
:
const counterEntity = {
Renderer: props => <h4>{props.count}</h4>,
count: 0,
}
A system
is just a function and will receive the list of entities
in the scene. Systems are allowed to mutate the entities' components
(thanks to immer!):
function frameCounterSystem({ entities }) {
entities.forEach(entity => entity.count++)
}
The useEntityComponentSystem
hook takes a list of entities and systems and returns the renderable result and an updater function:
export default function BasicECS() {
const [entities, updater] = useEntityComponentSystem(
[counterEntity],
[frameCounterSystem],
)
return (
<div>
<button onClick={() => updater()}>Next Frame</button>
{entities}
</div>
)
}
When the updater
is called, the systems
are called. This triggers a re-render and any changes to the entities
are reflected immediately. Combined with a loop like requestAnimationFrame
or the provided useGameLoop
hook, this can happen as much as 60 frames per second.
Additionally, you can pass an object to the updater
so your systems can have access to other things:
const gameLoop = useGameLoop(elapsedTime => {
updater({
gameLoop,
elapsedTime,
})
})
See this example and more in the stories folder
Storybook
While react-entity-component-system
is in development, you can check out the storybook to get a better sense of how things work.
git clone https://github.com/mattblackdev/react-entity-component-system.git
cd react-entity-component-system
yarn
yarn start
API
useEntityComponentSystem
useGameLoop
useGameEvents
useKeysDown
Contributing
I welcome any ideas and would really love some help with:
- Adding Typescript types
- Performance benchmarking and optimizations
- More game engine API like:
- Keeping track of "entity filters" for systems
- MatterJS or other physics lib integration