Skip to content
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

Ideas for 2.0 #165

Closed
hmans opened this issue Oct 4, 2022 · 6 comments
Closed

Ideas for 2.0 #165

hmans opened this issue Oct 4, 2022 · 6 comments
Assignees

Comments

@hmans
Copy link
Owner

hmans commented Oct 4, 2022

Some stuff I'd like to try/do in 2.0:

Remove the internal __miniplex component

Done! No more __miniplex component in 2.0. Whatever the library needs to track about entities now happens in separate internal data structures.

Provide an update(entity, update)-style mutation to make the world work a little bit more like a store

Cancelled! I experimented with this. The pattern was fun, but too inviting for bad patterns that would cause too many index updates. I will revisit this at some point though. The new buckets now have a touch function that doesn't perform updates to the entity, but just notifies connected buckets that they should reevaluate it.

and relax addComponent/removeComponent a little. Maybe update becomes the main interaction in 2.0?

Done (minus the update bit)! The World class that inherits from Bucket now has addProperty, setProperty and removeProperty, all of which will no-op if instead of throwing errors in case there's nothing to do for them.

Rename Archetype to just Index. Allow function-based indices that track entities where a custom function returns true. Potentially have subclasses like ArchetypeIndex and FunctionIndex.

Done! Except the base class is called Bucket, and it's really good. Bucket.derive(predicate) creates a derived bucket that automatically receives all entities that match the given predicate. If the predicate provides a type guard, all entities in the bucket will inherit that type. Cool!

Play around with some ideas around "chained archetypes/indices". Treat these as essentially derived state.

Done! This is now possible using the .derive function mentioned above.

Rework queuing. It's a little cumbersome that the queue API currently reflects the interaction functions 1:1. Maybe we can instead have a generic world.queue(() => world.destroyEntity(entity)) etc.?

TODO

Even if this breaks with the usual ECS terminology, maybe Miniplex should call components "properties"? It matches Miniplex' stance that entities are just objects, and would resolve potential confusion between ECS components and React components.

Done! Miniplex now calls them properties, and the related React component is now <Property>. This is closer to familiar JS nomenclature and resolves the annoying collision in terminology between React components and ECS components.

Cancelled! Turns out that this merely shifted the terminology collision to properties, with awkward conversations about "putting property x on the entity's y property". Ouch! It's now back to "components".

Other ideas:

The constructor for World could take a factory function that creates default new entities (and infer types from that)

TODO

@hmans hmans added this to the Miniplex 2.0.0 milestone Oct 4, 2022
@hmans hmans self-assigned this Oct 4, 2022
@mikecann
Copy link

mikecann commented Oct 16, 2022

Im personally not a fan of the rename from "Component" to "Property" but I havent done much with miniplex-react so am unable to comment on the confusion you have mentioned there.

My reasoning is that I see miniplex as an "ECS" and so they should be called "Components" not "Properties", I kind of see Properties as something that a Component has e.g. .x or .y in a Position Component.

But its not a strong dislike, so if the rename goes ahead its not going to stop me loving miniplex or anything ;)

The other changes im okay with so long as there is still a way to get an entities ID (now that the __miniplex component has been removed).

@hmans
Copy link
Owner Author

hmans commented Oct 16, 2022

My reasoning is that I see miniplex as an "ECS" and so they should be called "Components" not "Properties", I kind of see Properties as something that a Component has e.g. .x or .y in a Position Component.

The rename is not 100% set in stone yet, but it's likely that it'll be released this way. As you can imagine, talking about components gets very cumbersome once using this in a React context, and this will resolve that.

Outside of a React context, I like about "property" that it reflects that entities here are just normal objects, with normal properties. Miniplex has always been leaning more towards what is familiar in the JS world instead of what would be considered idiomatic ECS design and terminology, in an attempt to become one of the most approachable implementations of the pattern, and I think for this, the rename fits well.

The other changes im okay with so long as there is still a way to get an entities ID (now that the __miniplex component has been removed).

This isn't 100% final, but 2.0 currently exports an id function that you can use to get a stable ID for any entity (just do id(entity) wherever you need it; it will always return the same ID for the same entity), but at the same time I'd like to encourage users to implement their own IDs if they are needed in the application's business logic.

@mikecann
Copy link

This isn't 100% final, but 2.0 currently exports an id function that you can use to get a stable ID for any entity (just do id(entity) wherever you need it; it will always return the same ID for the same entity), but at the same time I'd like to encourage users to implement their own IDs if they are needed in the application's business logic.

