# YimMenuV2 Players Module Architecture: Session Player Management Explained

> Explore the Players module architecture in YimMenuV2. Learn how it manages session players using a singleton backend, unordered_maps, and provides efficient lookups for session management.

- Repository: [YimMenu/YimMenuV2](https://github.com/YimMenu/YimMenuV2)
- Tags: architecture
- Published: 2026-07-16

---

**The Players module implements a singleton-based backend system that tracks up to 32 session players using `unordered_map` containers keyed by slot index, exposing static lookup methods for Rockstar IDs and host tokens while maintaining a separate selected player reference for menu targeting.**

The **Players** module serves as the central hub for session player management in YimMenuV2, residing in [`src/game/backend/Players.hpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/backend/Players.hpp) and [`Players.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/Players.cpp). This architecture decouples live GTA V player entities from their persistent metadata, enabling thread-safe access across network features, UI submenus, and saved player systems while abstracting the 0-31 session slot indexing used by the game’s networking layer.

## Core Data Structures and Storage Architecture

The module employs a **singleton pattern** with three primary data members that separate entity references from auxiliary state:

### Live Player Entity Storage

The `std::unordered_map<uint8_t, Player> m_Players` container stores entries for every active session participant, keyed by their **session slot index** (ranging from 0 to 31). Each `Player` object defined in [`src/game/gta/Player.hpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/gta/Player.hpp) mirrors the in-game entity, exposing properties such as the player ped, network ID, and current health. This map provides O(1) access to live player data when the slot index is already known.

### Auxiliary Data Container

Parallel to the player map, `std::unordered_map<uint8_t, PlayerData> m_PlayerDatas` holds supplemental information defined in [`src/game/backend/PlayerData.hpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/backend/PlayerData.hpp). This structure stores custom stats, saved variables, and UI-related state that persists only for the duration of the session but remains decoupled from the core `Player` entity. The separation allows the **SavedPlayers** subsystem to serialize `PlayerData` entries without touching the live game objects.

### Selected Player Target

The `Player m_SelectedPlayer` member maintains a reference to the specific player currently targeted by the menu interface. When a user selects a victim for spectating, kicking, or applying features through the frontend, the system updates this field via `Players::SetSelected()`, while `Players::GetSelected()` retrieves the active target for feature execution.

## Player Lifecycle and Event Hooks

The module manages session transitions through static wrapper methods that delegate to private implementation routines in the singleton instance.

### Initialization and Shutdown

During menu load, `Players::Init()` calls `InitImpl()` on the singleton instance obtained through `GetInstance()`, setting up any necessary hooks for player event monitoring. Conversely, `Players::Shutdown()` invokes `ShutdownImpl()` to gracefully clear containers and release resources when the menu unloads or the game session ends.

### Join and Leave Events

Network player transitions are handled by `Players::OnPlayerJoin(CNetGamePlayer* player)` and `Players::OnPlayerLeave(CNetGamePlayer* player)`. The `OnPlayerJoinImpl` implementation constructs a new `Player` entry in `m_Players` at the appropriate slot index and initializes a corresponding `PlayerData` entry in `m_PlayerDatas`. When a player disconnects, `OnPlayerLeaveImpl` removes both entries, ensuring no stale references remain to disconnected peers.

## Player Lookup and Query Interface

While the primary maps use slot indices as keys, the module provides several lookup helpers that search by alternate identifiers, implemented as linear searches through `m_Players` since these IDs are not stored as map keys.

### Rockstar ID Resolution

`Players::GetByRID(uint64_t rid)` delegates to `GetByRIDImpl` to locate a player by their **Rockstar ID** (RID). This method iterates through `m_Players` comparing the RID of each entry, returning the matching `Player` object or an invalid instance if not found. Network features such as those in [`src/game/features/network/HarassPlayers.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/features/network/HarassPlayers.cpp) utilize this method to resolve targets before sending spoofed packets.

### Host Token and Message ID Lookups

Similarly, `Players::GetByHostToken(uint64_t token)` searches the map for a player matching the specified network **host token**, while `Players::GetByMessageId(int id)` retrieves players using the **message ID** utilized by GTAV’s native messaging system. Both methods perform O(n) scans through the active player list, making them suitable for occasional lookups rather than per-frame operations.

### Convenience Accessors

The module exposes several utility methods for common access patterns:

- `Players::GetPlayers()` returns a reference to the raw `m_Players` map for direct iteration
- `Players::GetPlayerData(uint8_t idx)` retrieves the auxiliary data structure for a specific slot
- `Players::GetRandom()` selects a random entry from `m_Players` for "random-player" features
- `Players::SetSelected(Player)` and `Players::GetSelected()` manage the menu’s current target

## Integration with Frontend and Network Systems

The backend module acts as the data source for multiple subsystems throughout the codebase.

### Frontend UI Consumption

The player list submenu in [`src/game/frontend/submenus/Players.hpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/frontend/submenus/Players.hpp) queries `Players::GetPlayers()` to populate the active session list and allows user selection via `SetSelected()`. This decouples the ImGui-based interface from direct manipulation of game memory, routing all player interactions through the standardized backend API.

### Network Feature Integration

Network manipulation features leverage the lookup methods to resolve targets before executing logic. For example, persistent harassment features call `GetByRID()` or `GetByHostToken()` to ensure actions apply to the correct peer even if they change slots during the session. The **SavedPlayers** module in [`src/game/backend/SavedPlayers.hpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/backend/SavedPlayers.hpp) additionally reuses `PlayerData` structures to persist information across game sessions, while the core `Players` module maintains only the ephemeral, in-memory state.

## Summary

- The **Players** module uses a **singleton pattern** with dual `unordered_map` containers to separate live `Player` entities from auxiliary `PlayerData`, both keyed by 0-31 session slot indices.
- Lifecycle management occurs through `Init()`, `Shutdown()`, `OnPlayerJoin()`, and `OnPlayerLeave()` hooks that maintain container consistency with the game’s network state.
- Lookup methods `GetByRID()`, `GetByHostToken()`, and `GetByMessageId()` provide identifier-based searching via linear scans, while `GetSelected()` manages the menu’s current target.
- Frontend UI components and network features consume this backend through static wrapper methods, ensuring consistent session player management across YimMenuV2.

## Frequently Asked Questions

### How does YimMenuV2 store active session players?

The system stores active players in `std::unordered_map<uint8_t, Player> m_Players` within the singleton `Players` class, using the game’s 0-31 session slot index as the key for O(1) access. This map is populated and cleared via `OnPlayerJoin` and `OnPlayerLeave` hooks that respond to GTA V’s network events.

### What distinguishes `Player` from `PlayerData` in the architecture?

The `Player` class mirrors the actual in-game entity with properties like health and ped handle, while `PlayerData` in [`src/game/backend/PlayerData.hpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/backend/PlayerData.hpp) stores menu-specific metadata such as custom flags and UI state. This separation allows the **SavedPlayers** system to persist metadata without serializing raw game pointers.

### Why do Rockstar ID lookups perform linear searches instead of map lookups?

Because `m_Players` uses the session slot index (0-31) as its key rather than the Rockstar ID, the `GetByRID` method must iterate through all entries to find a match. This design choice prioritizes fast slot-based access—which occurs every frame for UI rendering—over occasional RID lookups.

### How does the module ensure thread safety during player join events?

The singleton instance (`static Players Instance`) is accessed through `GetInstance()` and provides a consistent view of all players throughout the menu’s lifetime. Static wrapper methods like `Players::OnPlayerJoin()` forward to the singleton's private implementations, ensuring that all subsystem access operates on the same synchronized data structures.