Updating Move Event Visibility Rules
I already decided how I want to change the move event visibility rules the other day, but I need to actually implement these changes in the code. I start by updating the existing test cases so they assert on the new desired behavior.
I also add a new test case to check that PCLeftHexEvent
events are added to the events log before any PCEnteredHexEvent
events for the same round.
defmodule Minotaur.GameEngine.Session.EndRoundPlayerMoveTest do
# …
describe "multiple players move from one hex, some to the same destination, another to different" do
# …
test "left hex events are created before all entered hex events for the same round", ctx do
events = Enum.map(ctx.game.events_log.events, fn {_, event} -> event end)
left_events = Enum.filter(events, fn event -> is_struct(event, PCLeftHexEvent) end)
entered_events = Enum.filter(events, fn event -> is_struct(event, PCEnteredHexEvent) end)
assert Enum.all?(left_events, fn left_event ->
Enum.all?(entered_events, fn entered_event -> left_event.id < entered_event.id end)
end)
end
end
end
I replace private function responsible for mapping global events to player event lists. The new function applies the updated player visibility rules for move events.
defmodule Minotaur.GameEngine.Session do
# ...
defp get_visibility_entered_hex_event(%{to: destination}, post_move_world) do
post_move_world
|> Worlds.get_pcs_at_coord(destination)
|> Enum.map(& &1.player_id)
end
defp get_visibility_left_hex_event(event, pre_move_world, post_move_world) do
pc_ids_in_destination =
post_move_world
|> Worlds.get_pcs_at_coord(event.to)
|> Enum.map(& &1.player_id)
pre_move_world
|> Worlds.get_pcs_at_coord(event.from)
|> Enum.map(& &1.player_id)
|> Enum.reject(fn player_id -> Enum.member?(pc_ids_in_destination, player_id) end)
end
# Move event player visibility rules:
# - PCEnteredHexEvent seen by players in destination hex post-move
# - PCLeftHexEvent seen by players started in origin hex pre-move, excluding players in the destination hex post-move
defp update_events_log_with_moves(log, entered_hex_events, pre_move_world, post_move_world) do
left_events_with_visibility =
entered_hex_events
|> Enum.map(fn event ->
left_hex_event = struct(PCLeftHexEvent, Map.from_struct(event))
{left_hex_event, get_visibility_left_hex_event(event, pre_move_world, post_move_world)}
end)
|> Enum.reject(fn {_, visibility_list} -> visibility_list == [] end)
entered_events_with_visibility =
Enum.map(entered_hex_events, fn event ->
{event, get_visibility_entered_hex_event(event, post_move_world)}
end)
# Add all PCLeftHexEvents to log before PCEnteredHexEvents
Enum.concat(left_events_with_visibility, entered_events_with_visibility)
|> Enum.reduce(log, fn {event, visibility_list}, log ->
add_event_with_visibility(log, event, visibility_list)
end)
end
end
With these changes, the updated tests and the new test for event ordering are all passing.
The next feature I’ve been thinking about adding is to add a separator between events in the UI log to show which events happened on the same round.