Idea: ECSx.ServerEvents
Closed this issue · 1 comments
When the client is sensitive to network traffic, or the game state is very large, the cost of synchronizing all states each time is very high.
Is it possible to add an event list, just like client events, you can add events yourself every time you update the component, and only synchronize events to the client.
Only need to refresh all status at optional times.
In this way, the client can distinguish modifications based on events and synchronize the differences with the server.
Hi Binsect and thanks for the interesting questions. As you mentioned, using a naive approach such as in the Ship
tutorial, where every item is synchronized every frame, is often not ideal.
You introduced one possibility which is the publisher-subscriber pattern, where updates to the backend state would emit messages, to be received somehow by the client. If you're using Phoenix, you already have Phoenix.PubSub
set up, so this is a good fit. Simply update your System code to include a broadcast:
defmodule MyApp.Systems.Destruction do
...
def run do
for ship <- HitPoints.search(0) do
destroy_ship(ship)
Phoenix.PubSub.broadcast(MyApp.PubSub, "topic" {:ship_destroyed, ship})
end
end
end
and then any clients (e.g. LiveView) can subscribe to the topic to receive the messages:
defmodule MyAppWeb.ClientLive do
def mount(...) do
Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")
end
def handle_info({:ship_destroyed, entity}, socket) do
# update client state
end
end
The reason ECSx needs to provide a special ClientEvents API is to ensure that Component writes are serialized (due to technical implementation details using OTP). Going the other direction, from backend to frontend, does not have this issue, so it's not necessary for ECSx to force users into a single implementation if they wish to use this subscriber pattern.
Another possibility to solve the original issue, which is more difficult to implement but more robust (and used in many existing video games), is to reduce the amount of data transferred by calculating as many updates as possible on the client itself. That is a massive topic with lots of writing on it already so I'll leave that to you to research if you're interested 🙂