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

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions