# How YimMenuV2 Reads and Writes Named and Packed Player Stats

> Discover how YimMenuV2 reads and writes player stats. Learn about binary search, stat mappings, and direct packed sStatData structure modification for efficient synchronization.

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

---

**YimMenuV2 reads and writes player stats by performing a binary search on a sorted array of stat mappings in `CStatsMgr`, returning a pointer to the packed `sStatData` structure where values are modified directly and marked dirty for synchronization.**

The YimMenuV2 stats system provides a high-performance interface for manipulating Grand Theft Auto V player statistics through both Lua scripts and native C++ code. Understanding how this menu handles **named and packed player stats** requires examining the `CStatsMgr` class and its binary search implementation. This article breaks down the exact mechanism used to read and write stat values based on the actual source code in the YimMenu/YimMenuV2 repository.

## The Architecture of YimMenuV2's Stats System

### Named Stats vs. Packed Stats

In YimMenuV2, **named stats** are identified by their Jenkins hash (e.g., `0x123ABC45` for `MP0_CASH`), while **packed stats** refer to the concrete memory structures (`sStatData`) that store the actual values. The system maintains a clear separation between the symbolic hash identifiers used by scripts and the raw data storage accessed by the game engine.

### The CStatsMgr Singleton

The `CStatsMgr` class serves as the central authority for all stat operations. It stores a pre-sorted array of `sStatMap` entries in `m_Stats`, where each entry maps a hash ID to a pointer to its corresponding `sStatData`. This array is populated at startup by [`src/types/stats/CStatsMpCharacterMappingData.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/types/stats/CStatsMpCharacterMappingData.cpp), ensuring all character-specific stats are indexed before any queries occur.

## How Stat Lookup Works: Binary Search in CStatsMgr

When the menu needs to access a stat, it calls `CStatsMgr::GetStat(uint32_t statHash)` defined in [`src/types/stats/CStatsMgr.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/types/stats/CStatsMgr.cpp). This function executes a binary search (`bsearch`) over the sorted `m_Stats` array to locate the matching `sStatMap` entry. If found, the function returns the `sStatData*` pointer stored in that entry; otherwise, it returns `nullptr`.

The binary search implementation provides **O(log n)** lookup complexity, which is critical for real-time modifications that may query hundreds of stats per tick without impacting frame rates.

### The sStatMap and sStatData Structures

The `sStatMap` structure acts as a bridge between names and data, containing the stat hash and a pointer to its `sStatData`. The `sStatData` structure holds the actual values in union-like fields (`intValue`, `floatValue`, `boolValue`) along with a `dirty` boolean flag that signals the game's native sync system to propagate changes to Rockstar's servers.

## Reading Player Stats

### Lua API Implementation

The Lua binding layer in [`src/game/scripting/libraries/Stats.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/Stats.cpp) exposes functions like `Stats.GET_INT(hash)` and `Stats.GET_FLOAT(hash)`. These wrappers call `CStatsMgr::GetStat(hash)` to retrieve the `sStatData*`, then read the appropriate field and push the value to the Lua stack.

## Writing Player Stats

Writing stats follows the same lookup path but adds modification logic. When a script calls `Stats.SET_INT(hash, value)`, the system retrieves the `sStatData*` via `GetStat`, overwrites the `intValue` field, and sets the `dirty` flag to `true`. This marks the stat for synchronization without immediately triggering network traffic, allowing batch modifications.

### Dirty Flag Synchronization

The **dirty flag** inside `sStatData` is crucial for performance. Instead of calling native Rockstar functions (`STAT_SET_INT`, etc.) immediately on every write, YimMenuV2 modifies the memory directly and relies on the game's existing stat sync mechanism to detect changes via the dirty flag. This approach minimizes overhead and prevents excessive native call overhead.

## Practical Code Examples

### Reading an Integer Stat (Player Cash)

```lua
local CASH_HASH = 0x123ABC45   -- hash for "MP0_CASH"
local cash = Stats.GET_INT(CASH_HASH)
print("Current cash:", cash)

```

*Implementation path:* `Stats.GET_INT` → `CStatsMgr::GetStat(hash)` → `data->intValue`.

### Writing a Float Stat (Player Stamina)

```lua
local STAMINA_HASH = 0x98765432
Stats.SET_FLOAT(STAMINA_HASH, 100.0)   -- max out stamina

```

*Implementation path:* `Stats.SET_FLOAT` → `CStatsMgr::GetStat(hash)` → `data->floatValue = 100.0` → `data->dirty = true`.

### Batch Modifying Packed Stats via C++

For direct memory manipulation of multiple fields, access the packed structure directly:

```cpp
sStatData* stats = CStatsMgr::GetStat(customHash);
if (stats) {
    stats->intValue   = 42;
    stats->floatValue = 3.14f;
    stats->dirty = true;       // mark for sync
}

```

This pattern appears in [`src/types/stats/CStatsMgr.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/types/stats/CStatsMgr.cpp) where the binary search returns the raw pointer for in-place modification.

