Question about creating a server for each game session
Dear @iacobson , thanks for sharing the amazing Ecspanse lib! In case we want to create a server for each game session, in order to optimize the latency in case we have many game sessions simultaneously, let me know if this approach [AI gen] would be fine:
Yes, if you want to have one server per group of players, you would need to modify the architecture to dynamically spawn Demo servers. Currently, the Demo module is started as a single instance in the supervision tree.
Here's a high-level approach to support multiple game instances:
1 Create a DynamicSupervisor to manage multiple game instances:
defmodule Demo.GameSupervisor do
use DynamicSupervisor
def start_link(_) do
DynamicSupervisor.start_link(__MODULE__, nil, name: __MODULE__)
end
def init(_) do
DynamicSupervisor.init(strategy: :one_for_one)
end
def start_game(game_id) do
# Each game would need its own unique name
child_spec = %{
id: Demo,
start: {Demo, :start_link, [game_id]},
restart: :transient
}
DynamicSupervisor.start_child(__MODULE__, child_spec)
end
end
2 Modify the application supervision tree:
defmodule Demo.Application do
use Application
@impl true
def start(_type, _args) do
children = [
Demo.GameSupervisor
# Other supervisors/workers...
]
opts = [strategy: :one_for_one, name: Demo.Supervisor]
Supervisor.start_link(children, opts)
end
end
3 Modify the Demo module to accept a game_id and use it for naming:
defmodule Demo do
use Ecspanse
def start_link(game_id) do
Ecspanse.start_link(__MODULE__, game_id, name: via_tuple(game_id))
end
# Use Registry to track game instances
defp via_tuple(game_id) do
{:via, Registry, {Demo.GameRegistry, game_id}}
end
# Rest of the module...
end
4 Then you could start new game instances like:
# Start a new game for group "group_1"
{:ok, pid} = Demo.GameSupervisor.start_game("group_1")
# Start another game for group "group_2"
{:ok, pid2} = Demo.GameSupervisor.start_game("group_2")
You would also need to:
1 Add a Registry to track the game instances
2 Modify your game logic to scope operations to specific game instances
3 Consider how to clean up/stop game instances when they're no longer needed
4 Handle game state persistence if needed
5 Consider how to route player actions to the correct game instance
Hi @henry-hz !
First of all thanks for trying the Ecspanse library!
Regarding your question, the short answer, unfortunately, is that Ecspanse does not support multiple ECS servers. More users asked about it, but it was a decision I had to take in the early stages of the project.
The main reason is that Ecspanse needs to communicate with some outside UI (eg Liveview) or some API to produce any effects. Eg, display your game, or interact with your game as a server. In order to have multiple servers, you would need to know with every external request (event, query, etc) the name or the PID of the Ecspanse instance you are calling. I tried that, and it was a very "unfriendly" programming experience.
With a single named instance this is not needed anymore. The server is aware of its name and I can simply write the queries and events from outside the library context, making it much easier to deal with.
Please check this question: https://elixirforum.com/t/ecspanse-an-entity-component-system-framework-for-elixir/57650/41?u=iacobson and this answer https://elixirforum.com/t/ecspanse-an-entity-component-system-framework-for-elixir/57650/42?u=iacobson on the elixir forum more details, but also for some alternative to your question.
Thanks @iacobson for your feedback and appreciation! in fact, the solution you wrote in the forum
player_entities = Ecspanse.Query.list_children(room_entity)
## If the room has also other type of children
player_entities = Ecspanse.Query.select({Ecspanse.Entity},
with: [MyGame.Comp.Player],
for_children_of: [room_entity])
|> Ecspanse.Query.stream()
|> Enum.map( fn {player_entity} -> player_entity end )
can be quite good, we will probably have around 200 rooms for playing cards, so in a 5 FPS, we can still have a good performance without adding the multi-server complexity. I was wandering on a model to measure the latency performance based on the FPS , query complexitys and event frequency interactions with Ecspanse. Let me know if you have any tip :)
Glad if it helps!
I was wandering on a model to measure the latency performance based on the FPS , query complexitys and event frequency interactions with Ecspanse.
I agree that some kind of performance/monitoring system would be cool. But I suggest it as a plugin to the library. Most Like what the ECSx library does: https://github.com/ecsx-framework/ecsx_live_dashboard
The creator of Ecspanse state machine library, was also investigating this: https://github.com/ketupia/ecspanse_live_dashboard
As discussed with him, I would be happy to add some monitoring/performace API (functions) to the library (limited to the free time I have :) ), to provide the base for anybody wanting to build a dashboard on top. Or also very happy to accept PRs for such API. Probably many things such as a system duration, how many times an event is triggered, etc, can be exposed with telemetry. But I personally did not look into it at all.