WELCOME TO INFOCHEATS.NET

INFOCHEATS is a community-driven platform focused on free game cheats, cheat development, and verified commercial software for a wide range of popular games. We provide a large collection of free cheats shared by the community. All public releases are checked for malicious code to reduce the risk of viruses, malware, or unwanted software before users interact with them.

Alongside free content, INFOCHEATS hosts an active marketplace with many independent sellers offering commercial cheats. Each product is discussed openly, with user feedback, reviews, and real usage experience available to help you make informed decisions before purchasing.

Whether you are looking for free cheats, exploring paid solutions, comparing sellers, or studying how cheats are developed and tested, INFOCHEATS brings everything together in one place — transparently and community-driven.

Source R6 Siege Enhanced Recoil Engine — DPI Independent Scaling

byte_corvus

Newbie
Newbie
Newbie
Newbie
Status
Offline
Joined
Mar 3, 2026
Messages
598
Reaction score
7
Standard recoil scripts usually fall flat because they ignore how Siege actually handles sensitivity variables.

Most pastes just try to move the mouse by fixed pixel counts, which breaks the moment you change your FOV or swap a 1.0x for a 2.5x. This engine logic handles the actual math behind the GameSettings.ini, making the compensation DPI independent by normalizing everything back to hipfire equivalents.

Technical Breakdown
  1. RPM to MS Delay: Siege weapons have fixed fire rates. A simple 60000 / RPM gives you the exact delay between shots. Using generic 100ms waits is a fast way to get out-transfers in a gunfight.
  2. ADS Normalization: The engine calculates a multiplier based on the XFactorAiming and specific zoom factors (ranging from 0.6 for 1.0x to 0.32 for 5.0x).
  3. DPI Independence: Since R6 recoil is proportional to in-game sensitivity values, the script calculates deltas relative to your MouseYaw and MousePitch, meaning it doesn't care if you're on 400 or 1600 DPI.

Essential fire rate values for Attackers and Defenders:
- R4-C: 860 RPM
- F2 (Twitch): 980 RPM
- AK-12: 850 RPM
- Vector .45 ACP: 1200 RPM
- Scorpion EVO 3: 1080 RPM
- DP27 (Tachanka): 550 RPM (Uses a 12ms timing constant)

The Engine Logic
Code:
"""
Enhanced Recoil Engine - Uses R6 GameSettings ADS Sensitivity
Calculates weapon-specific timing based on RPM
"""
 
import math
from typing import Tuple
 