Ye I havent actually needed it yet (thanks to the power of simply referencing an entity by its object reference) but its good to know its there. As you say we could roll our own component / ID but "shrug" seems like if its in the engine anyways then it could be exposed.

Miniplex has always been leaning more towards what is familiar in the JS world instead of what would be considered idiomatic ECS design and terminology, in an attempt to become one of the most approachable implementations of the pattern, and I think for this, the rename fits well.

I hear you, but IMO I still prefer "Component" perhaps because of my background....

... at a risk of hijacking this thread. Im the lead of a web game called BattleTabs we are currently in the middle of porting it from 2D to 3D and at the same time upgrading the engine within it from a customised TS Port of Ash-ECS to miniplex. I have lots of experience with ECS systems haven written a few myself.

So when I came to implement the first version of BattleTabs I was kind of disappointed at the last of ECS options in JS land, hence why I ported Ash (from AS3) to TS. Now tho there are more options with much better performance than Ash but I wasnt really happy with the dev experience of a lot of them (bit-ecs, wolf-ecs etc), then I discovered Miniplex.

Its like Ash but with a lot less typing and I have been thoroughly enjoying it. Although it will never be as fast as bit-ecs I dont need it for BattleTabs which isnt going to have tens of thousands of entities. We will be bottlenecked by BabylonJS way before we are bottlenecked by Miniplex so the developer experience far outweighs that IMO.

Once Miniplex2.0 lands and the dust settles I hope to write a blog post on all of this and perhaps share some helper utils that I have been using with Miniplex (Systems management mostly).

So this has been a long way of saying, keep doing what you are doing, I really think there is a much needed hole in the market for Miniplex, I tried a lot of the ones out there and I think this is the best ❤️

@hmans
Copy link
Owner Author

hmans commented Oct 16, 2022

Ye I havent actually needed it yet (thanks to the power of simply referencing an entity by its object reference) but its good to know its there. As you say we could roll our own component / ID but "shrug" seems like if its in the engine anyways then it could be exposed.

The reasoning behind not making entity ID a first-class citizen of the entity itself, so far, is mostly that different projects can have wildly different requirements for IDs, depending on how they use the library, eg.:

  • not needing IDs at all (yay!)
  • just needing IDs for situations where a unique value is needed, but the value itself isn't important, eg. when rendering a list of React components where each one needs a key prop, or when you just want to reference entities using IDs instead of object identity (my personal most common usecase so far)
  • the business domain requires entity IDs that need to live inside the entity and is serializable (eg. any application that wants to save and load entities, or synchronize them between server and client)
    • this one can have multiple variations where the ID has different formats. It may be a number, it may be a string containing a UUID4, and so on.

The primary reason why I've been careful with this is that I know that as soon as Miniplex does any of this out of the box, it has a high risk of impacting (or, worse, clashing with) the application requirements and design.

The id function (which is just as undocumented at the moment as the rest of 2.0, but that doesn't mean it's just an internal feature) currently lacks a getEntity(id) counterpart that will make it useful for actually linking entities, but it'll get that before the release.

And I think I generally prefer this pattern (of implementing "ID stores" that are not linked to the rest of the ECS bits in Miniplex) to making World know about IDs.

I hear you, but IMO I still prefer "Component" perhaps because of my background....

FWIW, just this morning I caught myself saying, in a conversation about Miniplex, "if the entity has a sleeping property on its physics property`, and I immediately regretted this change, at least in that moment. So do rest assured that I will give this some more thought before release. :-)

Once Miniplex2.0 lands and the dust settles I hope to write a blog post on all of this and perhaps share some helper utils that I have been using with Miniplex (Systems management mostly).

That would be really cool! As for the release timeline, I want to give 2.0 at least a couple of weeks before I release a final version, but I do want to push a beta build soon (maybe the coming week, or shortly after) with an announcement blog post that describes the changes and how to upgrade. If you're curious, I have already been pushing prerelease builds under the next tag, but the usual warnings apply, and none of the documentation has been updated yet.

@mikecann
Copy link

mikecann commented Oct 17, 2022

As for the release timeline, I want to give 2.0 at least a couple of weeks before I release a final version, but I do want to push a beta build soon (maybe the coming week, or shortly after) with an announcement blog post that describes the changes and how to upgrade.

Fantastic, no rush at all, dont stress, get it right. Ill continue on with my port of BattleTabs with v1, it shouldnt be a big refactor later to upgrade it to 2.0.

@hmans
Copy link
Owner Author

hmans commented Nov 2, 2022

2.0 is getting close, so time to close this issue. Thanks for all the feedback!

@hmans hmans closed this as completed Nov 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants