Ralith / hecs

A handy ECS
Apache License 2.0
921 stars 79 forks source link

Is it possible to clone World? With use case. #333

Closed johan-overbye closed 10 months ago

johan-overbye commented 11 months ago

I'm making a game editor and game with hecs. All of the game state is currently stored in a hecs World. The idea is the game designer sets up the initial World state by adding entities and components, then plays the game (prototype) in the same editor app. At that point I need to clone the World somehow.

Its components contain Entity values (dialogue graph etc), so I can't just spawn and clone individual components. As I'm writing this I'm seeing that insert allows you to assign components to a specific Entity, so I guess I could use that? Seems inefficient though.

adamreichold commented 11 months ago

You can (ab)use the serialization mechanism for cloning by serializing and then deserializing. Admittedly, it has some drawbacks w.r.t. efficiency and determinism, but it should work right now.

Alternatively, we could implement something like the World::clone(&self, &Cloner) -> Word interface described in https://github.com/Ralith/hecs/issues/332#issuecomment-1651560564 where one would need to register Clone and Copy impls for all component types (until specialization stabilizes), but we get exact copies of World including allocator state and with minimal overhead.

johan-overbye commented 11 months ago

Thanks @adamreichold. :) That's exactly what I ended up doing. I actually realised I'd probably want to serialise/deserialise regardless, as some of the components have "editable" versions, and I'll want the non-editable ones for play testing. For example, editable versions of components have Strings for numeric fields so I can edit them with my immediate-mode UI, but they serialise to numbers.

In other words, would be very cool if World::clone were a thing, but I wouldn't actually use it for my current use case after all.

Off-topic: what would be a good serde format for this sort of thing?

adamreichold commented 11 months ago

Off-topic: what would be a good serde format for this sort of thing?

My personal first choice would be bincode as a simple and efficient codec. However, that crate is currently shifting its focus away from serde support. postcard or dlhn might be considered reasonable successors with focussed on serde support.

Ralith commented 11 months ago

Alternatively, we could implement something like the World::clone(&self, &Cloner) -> Word interface described in https://github.com/Ralith/hecs/issues/332#issuecomment-1651560564

It's worth noting that the public API is already powerful enough for this to be implemented downstream, even column-oriented.

is currently shifting its focus away from serde support

It's also possible to use non-serde serialization, though it may take a bit of work. The out-of-the-box serde serialization code should serve as a good example; it uses only public hecs APIs.

adamreichold commented 11 months ago

It's worth noting that the public API is already powerful enough for this to be implemented downstream, even column-oriented.

I think this is true for the component data but that the entity allocator state is not exposed leading to the restricted determinism as discussed in #332?

johan-overbye commented 11 months ago

Thanks for your advice guys, and thanks a lot for your work on hecs! I'm loving it, and it's a key crate in our game, next to serde, ash and rhai.

I'll stick with serde_json for prototyping as I'm very far away from performance being a concern.