Open Uriopass opened 1 year ago
After a big rewrite I have removed hecs in favor of a simple "entity lists" that has been working well for me for the map.
This allows me to get a better grip on determinism and serialization. However it makes iterations a bit more expensive (less cache friendly).
Determinism is a requirement for multiplayer as the state is too big to be synchronized live. We use lockstep networking which means only sending the initial state and subsequent inputs. It is also very useful to be able to save replays to help with bug reports as it is easier to see what the player did to get there.
However this comes with a lot of hurdles as the game needs to be deterministic even through ser/deserialization cycles as the game is sent over the network and serialized mid-replay.
Usually, this means that iteration order must be stable wherever used, ids must be stable if they are stored and used elsewhere, and in general any hidden state should be saved if it affects the game state in any way.
Note that determinism must only be there for the game state (the egregoria crate), the UI can be as random as it wants.
With that said, here's a list of recommendations and tracking issues about this:
BTreeMap
/BTreeSet
s instead ofHashMap
/HashSet
for deterministic iteration order even through ser/de (which isn't necessarily the case ofindexmap::IndexMap
s) for a modest runtime cost.https://github.com/orlp/slotmap/issues/104SlotMap
s don't keep freelists, a fork will be madehttps://github.com/Ralith/hecs/issues/332hecs
doesn't serialize entity state, so either a fork will be made or we will move out ofhecs
entirely, Egregoria does not really use the component/system ergonomics that much as entities don't share a lot of state