You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### React glue for [miniplex], the gentle game entity manager.
8
8
9
+
> **Note** This package contains the React glue for Miniplex. This documentation assumes that you are familiar with how Miniplex works. If you haven't done so already, please read the [Miniplex documentation](https://github.com/hmans/miniplex/tree/main/packages/miniplex#readme) first.
10
+
9
11
## Installation
10
12
11
13
Add `miniplex-react` and its peer dependency `miniplex` to your application using your favorite package manager, eg.
@@ -85,7 +87,7 @@ const Player = () => (
85
87
86
88
This will, once mounted, create a single entity in your ECS world, and add the `position` and `health` components to it. Once unmounted, it will also automatically destroy the entity.
87
89
88
-
### Storing objects in components
90
+
### Capturing object refs into components
89
91
90
92
If your components are designed to store rich objects, and these can be expressed as React components providing Refs, you can pass a single React child to `<Component>`, and its Ref value will automatically be picked up. For example, let's imagine a react-three-fiber based game that allows entities to have a scene object:
91
93
@@ -253,6 +255,8 @@ const Health = () => {
253
255
254
256
### Managed Entity Collections
255
257
258
+
> **Note** This feature is still experimental and may change (or even be removed) in the future.
259
+
256
260
In games and other ECS-oriented applications, you will often have several distinct _entity types_ -- like spaceships, asteroids, bullets, explosions, etc. -- even if these entities are composed of several shared ECS components. All entities within a specific entity type are typically composed from the same set of components (eg. spaceships always have a position and a velocity), and rendered in a similar manner (eg. bullets will always be rendered using a small box mesh, but with varying materials.)
257
261
258
262
The `<ManagedEntities>` React component is an abstraction over this. It will take over management and rendering of such an entity type, assuming that this type can be identified by the presence of a specific tag (a tag being a miniplex component that is always just `true` and doesn't hold any additional data; miniplex provides a `Tag` type and constant for this.)
@@ -300,3 +304,28 @@ A couple of important notes:
300
304
Find me on [Twitter](https://twitter.com/hmans) or the [Poimandres Discord](https://discord.gg/aAYjm2p7c7).
> Tested @hmans' Miniplex library over the weekend and after having previously implemented an ECS for my wip browser game, I have to say **Miniplex feels like the "right" way to do ECS in #r3f**. - [Brian Breiholz](https://twitter.com/BrianBreiholz/status/1577182839509962752)
React bindings. Create, extend and render entities declaratively.
11
16
12
17
## Introduction
13
18
14
19
**Miniplex is an entity management system for games and similarly demanding applications.** Instead of creating separate buckets for different types of entities (eg. asteroids, enemies, pickups, the player, etc.), you throw all of them into a single store, describe their properties through components, and then write code that performs updates on entities of specific types.
15
20
16
-
If you're familiar with Entity Component System architecture, this will sound familiar to you -- and rightfully so, for Miniplex is, first and foremost, a very straight-forward ECS implementation.
21
+
If you're familiar with **Entity Component System** architecture, this will sound familiar to you -- and rightfully so, for Miniplex is, first and foremost, a very straight-forward ECS implementation!
17
22
18
23
If you're hearing about this approach for the first time, maybe it will sound a little counter-intuitive -- but once you dive into it, you will understand how it can help you decouple concerns and keep your codebase well-structured and maintainable. [This post](https://community.amethyst.rs/t/archetypal-vs-grouped-ecs-architectures-my-take/1344) has a nice summary:
19
24
@@ -35,7 +40,7 @@ If you've used other Entity Component System libraries before, here's how Minipl
35
40
36
41
### Entities are just normal JavaScript objects
37
42
38
-
Entities are just **plain JavaScript objects**, and components are just **properties on those objects**. Component data can be **anything** you need, from primitive values to entire class instances, or even [reactive stores](https://github.com/hmans/statery). Miniplex aims to put developer experience first, and the most important way it does this is by making its usage feel as natural as possible in a JavaScript setting.
43
+
Entities are just **plain JavaScript objects**, and components are just **properties on those objects**. Component data can be **anything** you need, from primitive values to entire class instances, or even [entire reactive stores](https://github.com/hmans/statery). Miniplex puts developer experience first, and the most important way it does this is by making its usage feel as natural as possible in a JavaScript setting.
39
44
40
45
Miniplex does not expect you to programmatically declare component types before using them, but if you're using TypeScript, you can provide a type describing your entities and Miniplex will provide full edit- and compile-time type hints and safety.
41
46
@@ -47,7 +52,7 @@ Systems are extremely straight-forward: just write simple functions that operate
47
52
48
53
### Archetypal Queries
49
54
50
-
Entity queries are performed through **archetypes**, with archetypes representing a subset of your world's entities that have a specific set of components. More complex querying capabilities may be added at a later date.
55
+
Entity queries are performed through **archetypes**, with individual archetypes representing a subset of your world's entities that have a specific set of components. More complex querying capabilities may be added at a later date.
51
56
52
57
### Focus on Object Identities over numerical IDs
53
58
@@ -57,17 +62,19 @@ Most interactions with Miniplex are using **object identity** to identify entiti
57
62
58
63
Miniplex can be used in any JavaScript or TypeScript project, regardless of which extra frameworks you might be using. Integrations with frameworks like React are provided as separate packages, so here we will only talk about framework-less usage.
59
64
65
+
Specifically, if you intend to use Miniplex in a React project, please don't miss the [miniplex-react](https://github.com/hmans/miniplex/tree/main/packages/miniplex-react) documentation!
66
+
60
67
### Creating a World
61
68
62
-
Miniplex manages entities in worlds, which act as a containers for entities as well as an API for interacting with them. You can have one big world in your project, or several smaller worlds handling separate concerns.
69
+
Miniplex manages entities in worlds, which act as containers for entities as well as an API for interacting with them. You can have one big world in your project, or several smaller worlds handling separate concerns.
63
70
64
71
```ts
65
72
import { World } from"miniplex"
66
73
67
74
const world =newWorld()
68
75
```
69
76
70
-
### Typing your Entities (optional, but recommended)
77
+
### Typing your Entities (optional, but recommended!)
71
78
72
79
If you're using TypeScript, you can define a type that describes your entities and provide it to the `World` constructor to get full type support in all interactions with it:
Now we can implement our system, which is really just a function -- or any other piece of code -- that uses the archetype to fetch the associated entities and then iterates over them:
123
130
124
131
```ts
125
-
function movementSystem(world) {
126
-
for (const { position, velocity } ofmovingEntities.entities) {
132
+
function movementSystem() {
133
+
for (const { position, velocity } ofmovingEntities) {
127
134
position.x+=velocity.x
128
135
position.y+=velocity.y
129
136
position.z+=velocity.z
@@ -271,19 +278,19 @@ function movementSystem(world) {
271
278
}
272
279
```
273
280
274
-
This will incur a modest, but noticeable performance penalty, since you would be calling and returning from a function for every entity in the archetype. It is typically recommended to use either a `for/of` loop:
281
+
This will incur a modest, but noticeable performance penalty, since you would be calling and returning from a function for every entity in the archetype. If performance is a concern, it is recommended to use either a `for/of` loop:
275
282
276
283
```ts
277
284
function movementSystem(world) {
278
-
for (const { position, velocity } ofmovingEntities.entities) {
285
+
for (const { position, velocity } ofmovingEntities) {
279
286
position.x+=velocity.x
280
287
position.y+=velocity.y
281
288
position.z+=velocity.z
282
289
}
283
290
}
284
291
```
285
292
286
-
Or a classic `for` loop:
293
+
Or a classic `for` loop with numerical index access:
287
294
288
295
```ts
289
296
function movementSystem(world) {
@@ -308,7 +315,7 @@ For example, creating your archetypes within a system function like this will wo
0 commit comments