## Key Source Files and Implementation Details

| Component | Description | Source Path |
|-----------|-------------|-------------|
| [`CStatsMgr.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/CStatsMgr.cpp) | Core manager implementing binary search lookup (`GetStat`) over the sorted `m_Stats` array. | [`src/types/stats/CStatsMgr.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/types/stats/CStatsMgr.cpp) |
| [`Stats.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/Stats.cpp) | Lua library exposing `GET_*` and `SET_*` functions, handling type conversion and dirty flags. | [`src/game/scripting/libraries/Stats.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/Stats.cpp) |
| [`CStatsMpCharacterMappingData.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/CStatsMpCharacterMappingData.cpp) | Initializes the stat mapping table for multiplayer characters at startup. | [`src/types/stats/CStatsMpCharacterMappingData.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/types/stats/CStatsMpCharacterMappingData.cpp) |

## Summary

- **YimMenuV2 uses `CStatsMgr`** with a binary search (`bsearch`) over a sorted `m_Stats` array to resolve named stat hashes to packed `sStatData` pointers in O(log n) time.
- **Reads** return values directly from `sStatData` fields (`intValue`, `floatValue`, `boolValue`).
- **Writes** modify the packed structure in-place and set a `dirty` flag to trigger the game's native synchronization system.
- **Source files** [`src/types/stats/CStatsMgr.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/types/stats/CStatsMgr.cpp) and [`src/game/scripting/libraries/Stats.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/Stats.cpp) contain the core implementation and Lua bindings respectively.

## Frequently Asked Questions

### What is the time complexity of stat lookups in YimMenuV2?

Stat lookups operate in **O(log n)** time complexity due to the binary search implementation in `CStatsMgr::GetStat`. The `m_Stats` array is pre-sorted at initialization, ensuring consistent performance even with thousands of registered stats.

### How does YimMenuV2 handle stat synchronization with Rockstar's servers?

Rather than calling native functions immediately, YimMenuV2 sets a **dirty flag** in the `sStatData` structure when values change. The game's internal stat sync mechanism detects these flags and handles network propagation, reducing overhead from excessive native calls.

### What is the difference between named stats and packed stats in YimMenuV2?

**Named stats** refer to the Jenkins hash identifiers (e.g., `0x123ABC45`) used to look up values, while **packed stats** are the concrete `sStatData` memory structures containing the actual values and dirty flags. The `CStatsMgr` class bridges these two layers.

### Where are the stat mappings initialized in YimMenuV2?

The mapping table is populated during startup by [`src/types/stats/CStatsMpCharacterMappingData.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/types/stats/CStatsMpCharacterMappingData.cpp), which inserts multiplayer character stats into the sorted `m_Stats` array before any Lua scripts or menu functions attempt to access them.