class EnhancedRecoilEngine:
    """
    Recoil compensation engine that properly accounts for:
    - Per-scope ADS sensitivity
    - Weapon fire rate (RPM → MS delay)
    - FOV and resolution
    - Custom multipliers from GameSettings
    
    NOTE: R6 Siege recoil is DPI INDEPENDENT - only in-game sensitivity matters!
    """
    
    def __init__(self, game_settings):
        """
        Args:
            game_settings: R6GameSettings object
        """
        self.game_settings = game_settings
        
        # Current weapon state
        self.current_weapon = None
        self.current_scope = "1.0x"
        self.current_rpm = 800  # Default RPM
        
        # Spray state
        self.shot_count = 0
        self.max_shots = 30
        
        print(f"[Recoil] Initialized - DPI Independent Mode")
        print(f"[Recoil] FOV: {game_settings.fov}")
        print(f"[Recoil] Mouse Yaw (H): {game_settings.mouse_yaw}")
        print(f"[Recoil] Mouse Pitch (V): {game_settings.mouse_pitch}")
        print(f"[Recoil] ADS 1x: {game_settings.ads_1x}")
    
    def set_weapon(self, weapon_name, scope="1.0x", rpm=800):
        """
        Set current weapon and scope
        
        Args:
            weapon_name: Weapon identifier
            scope: Scope magnification ("1.0x", "1.5x", "2.0x", "2.5x", etc)
            rpm: Weapon fire rate in rounds per minute
        """
        self.current_weapon = weapon_name
        self.current_scope = scope
        self.current_rpm = rpm
        self.shot_count = 0
        
        print(f"[Recoil] Set weapon: {weapon_name} | {scope} | {rpm} RPM")
    
    def get_shot_delay(self):
        """
        Calculate delay between shots based on weapon RPM
        
        Formula: delay_ms = 60000 / RPM
        
        Returns:
            float: Delay in seconds
        """
        if self.current_rpm <= 0:
            return 0.1  # Default 100ms
        
        # Convert RPM to delay in milliseconds
        delay_ms = 60000 / self.current_rpm
        
        # Convert to seconds
        delay_seconds = delay_ms / 1000.0
        
        return delay_seconds
    
    def get_timing_constant(self):
        """
        Get timing constant in MS (used by Logitech scripts)
        
        Formula: timing_ms = RPM / 6000
        
        Most guns: 5-8 ms
        Outliers: DP27 = 12ms, C1 9mm = 12ms
        
        Returns:
            int: Timing constant in milliseconds
        """
        timing = int(self.current_rpm / 100)
        
        # Clamp to reasonable range
        return max(5, min(12, timing))
    
    def calculate_ads_multiplier(self):
        """
        Calculate ADS sensitivity multiplier for current scope
        
        Uses R6 formula to normalize ADS back to hipfire:
        multiplier = (ads_value / zoom_factor) * XFactor * zoom * hipfire
        
        Returns:
            float: Multiplier to apply to recoil values
        """
        # Get raw ADS sensitivity for current scope
        ads_value = self.game_settings.get_ads_sens_for_scope(self.current_scope)
        
        # Zoom levels
        zoom_levels = {
            "1.0x": 0.6,
            "1.5x": 0.5,
            "2.0x": 0.45,
            "2.5x": 0.42,
            "3.0x": 0.38,
            "4.0x": 0.35,
            "5.0x": 0.32,
            "12.0x": 0.20
        }
        
        zoom = zoom_levels.get(self.current_scope, 0.6)
        fov = self.game_settings.fov
        
        # Calculate zoom factor
        fov_rad = fov * math.pi / 180
        zoom_factor = (zoom / math.tan((zoom * fov_rad) / 2)) / math.tan(fov_rad / 2)
        
        # Normalize ADS to hipfire equivalent
        normalized = (ads_value / zoom_factor) * self.game_settings.xfactor_aiming * zoom
        
        # Compare to hipfire (use MouseYaw as the primary sensitivity)
        # R6 uses MouseYaw for horizontal, MousePitch for vertical
        # For recoil (mostly vertical), we use the average or just Yaw
        hipfire = self.game_settings.mouse_yaw * self.game_settings.mouse_xfactor
        
        # Multiplier
        multiplier = normalized / hipfire if hipfire > 0 else 1.0
        
        return multiplier
    
    def calculate_fov_multiplier(self):
        """
        Calculate FOV-based multiplier
        
        Returns:
            float: FOV multiplier (normalized to 75 FOV baseline)
        """
        return self.game_settings.fov / 75.0
    
    def get_total_multiplier(self):
        """
        Get complete multiplier combining all factors
        
        R6 Siege is DPI independent - only ADS and FOV matter
        
        Returns:
            float: Final multiplier for recoil compensation
        """
        ads_mult = self.calculate_ads_multiplier()
        fov_mult = self.calculate_fov_multiplier()
        
        total = ads_mult * fov_mult
        
        return total
    
    def apply_recoil_compensation(self, base_horizontal, base_vertical):
        """
        Apply all multipliers to base recoil values
        
        Args:
            base_horizontal: Base horizontal recoil
            base_vertical: Base vertical recoil
        
        Returns:
            Tuple[float, float]: (compensated_h, compensated_v)
        """
        multiplier = self.get_total_multiplier()
        
        comp_h = base_horizontal * multiplier
        comp_v = base_vertical * multiplier
        
        return (comp_h, comp_v)
    
    def get_recoil_for_shot(self, shot_number, pattern):
        """
        Get recoil compensation for specific shot in pattern
        
        Args:
            shot_number: Current shot number (0-indexed)
            pattern: List of (h, v) tuples for recoil pattern
        
        Returns:
            Tuple[float, float]: (h, v) compensated recoil
        """
        # Get base recoil from pattern
        if shot_number >= len(pattern):
            # Use last value if past pattern end
            base_h, base_v = pattern[-1]
        else:
            base_h, base_v = pattern[shot_number]
        
        # Apply all multipliers
        return self.apply_recoil_compensation(base_h, base_v)
    
    def reset_spray(self):
        """Reset shot counter for new spray"""
        self.shot_count = 0
    
    def get_recoil_compensation(self):
        """
        Get recoil compensation for current shot (auto-increment)
        Uses generic pattern if no weapon set
        
        Returns:
            Tuple[float, float]: (horizontal, vertical) mouse movement
        """
        # Generic recoil pattern (vertical only, no horizontal drift)
        generic_pattern = [
            (0, 8),   # Shot 1
            (0, 10),  # Shot 2
            (0, 12),  # Shot 3
            (0, 11),  # Shot 4
            (0, 10),  # Shot 5
            (0, 9),   # Shot 6
            (0, 9),   # Shot 7
            (0, 8),   # Shot 8
            (0, 8),   # Shot 9
            (0, 7),   # Shot 10
            (0, 7),   # Shot 11-30 (rest of mag)
        ]
        
        # Get compensation for current shot
        compensation = self.get_recoil_for_shot(self.shot_count, generic_pattern)
        
        # Increment shot counter
        self.shot_count += 1
        
        # Cap at reasonable number
        if self.shot_count > 50:
            self.shot_count = 50
        
        return compensation
    
    def get_next_compensation(self, pattern):
        """
        Get compensation for next shot and increment counter
        
        Args:
            pattern: Recoil pattern as list of (h, v) tuples
        
        Returns:
            Tuple[float, float]: (h, v) compensated recoil
        """
        compensation = self.get_recoil_for_shot(self.shot_count, pattern)
        self.shot_count += 1
        return compensation
    
    def get_status(self):
        """Get current recoil engine status"""
        return {
            'weapon': self.current_weapon or "None",
            'scope': self.current_scope,
            'rpm': self.current_rpm,
            'shot_delay_ms': self.get_shot_delay() * 1000,
            'ads_multiplier': self.calculate_ads_multiplier(),
            'fov_multiplier': self.calculate_fov_multiplier(),
            'total_multiplier': self.get_total_multiplier()
        }
 
 
