RED Tweaks - psiberx/cp2077-tweak-xl GitHub Wiki

Introduction

TweakXL supports the original tweak file format used by REDengine / REDmod, but interprets it differently, merging definitions instead of replacing them. This approach ensures compatibility and maintainability:

  • Allows different mods to modify the same records, and in some cases even the same properties
  • Makes mods more prepared for game updates, sometimes not requiring any changes

With full syntax support, you can use the REDmod sources as a reference and copy-paste definitions from it. But you shouldn't use entire files as is.

Tweak files can have any name and must have a .tweak extension, be placed in the <Cyberpunk 2077>/r6/tweaks directory, and can be organized using subdirectories.

Packages

Tweak file can define the package name that acts as the namespace for the groups, and import other packages to look for groups in:

package Attacks
using AttackModifier

GenjiReflect : BaseExplosion
{
    statModifiers = 
    [
        {
            refObject = "Parent";
        } : PhysicalAlliedDamage
    ];
}

The use of packages is optional, full names can be used instead:

Attacks.GenjiReflect : Attacks.BaseExplosion
{
    statModifiers = 
    [
        {
            refObject = "Parent";
        } : AttackModifier.PhysicalAlliedDamage
    ];
}

Groups

Groups can act as a namespace for flats or define records:

// Create flat named MyGroup.value
MyGroup
{
    int value = 1;
}

// Create record named MyRecord of type Vehicle
MyRecord : Vehicle
{
    type = "Vehicle.Car";
    model = "Vehicle.Turbo";
}

Flats

Flats can be scalars, structures or arrays.

Editing flats

To assign a value to an existing flat, you need the group name and flat name:

PreventionSystem.setup
{
    totalEntitiesLimit = 40;
}

Creating flats

To define a new flat, you must add type declaration:

MySystem
{
    CName triggerState = "Combat";
    float[] probabilities = [0.2, 0.5, 0.3];
}

This will create two flats MySystem.triggerState and MySystem.probabilities.

Records

Editing records

To change the properties of an existing record, you must use the record name:

Vehicle.v_standard2_archer_bandit_player
{
    trafficSuspension = "Vehicle.TrafficSuspension_Sport";
    enableDestruction = false;
}

Creating records

To create a record, you must add a record type declaration:

Items.MyClothingItem : Clothing
{
    entityName = "my_item";
    appearanceName = "my_item_";
    displayName = "My-Item-Name";
}

Unspecified properties will be filled with default values.

The type name can be in any of the following forms:

Form Value Comment
Base name Clothing Used in WolvenKit and REDmod.
Script name Clothing_Record Used in redscript.
Native name gamedataClothing_Record Used in CET and RED4ext.

Cloning records

To clone a record, you must use the other record name instead of type:

Items.MyClothingItem : Items.GenericFaceClothing
{
    entityName = "my_item";
    appearanceName = "my_item_";
    displayName = "My-Item-Name";
}

Inline records

The records can be created inline when assigning foreign keys:

Vehicle.v_my_archer_quartz : Vehicle.v_standard2_archer_quartz_player
{
    // This will crete new record of VehicleUIData type
    vehicleUIData = 
    {
        driveLayout = "LocKey#45371";
        horsepower = 250.0;
    };
}

Usually you don't need to specify the type of the inline record, because it's already known from the parent definition. But you have to use it for polymorphic relationships:

Items.MyWeapon : WeaponItem
{
    statModifiers = 
    [
        {
            statType = "BaseStats.BaseDamage";
            modifierType = "Additive";
            value = 50.0;
        } : ConstantStatModifier,
        {
            statType = "BaseStats.BaseDamage";
            modifierType = "Additive";
            min = 0.0;
            max = 10.0;
        } : RandomStatModifier,
    ];
}

Scalars

Integer

Tweak Type: int Native Type: Int32

Examples
{
    int a = 220;
    int b = -1;
}

Float

Tweak Type: float Native Type: Float

Examples
{
    float a = 50.0;
    float b = -7.25f; // optional "f" suffix 
    float c = 123;    // no decimal part 
}

Boolean

Tweak Type: bool Native Type: Bool

Examples
{
    bool a = true;
    bool b = false;
}

String

Tweak Type: string Native Type: String

Examples
{
    string a = "This is a string";
    string b = "Escape seque\nces a\ren't suppor\ted";
}

CName

Tweak Type: CName Native Type: CName

Examples
{
    CName a = "Thing";
    CName b = "None"; // Special value to define empty name
    CName c = "";     // Equals to "None"
}

Localization Key

Tweak Type: LocKey Native Type: gamedataLocKeyWrapper

Examples
{
    LocKey a = "LocKey#13245";      // Using primary key
    LocKey b = "LocKey#My-Mod-Key"; // Using secondary key defined with ArchiveXL
}

Resource Reference

Tweak Type: ResRef Native Type: raRef:CResource

Examples
{
    ResRef a = "base\gameplay\gui\world\lcd_screens\lcdscreen_1x3.inkwidget";
    ResRef b = "base/gameplay/gui/fullscreen/photo_mode/frame/v_frame.inkatlas";
    ResRef c = "";
}

Resource paths
The path can use backslashes \, double backslashes \\, or slashes /.
For example, all of these paths are valid and equal:

  • path\to\resource.ext
  • path\\to\\resource.ext
  • path/to/resource.ext

Foreign Key

Tweak Type: fk<Record> Native Type: TweakDBID

Examples
{
    fk<Stat> a = "BaseStats.Armor";
    fk<WeaponItem> b = "Items.Preset_Overture_Default";
    fk<IPrereq> c = "";
}

Structures

Quaternion

Tweak Type: Quaternion Native Type: Quaternion

Examples
{
    Quaternion a = (0.0, 0.0, 0.923880, 0.382683);
    Quaternion b = (0.f, 0.f, 1.f, -0.f);
}

Euler Angles

Tweak Type: EulerAngles Native Type: EulerAngles

Examples
{
    EulerAngles a = (0.0, 135.0, 0.0);
    EulerAngles b = (0.f, -45.f, 45.f);
}

Vector3

Tweak Type: Vector3 Native Type: Vector3

Examples
{
    Vector3 a = (0.113662, 2.880340, 0.000001);
    Vector3 b = (0, 0, 0);
}

Vector2

Tweak Type: Vector2 Native Type: Vector2

Examples
{
    Vector2 a = (15, 7.5);
    Vector2 b = (10000, 10000);
}

Arrays

Element types

Arrays are homogeneous and can be of any scalar or structure type.

Examples
{
    int[] intArray =
    [
        1, 3,
        5, 7, // trailing comma is allowed
    ];

    string[] stringArray = ["Str1", "Str2", "Str3"];

    Vector3[] vecArray = 
    [
        (0.0, 0.0, 0.0), 
        (-0.1, 0.0, 0.7), 
    ];
}

Array operations

Arrays can be mutated instead of replaced using operators += and -=.

Items.w_silencer_01
{
    // Remove some original modifiers
    statModifiers -=
    [
        "Items.SilencerBase_inline1",
        "Items.w_silencer_01_inline0"
    ];
    
    // Add new modifiers
    statModifiers +=
    [
        {
            statType = "BaseStats.StealthHitDamageMultiplier";
            modifierType = "Additive";
            value = 3.0;
        } : ConstantStatModifier
    ];
}
⚠️ **GitHub.com Fallback** ⚠️