This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@miniplex/bucket@2.0.0
Major Changes
8a7a315: Miniplex 2.0 now implements its core "reactive bucket" functionality in a small micropackage called @miniplex/bucket. It can be pretty useful even outside of Miniplex, and will eventually be extracted into its own project.
miniplex@2.0.0
Major Changes
8a7a315: Miniplex 2.0 is a complete rewrite of the library, with a heavy focus on further improving the developer experience, and squashing some significant bugs.
While it does bring some breaking changes, it will still allow you to do everything that you've been doing with 1.0; when upgrading a 1.0 project to 2.0, most changes you will need to do are related to things having been renamed.
The headline changes in 2.0:
A lot more relaxed and lightweight! Where Miniplex 1.0 would immediately crash your entire application when, for example, adding a component to an entity that already has the component, Miniplex 2.0 will simply no-op and continue.
Much more flexible! Miniplex 2.0 simplifies and extends the query API (formerly often referred to as "archetypes"); you can now create queries through world.with("componentName"), chain these together, use the new without, or even create advanced predicate-based queries using where.
Improved type support! If you're using TypeScript, you will be happy to hear that type support has been significantly improved, with much better type narrowing for queries.
The React API has been significantly simplified, and some pretty big bugs have been squashed. (Turns out Miniplex 1.0's React API really didn't like React's ``` much. Whoops!)
Some more details on the changes:
world.createEntity has been renamed and simplified to just world.add (which now returns the correct type for the entity, too), and world.destroyEntity to world.remove.
The Tag type and constant have been removed. For tag-like components, simply use true (which Tag was just an alias for.)
Entities added to a world no longer receive a __miniplex component. This component has always been an internal implementation detail, but you might have used it in the past to get a unique identifier for an entity. This can now be done through world.id(entity), with ID lookups being available through world.entity(id).
Queries can now be iterated over directly. Example:
This is, in fact, now the recommended way to iterate over entities, since it is extremely efficient, and will make sure that the list of entities is being iterated over in reverse, which makes it safe to modify it during iteration.
You can also use this to neatly fetch the first entity from an archetype that you only expect to have a single entity in it:
const [player] = world.with("player")
The queuing functionality that was built into the World class has been removed. If you've relied on this in the past, miniplex now exports a queue object that you can use instead. Example:
import { queue } from "miniplex"
queue(() => {
// Do something
})
/* Later */
queue.flush()
Please note that this is being provided to make upgrading to 2.0 a little easier, and will likely be removed in a future version.
with and without are the new API for building queries. Examples:
The new world.where now allows you to build predicate-based queries! You can use this as an escape hatch for creating any kind of query based on any conditions you specify. Example:
Please note that his requires entities with the health component to be reindexed using the world.reindex function in order to keep the archetype up to date. Please refer to the documentation for more details.
You can use where to create a predicate-based iterator. This allows you to quickly filter a set of entities without creating new archetypes or other objects. Example:
for (const entity of world.where((entity) => entity.health < 10)) {
// Do something
}
All of these can be chained!
world
.with("position", "velocity")
.without("dead")
.where((entity) => entity.health < 10)
Entities fetched from a query will have much improved types, but you can also specify a type to narrow to via these functions' generics:
const player = world.with<Player>("player")
Miniplex provides the new Strict and With types which you can use to compose types from your entity main type:
type Entity = {
position: { x: number; y: number }
velocity: { x: number; y: number }
}
type Player = Strict<With<Entity, "position" | "velocity">>
const player = world.archetype<Player>("player")
The event library Miniplex uses has been changed to Eventery, which brings a change in API. Where before you would have done onEntityAdded.add(listener), you will now to onEntityAdded.subscribe(listener).
Patch Changes
Updated dependencies [8a7a315]
@miniplex/bucket@2.0.0
miniplex-react@2.0.0
Major Changes
8a7a315: - The library has been significantly simplified and an almost mind-boggling number of bugs have beens quashed.
The main import and initialization have changed:
import { World } from "miniplex"
import createReactAPI from "miniplex-react" // !
/* It now expects a world as its argument, so you need to create one first: */
const world = new World()
const ECS = createReactAPI(world)
All lists of entities are now rendered through the upgraded <Entities> component, which takes an array of entities or a query (or even a world) as its in prop:
If you're passing in a query or a world, the component will automatically re-render when the entities appear or disappear. If you don't want this, you can also just pass in a plain array containing entities:
<ManagedEntities> has been removed. You were probably not using it. If you were, you can replicate the same behavior using a combination of the <Entities> component and a useEffect hook.
The useEntity hook has been renamed to useCurrentEntity.
The world-scoped useArchetype hook has been removed, and superseded by the new global useEntities hook:
/* Before */
const entities = useArchetype("position", "velocity")
/* Now */
const entities = useEntities(world.with("position", "velocity"))
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@miniplex/bucket@2.0.0
Major Changes
@miniplex/bucket
. It can be pretty useful even outside of Miniplex, and will eventually be extracted into its own project.miniplex@2.0.0
Major Changes
8a7a315: Miniplex 2.0 is a complete rewrite of the library, with a heavy focus on further improving the developer experience, and squashing some significant bugs.
While it does bring some breaking changes, it will still allow you to do everything that you've been doing with 1.0; when upgrading a 1.0 project to 2.0, most changes you will need to do are related to things having been renamed.
The headline changes in 2.0:
world.with("componentName")
, chain these together, use the newwithout
, or even create advanced predicate-based queries usingwhere
.Some more details on the changes:
world.createEntity
has been renamed and simplified to justworld.add
(which now returns the correct type for the entity, too), andworld.destroyEntity
toworld.remove
.The
Tag
type and constant have been removed. For tag-like components, simply usetrue
(whichTag
was just an alias for.)Entities added to a world no longer receive a
__miniplex
component. This component has always been an internal implementation detail, but you might have used it in the past to get a unique identifier for an entity. This can now be done throughworld.id(entity)
, with ID lookups being available throughworld.entity(id)
.Queries can now be iterated over directly. Example:
This is, in fact, now the recommended way to iterate over entities, since it is extremely efficient, and will make sure that the list of entities is being iterated over in reverse, which makes it safe to modify it during iteration.
You can also use this to neatly fetch the first entity from an archetype that you only expect to have a single entity in it:
The queuing functionality that was built into the
World
class has been removed. If you've relied on this in the past,miniplex
now exports aqueue
object that you can use instead. Example:Please note that this is being provided to make upgrading to 2.0 a little easier, and will likely be removed in a future version.
with
andwithout
are the new API for building queries. Examples:The new
world.where
now allows you to build predicate-based queries! You can use this as an escape hatch for creating any kind of query based on any conditions you specify. Example:Please note that his requires entities with the
health
component to be reindexed using theworld.reindex
function in order to keep the archetype up to date. Please refer to the documentation for more details.You can use
where
to create a predicate-based iterator. This allows you to quickly filter a set of entities without creating new archetypes or other objects. Example:All of these can be chained!
Entities fetched from a query will have much improved types, but you can also specify a type to narrow to via these functions' generics:
Miniplex provides the new
Strict
andWith
types which you can use to compose types from your entity main type:The event library Miniplex uses has been changed to Eventery, which brings a change in API. Where before you would have done
onEntityAdded.add(listener)
, you will now toonEntityAdded.subscribe(listener)
.Patch Changes
miniplex-react@2.0.0
Major Changes
8a7a315: - The library has been significantly simplified and an almost mind-boggling number of bugs have beens quashed.
The main import and initialization have changed:
All lists of entities are now rendered through the upgraded
<Entities>
component, which takes an array of entities or a query (or even a world) as itsin
prop:If you're passing in a query or a world, the component will automatically re-render when the entities appear or disappear. If you don't want this, you can also just pass in a plain array containing entities:
<ManagedEntities>
has been removed. You were probably not using it. If you were, you can replicate the same behavior using a combination of the<Entities>
component and auseEffect
hook.The
useEntity
hook has been renamed touseCurrentEntity
.The world-scoped
useArchetype
hook has been removed, and superseded by the new globaluseEntities
hook: