-
-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Ergonomics Improvements for 0.8.0 #7
Comments
Would treating world the same way you treat entities be a possibility? Basically a context and provider for the created singleton world and then a useWorld hook to access it? |
I specifically designed the React bits to create per-world instances of hooks and components for (at least) two reasons:
One alternative API that I have been thinking about was to provide an uncurried, global version of, for example, the const { entities } = useArchetype(world, "position", "velocity") And then leave it to the user to curry it with their preferred world, but the end result would in practice be extremely close to what we have in I hope this makes sense? |
Yes! I knew I was missing something obvious and the separate overlapping worlds was the key thing I was missing there. The uncurried, global version looks interesting, but yeah, it doesn't seem all that different than the current implementation. |
Most of this has now found its way into |
A collection of potential tweaks and improvements to the Miniplex API. Miniplex puts DX first, so let's make this awesome! If you've used Miniplex in the past (you're very courageous!) and have opinions on this, please chime in.
React API factory still feels weird
When using Miniplex vanilla, you just create a
new World()
instance. The React integration module provides acreateECS()
function that returns an object containing theworld
alongside a collection of React hooks and components. This works, but the difference in usage feels off. (OTOH, it might no longer be an issue if we move the React glue into its own package.)API drift between
createEntity
andaddComponent
createEntity
will accept an entity object, whileaddComponent
expects the name of the component and its data as separate arguments. This by itself is not a huge deal (and it matches the API ofremoveComponent
, which expects a component name as an argument), but there may be some nice opportunities for using functions to compose (and initialize) entities and components that would be blocked by this API.For example, we might provide some API tweaks that would allow you to do the following:
This kind of stuff would be easy to add to
createEntity
, but immediately clash with the currentaddComponent
signature.Should
<Collection>
use something other than a Tag to identify its collection of entities?The new
<Collection>
component serves a double purpose:tag
initial
prop is set to a non-zero value, it automatically spawns that number of entities, automatically tagged withtag
, and renders themThe idea here is that you have a single place in your application code that renders a collection of "things" (enemies, bullets, explosions) that are initially created as entities with just the tag identifying them, and then having the render function "mix in" new components. This is mostly intended as convenience glue to make game code expressive and easy to reason about.
Example:
Identifying discrete collections of entity "types" by tag is a very opinionated approach. It has worked well so far, but maybe this mechanism can be refined further? Some ideas:
Tag
type and constant for convenience (both of which are just equal totrue
), it could export aCollectionTag
flavor. Mechanically it would be the same thing, but in a complex entity type, it might make the intent clearer.Should
<Collection>
and<Entities>
memoize by default?The two components take a (currently) optional
memoize
prop that will make sure its children/render function will be converted into a memo'd component before being used. This is almost always what you want; consider that these two components will re-render every time an entity is added to or removed from "their" collection of entities; you wouldn't want to re-render 999 items when the 1000th is added.It is very easy to forget this prop and accidentally ruin the performance of your application, so maybe the memoization should become the default. In this scenario, the question is how to express this in the component API. There would need to be a new prop, but what would be call it?
unmemoized
?rerender
?active
?Provide
addTag
andremoveTag
?Miniplex already has a built-in notion of Tag components, providing a Tag type and constant, both of which equal to
true
. In addition toaddComponent
andremoveComponent
, Miniplex could provideaddTag
andremoveTag
for convenience.The text was updated successfully, but these errors were encountered: