Skip to content

[Bug]: Premature game reset when agent quits — any() vs all() in _remove_agent_from_game #474

@MariaRigaki

Description

@MariaRigaki

Bug Description

In netsecgame/game/coordinator.py:676, the _remove_agent_from_game method uses any(self._reset_requests.values()) to decide whether to trigger a game reset after an agent quits. The correct check is all(self._reset_requests.values()), which is the same logic used in _process_reset_game_action at line 424.

Using any() means that if even one remaining agent has requested a reset, the game reset is triggered immediately — even though other agents are still actively playing and have not requested a reset. This causes a premature, unsolicited game reset that corrupts the episode for all remaining agents.

Root cause

# Line 674-677 (_remove_agent_from_game) — BUGGY
agent_info["reset_request"] = self._reset_requests.pop(agent_addr)
# check if this agent was not preventing reset
if any(self._reset_requests.values()):    # <-- BUG: should be all()
    self._reset_event.set()

Compare with the correct logic used when agents explicitly request resets:

# Line 424 (_process_reset_game_action) — CORRECT
if all(self._reset_requests.values()):
    # all agents want reset - reset the world
    self._reset_event.set()

Steps to Reproduce

  1. Start a game with 3 agents (e.g., 2 Attackers + 1 Defender)
  2. Agent A requests a game reset (sets _reset_requests[A] = True)
  3. Agents B and C are still playing (_reset_requests[B] = False, _reset_requests[C] = False)
  4. Agent C sends QuitGame
  5. _remove_agent_from_game pops C's reset request, then checks any({A: True, B: False}.values()) which is True
  6. _reset_event.set() fires — the game resets even though Agent B never requested it

Agent B's in-progress episode is destroyed. The _reset_game task resets all agent states, trajectories, and rewards.

Expected Behavior

After an agent quits, a game reset should only be triggered if all remaining agents have requested a reset. Line 676 should use all() instead of any():

if all(self._reset_requests.values()):
    self._reset_event.set()

This matches the existing logic at line 424 and the comment at line 675 ("check if this agent was not preventing reset").

Version

1.1

Installation / Deployment Method

Running locally from source

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No fields configured for Bug.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions