diff --git a/docs/assets/network_intel_node.svg b/docs/assets/network_intel_node.svg
new file mode 100644
index 00000000..38217167
--- /dev/null
+++ b/docs/assets/network_intel_node.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/network_intel_node_white.svg b/docs/assets/network_intel_node_white.svg
new file mode 100644
index 00000000..78fc6249
--- /dev/null
+++ b/docs/assets/network_intel_node_white.svg
@@ -0,0 +1 @@
+
diff --git a/docs/base_agent.md b/docs/base_agent.md
index 68fdad5c..b402bd39 100644
--- a/docs/base_agent.md
+++ b/docs/base_agent.md
@@ -3,5 +3,4 @@ The `BaseAgent` class provides the foundational interface for all agents interac
All custom agents should extend this class and implement their decision-making logic by overriding a method like `choose_action` (see [Getting Started](getting_started.md#creating-your-first-agent) for an example).
-::: netsecgame.agents.base_agent.BaseAgent
-::: netsecgame.agents.parallel_base_agent.ParallelBaseAgent
\ No newline at end of file
+::: netsecgame.agents.base_agent.BaseAgent
\ No newline at end of file
diff --git a/docs/parallel_base_agent.md b/docs/parallel_base_agent.md
new file mode 100644
index 00000000..441002d8
--- /dev/null
+++ b/docs/parallel_base_agent.md
@@ -0,0 +1,7 @@
+# Parallel Base Agent
+
+The `ParallelBaseAgent` class extends the concepts of the base agent to manage connections to multiple NetSecGame server instances simultaneously, enabling parallel environment interaction.
+
+Unlike `BaseAgent` (which manages a single socket), this class maintains one TCP socket per environment and exposes vectorized versions of methods like `register()`, `make_step()`, and `request_game_reset()` that operate on lists of actions and observations.
+
+::: netsecgame.agents.parallel_base_agent.ParallelBaseAgent
diff --git a/mkdocs.yml b/mkdocs.yml
index bfbcf0c7..29677129 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -2,6 +2,8 @@ site_name: Network Security Game
theme:
name: material
user_color_mode_toggle: true
+ favicon: assets/network_intel_node.svg
+ logo: assets/network_intel_node_white.svg
nav:
- Home: index.md
@@ -11,7 +13,9 @@ nav:
- Global Defender: global_defender.md
- API Reference:
- Game Components: game_components.md
- - Base Agent: base_agent.md
+ - Agents:
+ - Base Agent: base_agent.md
+ - Parallel Base Agent: parallel_base_agent.md
- Agent Server: agent_server.md
- Game Coordinator: game_coordinator.md
- Configuration Manager: configuration_manager.md
diff --git a/netsecgame/agents/parallel_base_agent.py b/netsecgame/agents/parallel_base_agent.py
index 067ca3eb..2f0bd982 100644
--- a/netsecgame/agents/parallel_base_agent.py
+++ b/netsecgame/agents/parallel_base_agent.py
@@ -322,8 +322,7 @@ def _run_parallel(
args_per_env: Optional extra positional args per env index.
Returns:
- List of results, one per ``self._num_envs``. Indices not included
- in *env_indices* get ``None``.
+ List of results, one per ``self._num_envs``. Indices not included in *env_indices* get ``None``.
"""
if env_indices is None:
env_indices = [i for i in range(self._num_envs) if self._sockets[i] is not None]
@@ -367,9 +366,7 @@ def register(self) -> "Observation | None | List[Optional[Observation]]":
"""Register in all connected environments in parallel.
Returns:
- In single-env mode: the initial ``Observation`` (or ``None``).
- In multi-env mode: list of initial observations, positionally
- aligned with ``game_ports``.
+ The initial ``Observation`` (or ``None``) in single-env mode, or a list of initial observations positionally aligned with ``game_ports`` in multi-env mode.
"""
results = self._run_parallel(self._register_single)
# Re-initialise done mask: failed envs stay done
@@ -383,6 +380,9 @@ def make_step(
) -> "Observation | None | List[Optional[Observation]]":
"""Execute one step in every **active** environment in parallel.
+ *Note: If you need to access the boolean done statuses across
+ all environments, you can use the `self.done_mask` property.*
+
Args:
actions: In single-env mode a single ``Action``; in multi-env
mode a list of ``Action`` objects (one per environment).
@@ -390,12 +390,7 @@ def make_step(
**ignored** (no message is sent to that env).
Returns:
- In single-env mode: a single ``Observation | None``.
- In multi-env mode: list of observations positionally aligned
- with ``game_ports``.
-
- *Note: If you need to access the boolean done statuses across
- all environments, you can use the `self.done_mask` property.*
+ A single ``Observation | None`` in single-env mode, or a list of observations positionally aligned with ``game_ports`` in multi-env mode.
Raises:
ValueError: If the number of actions doesn't match ``num_envs``.
@@ -444,9 +439,7 @@ def request_game_reset(
seed: RNG seed. Required when ``randomize_topology`` is True.
Returns:
- In single-env mode: the initial ``Observation`` (or ``None``).
- In multi-env mode: list of initial observations, positionally
- aligned with ``game_ports``.
+ The initial ``Observation`` (or ``None``) in single-env mode, or a list of initial observations positionally aligned with ``game_ports`` in multi-env mode.
"""
if seed is None and randomize_topology:
raise ValueError(