How YimMenuV2 Entity Networking Methods Work: ForceControl and PreventMigration Explained
YimMenuV2 uses ForceControl() to seize network ownership of any entity and PreventMigration() to disable GTA V's automatic proximity-based host migration, ensuring stable modding control over vehicles, peds, and objects.
The YimMenu::Entity class serves as the foundation for manipulating in-game objects within the YimMenuV2 codebase. When entities are networked—meaning they possess a corresponding netObject—these methods provide deterministic control over ownership states that standard game scripts cannot guarantee.
Understanding Network Ownership in GTA V
GTA V's networking architecture automatically manages entity ownership to distribute simulation load across connected clients. By default, the player closest to an entity becomes its network owner, granting exclusive write permissions for position updates, health changes, and deletion requests. This automatic migration causes desynchronization issues in modding contexts, requiring explicit intervention through the network object manager (Pointers.NetworkObjectMgr).
How ForceControl() Takes Ownership of Networked Entities
The ForceControl() method programmatically transfers network ownership to the local player without waiting for standard request-control loops. This operation is essential for executing destructive or transformative actions on entities created by other players.
Implementation Details in Entity.cpp
According to the source code in src/game/gta/Entity.cpp, the method executes a strict validation sequence before modifying ownership:
- Entity Validation: Uses
ENTITY_ASSERT_VALIDto ensure the handle references an existing game object - Network Check: Returns early if
IsNetworked()returns false orHasControl()returns true (already owned) - Ownership Transfer: Calls
ChangeOwneron the network object manager to immediately assign the local player as host
// From src/game/gta/Entity.cpp (lines 137-144)
void Entity::ForceControl()
{
ENTITY_ASSERT_VALID();
if (!IsNetworked() || HasControl())
return;
// Forces local player to become network owner
Pointers.NetworkObjectMgr->ChangeOwner(m_NetObject, Pointers.GetLocalPlayerInfo(), 0);
}
Lua Scripting Access
The scripting interface exposes this functionality through the force_control binding registered in src/game/scripting/libraries/Entity.cpp. This allows Lua scripts to safely manipulate entities selected through the menu interface.
-- Assume 'vehicle' is a YimMenu entity handle
vehicle:force_control()
-- Now safe to modify: set position, apply upgrades, or delete
vehicle:set_position(PLAYER.GET_PLAYER_COORDS(PLAYER.PLAYER_ID()))
How PreventMigration() Stops Automatic Host Transfer
GTA V's proximity-based migration system automatically transfers entity ownership to the nearest player to optimize network traffic. The PreventMigration() method disables this behavior, keeping the entity bound to its current host regardless of physical distance.
The Migration Problem
Without migration prevention, entities transferred between hosts experience:
- Position snapping and rubber-banding
- Loss of applied modifications (god mode, custom properties)
- Failed deletion attempts when the original creator leaves
Implementation Details
The implementation in src/game/gta/Entity.cpp (lines 317-334) verifies session state before invoking the native:
void Entity::PreventMigration()
{
ENTITY_ASSERT_VALID();
if (!*Pointers.IsSessionStarted)
return;
if (!NETWORK::NETWORK_HAS_ENTITY_BEEN_REGISTERED_WITH_THIS_THREAD(m_Handle))
return;
// Disable automatic proximity-based migration
NETWORK::NETWORK_DISABLE_PROXIMITY_MIGRATION(NETWORK::PED_TO_NET(m_Handle));
}
This method requires:
- An active game session (
*Pointers.IsSessionStarted) - Thread registration via
NETWORK_HAS_ENTITY_BEEN_REGISTERED_WITH_THIS_THREAD - Conversion of the entity handle to a network ID using
NETWORK::PED_TO_NET
C++ Usage Example
YimMenu::Entity target = GetEntityByHandle(someVehicle);
target.ForceControl(); // Take ownership first
target.PreventMigration(); // Lock to current host
// Entity remains stable regardless of distance from original owner
Practical Implementation: The Bring Feature
The Bring feature in src/game/features/world/Bring.cpp demonstrates the combined usage pattern (lines 18-52). This feature teleports distant entities to the local player by first ensuring network dominance:
void BringEntity(YimMenu::Entity& obj)
{
// Seize control to allow position updates
obj.ForceControl();
// Prevent immediate migration back to original host
obj.PreventMigration();
// Safely teleport now that we own the network object
obj.SetPosition(self.GetPosition());
}
This sequence prevents the common failure mode where entities snap back to their original positions after teleportation due to ownership conflicts.
Summary
- ForceControl() immediately transfers network ownership to the local player through
Pointers.NetworkObjectMgr->ChangeOwner(), bypassing standard request queues insrc/game/gta/Entity.cpp - PreventMigration() calls
NETWORK_DISABLE_PROXIMITY_MIGRATIONto stop GTA V's automatic host transfer based on player proximity - Both methods validate entities using
ENTITY_ASSERT_VALIDand check session state viarage::tlsContextto prevent crashes - The Lua binding in
src/game/scripting/libraries/Entity.cppexposesforce_controlto scripting environments - Production features like
Bringinsrc/game/features/world/Bring.cppcombine these methods to ensure stable entity manipulation
Frequently Asked Questions
What is network ownership in GTA V?
Network ownership determines which client has authority to write state changes (position, health, deletion) to an entity. Only the current network owner can reliably modify networked objects; other players receive desynchronized updates if they attempt changes. YimMenuV2's ForceControl() manipulates this ownership through the netObject system.
Why does ForceControl fail on some entities?
ForceControl() fails when entities are not networked (IsNetworked() returns false) or when the local player already owns the entity (HasControl() returns true). Additionally, the method requires a valid netObject pointer from the network object manager; entities in single-player modes or certain interior cells lack these network components entirely.
Is PreventMigration permanent?
No, PreventMigration() persists only for the current session or until the entity is deleted. If the entity is recreated or the session changes, the protection must be reapplied. The method uses NETWORK_DISABLE_PROXIMITY_MIGRATION, which binds to the specific network ID generated when NETWORK_HAS_ENTITY_BEEN_REGISTERED_WITH_THIS_THREAD validates the script context.
Can these methods be used in Lua scripts?
Yes, force_control is exposed to Lua through the scripting library in src/game/scripting/libraries/Entity.cpp. However, prevent_migration requires direct native calls via the NETWORK_DISABLE_PROXIMITY_MIGRATION native, as the specific method binding may vary by build. Always call force_control before attempting destructive operations on entities created by other players.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →