SanderMertens / flecs

A fast entity component system (ECS) for C & C++

Home Page:https://www.flecs.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lockstep support, or deterministic calculations.

Eragon-Brisingr opened this issue · comments

Can Flecs support Lockstep network synchronization? I've noticed the use of some floating-point numbers in the systems, which is unacceptable for deterministic calculations.
The Lockstep scheme needs to synchronize an initial world state to the client. Can Flecs serialize the state of the world into binary and then deserialize it on another end? What solutions can ensure that the deserialized result is consistent with the server's state, such as the order of components and the execution order of systems?

Which are the floating-point numbers that are used in Flecs' built-in systems? I can think of delta_time and other timing related functionality, but you can roll you own, and call ecs_progress to move the world one step forward. There might also be the possibility of overriding ecs_ftime_t with a non-floating-point type.

Can't speak on your other questions.

Yes it can. Like @copygirl mentioned you can override the ecs_ftime_t type (see flecs header) to an integer type, which will change all floating point time keeping features to use an integer. You can also call ecs_progress with a fixed/application specified time value.

Flecs has a reflection framework that lets you build any kind of serialization on top of it. Take a look at the JSON code for an example.

  • If I change ecs_ftime_t to uint32_t, the following code would cause an infinite loop: https://github.com/SanderMertens/flecs/blob/a666b506c74ceaabd79d35c09b67c5df4259503c/flecs.c#L24078
  • I have also found several uses of floating point numbers in the source code, and I cannot evaluate whether they will affect deterministic calculations.
  • After performing Json serialization, can it be guaranteed that the states of the two ends are completely consistent, such as the order of execution of entities in the next frame, the allocation logic of ecs_id, and so on?

Ah, the infinite loop sounds like an issue that was recently reported on the Discord as well. I'll take a look at that.

There are plenty of cases where floating point numbers are used in the code, though all usages related to time use the ecs_ftime_t type. That's the only one that should affect gameplay code because of delta_time, unless you explicitly build your game logic on other floating point values (which you shouldn't do if you want it to be deterministic).

The JSON serializer is not deterministic. I mentioned it because it's an example of a serializer that's built on top of the reflection framework. You can build a deterministic serializer on top of the reflection framework, there's nothing in it that'd prevent you from doing that.

@SanderMertens thank your answer. when infinite loop fixed i will close this issue.

@SanderMertens , I am currently attempting network synchronization with Lockstep based on Flecs.

  • When referring to the Json serialization solution, I noticed that information such as ecs_id cannot be overwritten to the client. After tracing the source code, I understood that I need to serialize the status and entity id information in ecs_world_t.store.entity_index. However, there seems to be no public API to access ecs_entity_index_t. Is there a reasonable way to complete the above function? (Modifying the source code is acceptable)
  • Could you provide a list of system states that need to be serialized? I am unsure whether the initial state consistency and calculation order are satisfied after completing the id status initialization synchronization.

Also, thank you for providing such a clean ecs solution for the community to use.