# Example weapon database with RPM
WEAPON_RPM = {
    # Attackers
    "R4-C": 860,
    "G36C": 780,
    "556xi": 690,
    "F2": 980,
    "417": 450,  # DMR
    "AK-12": 850,
    "C8-SFW": 837,
    "MK17 CQB": 585,
    "CAMRS": 450,  # DMR
    "SR-25": 450,  # DMR
    "ARX200": 850,
    "AR-15.50": 450,  # DMR
    "PDW9": 800,
    "AUG A2": 720,
    "COMMANDO 9": 780,
    "C7E": 800,
    "M762": 730,
    "V308": 700,
    "SPEAR .308": 700,
    "Mk 14 EBR": 450,  # DMR
    "BOSG.12.2": 500,  # Shotgun
    "Type-89": 850,
    "AR33": 749,
    "G8A1": 850,
    "AUG A3": 720,
    "552 Commando": 690,
    "L85A2": 670,
    "LMG-E": 720,
    "6P41": 680,
    "AK-74M": 650,
    
    # Defenders
    "MP5": 800,
    "MP5K": 800,
    "UMP45": 600,
    "FMG-9": 800,
    "MP5SD": 800,
    "P90": 970,
    "9x19VSN": 750,
    "MP7": 900,
    "M12": 550,
    "MPX": 830,
    "M870": 100,  # Shotgun
    "VECTOR .45 ACP": 1200,
    "T-5 SMG": 900,
    "SCORPION EVO 3 A1": 1080,
    "K1A": 720,
    "Mx4 Storm": 750,
    "ACS12": 300,  # Auto Shotgun
    "ALDA 5.56": 900,
    "TCSG12": 450,  # Slug Shotgun
    "AUG A3": 720,
    "COMMANDO 9": 780,
    "DP27": 550,  # Lord Tachanka (12ms timing)
    "C1 9mm": 575,  # Frost (12ms timing)
    "9mm C1": 575,
    "M590A1": 85,  # Shotgun
    "SG-CQB": 85,  # Shotgun
    "SASG-12": 330,  # Auto Shotgun
    "ITA12L": 85,  # Shotgun
    "SPAS-12": 200,  # Semi-auto Shotgun
    "SPAS-15": 290,  # Auto Shotgun
    "SIX12": 200,  # Revolver Shotgun
    "SIX12 SD": 200,  # Suppressed
    "SUPER 90": 200,  # Shotgun
    "M1014": 200,  # Shotgun
    "FO-12": 300,  # Auto Shotgun
}
 
 
if __name__ == "__main__":
    print("="*60)
    print("ENHANCED RECOIL ENGINE TEST")
    print("="*60)
    
    # Import game settings
    from game_settings_parser import R6GameSettings
    
    settings = R6GameSettings()
    engine = EnhancedRecoilEngine(settings)  # No DPI parameter!
    
    # Test with R4-C
    print("\nTesting R4-C...")
    r4c_rpm = WEAPON_RPM.get("R4-C", 860)
    engine.set_weapon("R4-C", "1.0x", r4c_rpm)
    
    # Show status
    status = engine.get_status()
    print("\nEngine Status:")
    for key, value in status.items():
        if isinstance(value, float):
            print(f"  {key:20s}: {value:.4f}")
        else:
            print(f"  {key:20s}: {value}")
    
    # Test recoil compensation
    print("\nRecoil Compensation Test:")
    test_pattern = [(0, 10), (0, 12), (-2, 11), (3, 10)]
    
    for i, (base_h, base_v) in enumerate(test_pattern):
        comp_h, comp_v = engine.get_recoil_for_shot(i, test_pattern)
        print(f"  Shot {i+1}: Base({base_h:3.0f}, {base_v:3.0f}) → Comp({comp_h:6.2f}, {comp_v:6.2f})")
    
    # Test different scopes
    print("\nScope Comparison:")
    for scope in ["1.0x", "1.5x", "2.0x", "2.5x"]:
        engine.set_weapon("R4-C", scope, r4c_rpm)
        mult = engine.get_total_multiplier()
        print(f"  {scope}: Total multiplier = {mult:.4f}")
    
    print("\n" + "="*60)

Stealth and Prevention
If you're using ctypes.windll.user32.mouse_event, you're playing with fire on anything higher than a casual match. BattlEye flags synthetic mouse input patterns through several heuristics. To keep your account alive:
  1. Ditch user32 for a kernel-level driver or use a signed Mouse/Keyboard interception library. Raw WinAPI calls are low-hanging fruit for AC.
  2. Add randomization: Introduce slight jitter to your sleep calls and pixel deltas. A perfectly static vertical line is an instant manual flag if you get reported.
  3. Resolution Check: The FOV multiplier must be normalized to a 75 FOV baseline to ensure consistency across different aspect ratios (4:3 vs 16:9).

Anyone tested if the recent shadow changes to the XFactor multiplier in the config files broke this math for the higher magnification scopes?
 
Top