### Add New Item with Vendor Stock (YAML) Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt This YAML example demonstrates a complete end-to-end process for adding a new item, including record creation, icon setup, and injecting it into multiple vendor stocks using anchors for efficiency. ```yaml # r6/tweaks/MyGlasses.yaml Items.MyGlasses_01: $base: Items.GenericFaceClothing entityName: my_glasses_001 appearanceName: my_glasses_001_ displayName: My-Glasses-01-Name # ArchiveXL loc key localizedDescription: My-Glasses-01-Desc icon: atlasResourcePath: mod\my_glasses_001.inkatlas atlasPartName: icon_glasses_01 # Add to multiple vendors in one pass using anchors Vendors.wat_lch_clothingshop_01: &StockGlasses itemStock: - !append item: Items.MyGlasses_01 quantity: [ Vendors.Always_Present ] Vendors.wat_kab_clothingshop_01: *StockGlasses Vendors.wbr_jpn_clothingshop_01: *StockGlasses ``` -------------------------------- ### Vector3 Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates the initialization of Vector3 structures for 3D coordinates or directions. Values can be specified with decimals or floats. ```cpp Vector3 a = (0.113662, 2.880340, 0.000001); Vector3 b = (0, 0, 0); ``` -------------------------------- ### Localization Key Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Shows how to use LocKey for localization. It supports primary keys and secondary keys defined with ArchiveXL. ```cpp LocKey a = "LocKey#13245"; // Using primary key LocKey b = "LocKey#My-Mod-Key"; // Using secondary key defined with ArchiveXL ``` -------------------------------- ### Quaternion Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Shows how to define Quaternion values for 3D rotations. Values can be specified with decimals or floats. ```cpp Quaternion a = (0.0, 0.0, 0.923880, 0.382683); Quaternion b = (0.f, 0.f, 1.f, -0.f); ``` -------------------------------- ### String Scalar Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Provides an example of defining string variables. Note that escape sequences like newline '\n' are not supported. ```tweak Examples { string a = "This is a string"; string b = "Escape seque\nces a\ren't suppor\ted"; } ``` -------------------------------- ### CName Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates the usage of CName for string identifiers. 'None' is a special value for an empty name. ```cpp CName a = "Thing"; CName b = "None"; // Special value to define empty name CName c = ""; // Equals to "None" ``` -------------------------------- ### ScriptableTweak - Make Items Epic Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Example of a ScriptableTweak that iterates through 'Clothing' and 'WeaponItem' records, setting their quality to 'Epic' and updating the records. Note that game systems are unavailable during OnApply. ```swift public class ThisIsEpic extends ScriptableTweak { protected cb func OnApply() -> Void { for record in TweakDBInterface.GetRecords(n"Clothing") { this.MakeEpic(record); } for record in TweakDBInterface.GetRecords(n"WeaponItem") { this.MakeEpic(record); } } protected func MakeEpic(record: ref) -> Void { TweakDBManager.SetFlat(record.GetID() + t".quality", t"Quality.Epic"); TweakDBManager.UpdateRecord(record.GetID()); } } ``` -------------------------------- ### ScriptableTweak - EnableMoreSpawns Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Example of a ScriptableTweak that sets the 'totalEntitiesLimit' flat to 40. This modification occurs early in the TweakDB initialization process. ```swift public class EnableMoreSpawns extends ScriptableTweak { protected cb func OnApply() -> Void { TweakDBManager.SetFlat(t"PreventionSystem.setup.totalEntitiesLimit", 40); } } ``` -------------------------------- ### TweakDBInterface - Enumerate Records Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Example of iterating through all records of a specific type and logging their enum names. ```swift for record in TweakDBInterface.GetRecords(n"Achievement_Record") { Log(ToString((record as Achievement_Record).EnumName())); } ``` -------------------------------- ### Basic YAML Tweak Structure Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Demonstrates the top-level structure of a TweakXL YAML file, showing examples of both 'flats' and 'records'. ```yaml # Flats FreeCameraParams.baseSpeed: 10.0 timeSystem.netrunnerBreach.easeInCurve: DiveEaseIn # Record Items.Preset_Katana_Default: quality: Quality.Random mass: 20.0 ``` -------------------------------- ### Boolean Scalar Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Shows how to define boolean variables, which can only have the values 'true' or 'false'. ```tweak Examples { bool a = true; bool b = false; } ``` -------------------------------- ### Integer Scalar Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Provides an example of defining integer variables. Integers are whole numbers and can be positive or negative. ```tweak Examples { int a = 220; int b = -1; } ``` -------------------------------- ### Create New Flat with Type Declaration Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates creating new flats by providing a type declaration along with the flat name. This example creates a 'CName' flat and a 'float' array flat. ```tweak MySystem { CName triggerState = "Combat"; float[] probabilities = [0.2, 0.5, 0.3]; } ``` -------------------------------- ### Resource Reference Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Illustrates the use of ResRef for referencing game resources. Paths can use backslashes, double backslashes, or forward slashes. ```cpp 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 = ""; ``` -------------------------------- ### Vector2 Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Shows how to define Vector2 structures for 2D coordinates or vectors. Values can be specified with integers or decimals. ```cpp Vector2 a = (15, 7.5); Vector2 b = (10000, 10000); ``` -------------------------------- ### Foreign Key Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates foreign key references to other record types, such as Stats, WeaponItems, and IPrereqs. An empty string represents a null reference. ```cpp fk a = "BaseStats.Armor"; fk b = "Items.Preset_Overture_Default"; fk c = ""; ``` -------------------------------- ### Batch TweakDB Modifications Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt This example demonstrates how to use TweakDBBatch to group multiple TweakDB writes into a single atomic commit. Operations are queued after starting a batch and then committed. ```swift // r6/scripts/batch_example.reds public class BatchExample extends ScriptableTweak { protected cb func OnApply() -> Void { let batch = TweakDBManager.StartBatch(); // Queue operations — nothing is written until Commit() batch.CloneRecord(n"Items.MyKatana", t"Items.Preset_Katana_Default"); batch.SetFlat(t"Items.MyKatana.mass", ToVariant(3.0f)); batch.SetFlat(t"Items.MyKatana.quality", ToVariant(t"Quality.Legendary")); batch.UpdateRecord(t"Items.MyKatana"); batch.CreateRecord(n"Items.MyPistol", n"WeaponItem_Record"); batch.SetFlat(t"Items.MyPistol.mass", ToVariant(1.5f)); batch.UpdateRecord(t"Items.MyPistol"); // Write all changes atomically batch.Commit(); } } ``` -------------------------------- ### Create New Record Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Illustrates creating a new record by specifying its type. This example defines a new clothing item record with properties like 'entityName', 'appearanceName', and 'displayName'. ```tweak Items.MyClothingItem : Clothing { entityName = "my_item"; appearanceName = "my_item_"; displayName = "My-Item-Name"; } ``` -------------------------------- ### Euler Angles Examples Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Illustrates the definition of Euler Angles for 3D rotations. Values can be specified with decimals or floats. ```cpp EulerAngles a = (0.0, 135.0, 0.0); EulerAngles b = (0.f, -45.f, 45.f); ``` -------------------------------- ### TweakDBInterface - Check Flat Existence and Type Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Demonstrates checking if a TweakDB flat exists and retrieving its type name using GetFlat, IsDefined, and VariantTypeName. ```swift let flat = TweakDBInterface.GetFlat(t"PreventionSystem.setup.totalEntitiesLimit"); Log(ToString(IsDefined(flat))); Log(ToString(VariantTypeName(flat))); ``` -------------------------------- ### Array Element Types Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Provides examples of different array types, including integers, strings, and Vector3 arrays. Trailing commas are permitted in array definitions. ```cpp 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), ]; ``` -------------------------------- ### Float Scalar Example Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates defining float variables, which can have decimal values. An optional 'f' suffix can be used, and integers without a decimal part are also valid floats. ```tweak Examples { float a = 50.0; float b = -7.25f; // optional "f" suffix float c = 123; // no decimal part } ``` -------------------------------- ### TweakDB Data Model Examples Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Illustrates TweakDB data types, record structure, and TweakDBID hashing. TweakDBID can be explicitly defined using Redscript or CET syntax, or implicitly when the type is known. ```plaintext Flat types: Int32, Float, Bool, String, CName, TweakDBID, gamedataLocKeyWrapper, raRef:CResource, Quaternion, EulerAngles, Vector3, Vector2, Color, and arrays of any of the above. Record = named group of flats (properties). e.g. Items.Preset_Katana_Default, Vehicle.v_standard2_archer_quartz_player A TweakDBID is a hash of the full flat/record name: t"Items.Preset_Katana_Default" (Redscript explicit) TweakDBID("Items.Preset_Katana_Default") (CET explicit) Items.Preset_Katana_Default (implicit, when type is known) ``` -------------------------------- ### TweakDBInterface - Accessing TweakDB Records and Flats Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Extends TweakDBInterface with functions to get records, flats, and their counts. Use these for reading TweakDB data. ```swift class TweakDBInterface { static func GetFlat(path: TweakDBID) -> Variant static func GetRecord(path: TweakDBID) -> ref static func GetRecords(type: CName) -> array> static func GetRecordCount(type: CName) -> Uint32 static func GetRecordByIndex(type: CName, index: Uint32) -> ref static func GetRecords(keys: array) -> array> static func GetRecordIDs(type: CName) -> array } ``` -------------------------------- ### Edit Existing Record Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Shows how to modify properties of an existing record by specifying the record name. This example changes 'trafficSuspension' and 'enableDestruction' for a vehicle record. ```tweak Vehicle.v_standard2_archer_bandit_player { trafficSuspension = "Vehicle.TrafficSuspension_Sport"; enableDestruction = false; } ``` -------------------------------- ### Use Full Package Names Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates using fully qualified names for groups and records when packages are not explicitly defined or imported. This ensures clarity and avoids naming conflicts. ```tweak Attacks.GenjiReflect : Attacks.BaseExplosion { statModifiers = [ { refObject = "Parent"; } : AttackModifier.PhysicalAlliedDamage ]; } ``` -------------------------------- ### Using Inline Syntax for Records Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Demonstrates combining the creation of a vehicle and its associated UI data into a single definition using inline syntax. ```yaml Vehicle.v_my_archer_quartz: $base: Vehicle.v_standard2_archer_quartz_player vehicleUIData: driveLayout: LocKey#45371 horsepower: 250.0 info: LocKey#53579 mass: 1070.0 productionYear: 2041-2077 ``` -------------------------------- ### Create Flat and Record Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Shows how to create a simple flat named 'MyGroup.value' with an integer type and a record named 'MyRecord' of type 'Vehicle' with specified properties. ```tweak // Create flat named MyGroup.value MyGroup { int value = 1; } // Create record named MyRecord of type Vehicle MyRecord : Vehicle { type = "Vehicle.Car"; model = "Vehicle.Turbo"; } ``` -------------------------------- ### YAML Anchors, Aliases, and Templates Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Illustrates using YAML anchors (`&`) and aliases (`*`) to avoid repetition, and templates with `$instances` to generate multiple records from a single parameterized definition. ```yaml # Anchors & aliases: add item to multiple vendors Vendors.wat_lch_clothingshop_01: &AddMyItem itemStock: - !append item: Items.MyClothingItem quantity: [ Vendors.Always_Present ] Vendors.wat_kab_clothingshop_01: *AddMyItem Vendors.wat_nid_clothingshop_01: *AddMyItem Vendors.wbr_jpn_clothingshop_01: *AddMyItem --- # Templates: generate one record per color variant Items.my_item_$(color): $instances: - { color: black, icon: slot_1 } - { color: white, icon: slot_2 } - { color: red, icon: slot_3 } $base: Items.GenericHeadClothing entityName: my_item appearanceName: my_item!$(color) displayName: my_item_$(color)_name icon: atlasResourcePath: mod\icons\my_item.inkatlas atlasPartName: $(icon) # Generates: Items.my_item_black, Items.my_item_white, Items.my_item_red ``` -------------------------------- ### Execute Scriptable Tweak by Class Name Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Modder-Tools Use this command to execute a specific scriptable tweak by providing its class name as a string argument. Ensure the class name is accurate. ```lua TweakXL.Execute("NoCyberwareEquipReqs") ``` -------------------------------- ### Creating New Flats with Explicit Types Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Illustrates creating new flats by using a non-existent name and an explicit value format to define the type. ```yaml MySystem.triggerState: n"Combat" MySystem.probabilities: [ 0.2, 0.5, 0.3 ] ``` -------------------------------- ### TweakXL Console Commands Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Modder-Tools Provides functions to reload tweaks, execute scriptable tweaks, and check the mod version. ```APIDOC ## TweakXL.Reload() ### Description Hot reload all tweaks from `r6/tweaks` and execute scriptable tweaks. ### Method `TweakXL.Reload()` ``` ```APIDOC ## TweakXL.ExecuteAll() ### Description Execute scriptable tweaks only. ### Method `TweakXL.ExecuteAll()` ``` ```APIDOC ## TweakXL.Execute(class) ### Description Executes a scriptable tweak by class name. ### Method `TweakXL.Execute(class)` ### Parameters #### Path Parameters - **class** (string) - Required - The name of the scriptable tweak class to execute. ### Request Example ```lua TweakXL.Execute("NoCyberwareEquipReqs") ``` ``` ```APIDOC ## TweakXL.Version() ### Description Returns the mod version. ### Method `TweakXL.Version()` ### Response Example ```lua print(TweakXL.Version()) ``` ``` -------------------------------- ### Standard UIIcon and Item Definition Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks This shows the traditional method of defining an icon and then referencing it in an item. The icon must be prefixed with 'UIIcon.' and the item's iconPath must use the part after the prefix. ```yaml UIIcon.MyItemIcon: atlasResourcePath: mod\icons.inkatlas atlasPartName: icon_my_item Items.MyItem: # Must use only the part after UIIcon. prefix iconPath: MyItemIcon ``` -------------------------------- ### Creating and Associating Inline Records Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Shows how to create a vehicle record and associate UI data by defining the UI data record separately. ```yaml # Create UI data Vehicle.v_my_archer_quartz_data: $type: VehicleUIData driveLayout: LocKey#45371 horsepower: 250.0 info: LocKey#53579 mass: 1070.0 productionYear: 2041-2077 # Create vehicle and associate UI data Vehicle.v_my_archer_quartz: $base: Vehicle.v_standard2_archer_quartz_player vehicleUIData: Vehicle.v_my_archer_quartz_data ``` -------------------------------- ### Editing and Creating Records with RED Tweaks Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Use the .tweak format to modify existing records or create new ones by cloning. Ensure definitions are placed in `r6/tweaks/` for merging. ```tweak // r6/tweaks/my_mod.tweak package MyMod using Vehicle, Items // Edit an existing record Vehicle.v_standard2_archer_bandit_player { trafficSuspension = "Vehicle.TrafficSuspension_Sport"; enableDestruction = false; } // Create a new record (clone syntax) Items.MyClothingItem : Items.GenericFaceClothing { entityName = "my_item"; appearanceName = "my_item_"; displayName = "My-Item-Name"; } // Create new flats in a group MySystem { CName triggerState = "Combat"; float[] probabilities = [0.2, 0.5, 0.3]; } ``` -------------------------------- ### Add New Item with Vendor Stock (Template) Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Examples This YAML snippet defines a new item and makes it available for purchase from a specific vendor. Ensure the item and vendor names are correctly referenced. ```yaml Items.MyGlasses_01: $base: Items.GenericFaceClothing entityName: my_glasses_001 appearanceName: my_glasses_001_ displayName: My-Glasses-01-Name localizedDescription: My-Glasses-01-Desc icon: atlasResourcePath: mod\my_glasses_001.inkatlas atlasPartName: icon_glasses_01 Vendors.wat_lch_clothingshop_01: itemStock: - !append item: Items.MyGlasses_01 quantity: [ Vendors.Always_Present ] ``` -------------------------------- ### Using Templates for Multiple Instances in YAML Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Define a template using `$instances` to create multiple copies of a definition with specified data substitutions. Placeholders like `$(color)` and `$(icon)` are replaced by values from the `$instances` array. ```yaml Items.my_item_$(color): $instances: - { color: black, icon: slot_1 } - { color: white, icon: slot_2 } - { color: red, icon: slot_3 } $base: Items.GenericHeadClothing entityName: my_item appearanceName: my_item!$(color) displayName: my_item_$(color)_name icon: atlasResourcePath: mod\icons\my_item.inkatlas atlasPartName: $(icon) ``` -------------------------------- ### Clone Record Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates cloning an existing record by using another record's name as the base type. This allows for creating a new record with inherited properties. ```tweak Items.MyClothingItem : Items.GenericFaceClothing { entityName = "my_item"; appearanceName = "my_item_"; displayName = "My-Item-Name"; } ``` -------------------------------- ### TweakXL Console Commands Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt These Lua commands are accessible via Cyber Engine Tweaks (CET) for live development. They allow reloading tweaks, re-executing scriptable tweaks, executing specific tweaks by class name, and checking the TweakXL version. ```lua -- Reload all tweaks from r6/tweaks/ AND re-execute all scriptable tweaks TweakXL.Reload() -- Re-execute all scriptable tweaks without re-importing YAML/tweak files TweakXL.ExecuteAll() -- Execute a single scriptable tweak by class name TweakXL.Execute("NoCyberwareEquipReqs") TweakXL.Execute("ThisIsEpic") -- Return the running TweakXL version string print(TweakXL.Version()) -- Output: "1.x.x" ``` -------------------------------- ### Cloning Existing Records Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Demonstrates cloning an existing record by using the '$base' attribute to specify the source record name. ```yaml Items.MyClothingItem: $base: Items.GenericFaceClothing entityName: my_item appearanceName: my_item_ displayName: My-Item-Name ``` -------------------------------- ### Define Package and Import Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Defines a package named 'Attacks' and imports 'AttackModifier' for use within the package. This allows for namespaced definitions and code reuse. ```tweak package Attacks using AttackModifier GenjiReflect : BaseExplosion { statModifiers = [ { refObject = "Parent"; } : PhysicalAlliedDamage ]; } ``` -------------------------------- ### Inline Records with Base Cloning Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Shows how to use the '$base' attribute for inline records, allowing for cloning and modification of nested structures. ```yaml Vehicle.v_my_archer_quartz: $base: Vehicle.v_standard2_archer_quartz_player vehicleUIData: $base: Vehicle.v_standard2_archer_quartz_gt_inline0 horsepower: 250.0 ``` -------------------------------- ### Inline Record Creation for Foreign Keys Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Shows how to create a record inline when assigning a foreign key. This is useful for defining nested structures like 'vehicleUIData' directly within the parent record. ```tweak 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; }; } ``` -------------------------------- ### YAML Array Operations Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Demonstrates array mutation operators for adding, prepending, removing, or merging elements in arrays, crucial for multi-mod compatibility without replacing entire lists. ```yaml # !append / !prepend — add element Vehicle.vehicle_list.list: - !prepend Vehicle.v_012_corpo_suv - !append Vehicle.v_standard25_villefort_columbus_corpo # !append-once / !prepend-once — add only if not already present Vehicle.vehicle_list.list: - !append-once Vehicle.v_standard2_villefort_cortes_police - !append-once Vehicle.v_standard2_archer_hella_police # !append-from / !prepend-from — merge another array, discarding duplicates Items.HandgunPossibleScopesList: itemPartList: - !append-from Items.RiflePossibleScopesList.itemPartList - !append-from Items.SniperPossibleScopesList.itemPartList # !remove — delete a specific element Vehicle.vehicle_list.list: - !remove Vehicle.v_sport1_herrera_outlaw_player # Combining remove + append to replace a stat modifier Items.w_silencer_01: statModifiers: - !remove Items.w_silencer_01_inline0 - !append $type: ConstantStatModifier statType: BaseStats.StealthHitDamageMultiplier modifierType: Additive value: 3.0 ``` -------------------------------- ### YAML Inheritance and Array Chaining Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Explains how cloned records inherit parent array contents and how array mutation tags applied on derived records layer on top, with these layers also being inheritable. ```yaml # Base weapon clone: add iconic modifier Items.Weapon_A: $base: Items.Base_Ashura statModifiers: - !append Quality.IconicItem # Inherit Weapon_A, add recoil modifier on top Items.Weapon_B: $base: Items.Weapon_A statModifiers: - !append $type: ConstantStatModifier statType: BaseStats.RecoilRecoveryTime modifierType: Additive value: -0.15 # Inherit Weapon_B but strip the iconic modifier from Weapon_A Items.Weapon_C: $base: Items.Weapon_B statModifiers: - !remove Quality.IconicItem ``` -------------------------------- ### Array Operations (Add/Remove) Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Demonstrates modifying arrays in place using `+=` to add elements and `-=` to remove elements, shown in the context of item stat modifiers. ```cpp 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 ]; } ``` -------------------------------- ### ScriptableTweak - Base Class Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Abstract class for scriptable tweaks that allows modification of TweakDB at an early stage after initialization. The OnApply callback is invoked during TweakDB loading. ```swift abstract class ScriptableTweak { protected cb func OnApply() -> Void } ``` -------------------------------- ### Using Anchors and Aliases for Reusable Definitions in YAML Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Anchors (`&`) define reusable blocks of YAML, and aliases (`*`) reference them. This avoids copy-pasting common definitions, such as item additions for vendors. ```yaml # Define item addition for one vendor Vendors.wat_lch_clothingshop_01: &AddToVendor itemStock: - !append item: Items.MyClothing quantity: [ Vendors.IsPresent ] # Repeat for other vendors Vendors.wat_kab_clothingshop_01: *AddToVendor Vendors.wat_nid_clothingshop_01: *AddToVendor Vendors.wbr_jpn_clothingshop_01: *AddToVendor ``` -------------------------------- ### Print TweakXL Mod Version Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Modder-Tools Retrieve and print the current version of the TweakXL mod. This is useful for debugging and ensuring compatibility. ```lua print(TweakXL.Version()) ``` -------------------------------- ### YAML Tweaks - Creating New Records Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Shows how to create new records in TweakDB using YAML. A new record is defined by using a non-existent name, and the `$type` attribute specifies the record's type. ```yaml # r6/tweaks/my_item.yaml Items.MyClothingItem: $type: Clothing # base name — also accepted: Clothing_Record, gamedataClothing_Record entityName: my_item appearanceName: my_item_ displayName: My-Item-Name # All unspecified properties receive default values automatically ``` -------------------------------- ### ScriptableTweak - Early Data Modification Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Allows modification of TweakDB data at a very early stage, right after TweakDB initialization, via the `OnApply` callback. ```APIDOC ## ScriptableTweak ### Description Scriptable tweaks allow modification of TweakDB at a very early stage, right after TweakDB initialization. ### Abstract Class ```swift abstract class ScriptableTweak { protected cb func OnApply() -> Void } ``` ### Usage Define your own class derived from `ScriptableTweak`. The loader instantiates all scriptable tweaks during TweakDB initialization and calls their `OnApply` callbacks. ### Example #1: Setting a flat value ```swift public class EnableMoreSpawns extends ScriptableTweak { protected cb func OnApply() -> Void { TweakDBManager.SetFlat(t"PreventionSystem.setup.totalEntitiesLimit", 40); } } ``` ### Example #2: Modifying multiple records ```swift public class ThisIsEpic extends ScriptableTweak { protected cb func OnApply() -> Void { for record in TweakDBInterface.GetRecords(n"Clothing") { this.MakeEpic(record); } for record in TweakDBInterface.GetRecords(n"WeaponItem") { this.MakeEpic(record); } } protected func MakeEpic(record: ref) -> Void { TweakDBManager.SetFlat(record.GetID() + t".quality", t"Quality.Epic"); TweakDBManager.UpdateRecord(record.GetID()); } } ``` ### Lifecycle Note `GameInstance` is not ready during the `OnApply` callback, making all game systems unavailable. ``` -------------------------------- ### Append and Prepend to Arrays in YAML Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Use `!prepend` and `!append` to add elements to the beginning or end of an array, respectively. These operations modify existing arrays in place. ```yaml Vehicle.vehicle_list.list: - !prepend Vehicle.v_012_corpo_suv - !append Vehicle.v_standard25_villefort_columbus_corpo ``` -------------------------------- ### Implicit CName Definition Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Use the implicit format for simplicity when the context clearly defines the expected type. This format relies on the system to infer the type, which can lead to ambiguity if not used carefully. ```yaml Example.variable: Value ``` -------------------------------- ### Explicit Localization Key Formats Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Define localization keys using various explicit formats, including Redscript style 'l"..."', CET style 'LocKey(...)' or 'LocKey#...', and REDengine style 'LocKey#...'. These formats specify whether a primary or secondary key is used. ```yaml l"Secondary-Loc-Key" ``` ```yaml LocKey("Secondary-Loc-Key") ``` ```yaml LocKey(12345) ``` ```yaml LocKey#Secondary-Loc-Key ``` ```yaml LocKey#12345 ``` -------------------------------- ### Editing Existing Flats Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Shows how to assign a new value to an existing flat by specifying its name and a compatible value. ```yaml PreventionSystem.setup.totalEntitiesLimit: 40 ``` -------------------------------- ### YAML Tweaks - Editing Existing Flats and Records Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Demonstrates how to modify existing TweakDB data using YAML files. Flats are edited by their full name, and records are modified by listing property assignments under the record name. ```yaml # r6/tweaks/tweaks.yaml # Edit a single flat directly PreventionSystem.setup.totalEntitiesLimit: 40 PreventionSystem.vehicle_spawn_setup.vehicleDespawnDistance: 75.0 # Edit multiple properties of a record Vehicle.v_standard2_archer_bandit_player: trafficSuspension: Vehicle.TrafficSuspension_Sport enableDestruction: false # Edit a single property using full path syntax Items.ReversePowerInductor.mass: 1.5 ``` -------------------------------- ### Creating New Records with Type Specification Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Illustrates creating a new record by using a non-existent name and specifying its type using the '$type' attribute. ```yaml Items.MyClothingItem: $type: Clothing entityName: my_item appearanceName: my_item_ displayName: My-Item-Name ``` -------------------------------- ### YAML Structure Types Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Shows how to define structure types like Quaternion, EulerAngles, Vector3, Vector2, and Color, supporting both inline and multiline formats, with implicit defaults for omitted fields. ```yaml # Quaternion MyMod.rotation: { i: 0.0, j: 0.0, k: -0.9, r: 0.4 } # EulerAngles MyMod.angles: { roll: 30.0, pitch: 90.0, yaw: 0.0 } MyMod.angles: { yaw: 150.0 } # implicit: omitted fields use defaults # Vector3 MyMod.position: { x: 0.5, y: -0.8, z: 0.0 } # Vector2 MyMod.uv: { x: 20.0, y: 40.0 } # Color (Uint8 fields) MyMod.tint: { red: 51, green: 102, blue: 0, alpha: 255 } MyMod.tint: { red: 255, alpha: 127 } # implicit: unspecified channels = 0 ``` -------------------------------- ### Define Array in One Line (YAML) Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Use brackets for a compact, single-line definition of an array. ```yaml Example.array: [ First, Second, Third ] ``` -------------------------------- ### TweakXL Inline Icon Definition Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks TweakXL's inline syntax allows defining the icon directly within the item. TweakXL automatically creates the necessary UIIcon record and sets the iconPath. ```yaml Items.MyItem: icon: atlasResourcePath: mod\icons.inkatlas atlasPartName: icon_my_item ``` -------------------------------- ### Modifying TweakDB from Scripts with TweakDBManager Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Use TweakDBManager to write flats, create, clone, and update records from scripts. Call `UpdateRecord()` to propagate changes to live instances. ```swift // r6/scripts/my_manager_example.reds // Set a flat by TweakDBID (changes visible as hash in CET) TweakDBManager.SetFlat(t"PreventionSystem.setup.totalEntitiesLimit", ToVariant(40)); // Set a flat by CName (registers name so CET shows human-readable label) TweakDBManager.SetFlat(n"PreventionSystem.setup.totalEntitiesLimit", ToVariant(40)); // Create a brand-new record TweakDBManager.CreateRecord(n"Items.MyNewRecord", n"Clothing_Record"); // Clone an existing record TweakDBManager.CloneRecord(n"Items.MyKatana", t"Items.Preset_Katana_Default"); TweakDBManager.SetFlat(t"Items.MyKatana.mass", ToVariant(5.0f)); TweakDBManager.UpdateRecord(t"Items.MyKatana"); // propagate to live instances // RegisterName makes any existing TweakDBID visible by name in CET TweakDBManager.RegisterName(n"Items.MyKatana"); ``` -------------------------------- ### Edit Existing Flat Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Illustrates how to modify an existing flat by specifying its group and flat name. This is used to change properties of predefined game elements. ```tweak PreventionSystem.setup { totalEntitiesLimit = 40; } ``` -------------------------------- ### Define Structure in One Line (YAML) Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Use curly braces for a compact, single-line definition of a structure when the type is known. ```yaml Example.struct: { foo: 1, bar: 2 } ``` -------------------------------- ### Reading TweakDB from Scripts with TweakDBInterface Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Query TweakDB flats and records at runtime using native methods provided by TweakDBInterface. Ensure correct types and IDs are used for querying. ```swift // r6/scripts/my_mod.reds // Get a single flat value and inspect it let flat = TweakDBInterface.GetFlat(t"PreventionSystem.setup.totalEntitiesLimit"); Log(ToString(IsDefined(flat))); // "true" Log(ToString(VariantTypeName(flat))); // "Int32" // Get a single record let record = TweakDBInterface.GetRecord(t"Items.Preset_Katana_Default"); let item = record as WeaponItem_Record; Log(ToString(item.Mass())); // Enumerate all records of a given type for record in TweakDBInterface.GetRecords(n"Achievement_Record") { Log(ToString((record as Achievement_Record).EnumName())); } // Get record count and access by index let count = TweakDBInterface.GetRecordCount(n"Clothing"); Log(ToString(count)); let first = TweakDBInterface.GetRecordByIndex(n"Clothing", 0u); // Batch-retrieve records from a list of IDs let ids: array = TweakDBInterface.GetRecordIDs(n"WeaponItem"); let records = TweakDBInterface.GetRecords(ids); ``` -------------------------------- ### YAML Tweaks - Cloning Records Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Illustrates how to clone existing records to create new ones, which is preferred for complex items like weapons and vehicles. The `$base` attribute copies properties from the source record, and only specified properties are overridden. ```yaml # r6/tweaks/my_glasses.yaml Items.MyGlasses_01: $base: Items.GenericFaceClothing # clone source record entityName: my_glasses_001 appearanceName: my_glasses_001_ displayName: My-Glasses-01-Name localizedDescription: My-Glasses-01-Desc icon: # TweakXL magic: creates UIIcon record automatically atlasResourcePath: mod\my_glasses_001.inkatlas atlasPartName: icon_glasses_01 ``` -------------------------------- ### Editing Existing Records Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Demonstrates how to modify properties of an existing record by referencing its name and assigning new values to its properties. ```yaml Vehicle.v_standard2_archer_bandit_player: trafficSuspension: Vehicle.TrafficSuspension_Sport enableDestruction: false ``` -------------------------------- ### Explicit CName Formats Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Define CName values using specific formats like Redscript style 'n"Thing"' or CET style 'CName("Thing")'. 'None' is a special explicit value for an empty name. ```yaml n"Thing" ``` ```yaml CName("Thing") ``` ```yaml None ``` -------------------------------- ### Define Quaternion (YAML) Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Explicitly define a Quaternion with all its components (i, j, k, r). Implicit definitions can omit fields. ```yaml { i: 0.0, j: 0.0, k: -0.9, r: 0.4 } ``` ```yaml { k: 0.1, r: 0.2 } ``` -------------------------------- ### Make Clothing and Weapon Items Epic Quality Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt This script sets the quality of all clothing and weapon items to Epic. It iterates through Clothing and WeaponItem records and applies the change. ```swift // Make every clothing and weapon item Epic quality public class ThisIsEpic extends ScriptableTweak { protected cb func OnApply() -> Void { for record in TweakDBInterface.GetRecords(n"Clothing") { this.MakeEpic(record); } for record in TweakDBInterface.GetRecords(n"WeaponItem") { this.MakeEpic(record); } } protected func MakeEpic(record: ref) -> Void { TweakDBManager.SetFlat(record.GetID() + t".quality", ToVariant(t"Quality.Epic")); TweakDBManager.UpdateRecord(record.GetID()); } } ``` -------------------------------- ### Inline Records with Polymorphic Relationships Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/RED-Tweaks Illustrates using inline records for polymorphic relationships, such as defining different types of stat modifiers within an array. This requires specifying the type of the inline record. ```tweak 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, ]; } ``` -------------------------------- ### TweakDBManager - Human Readable IDs Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Provides alternative functions in `TweakDBManager` that accept `CName` instead of `TweakDBID` for human-readable IDs, recognized by CET TweakDB Editor. ```APIDOC ## TweakDBManager with Human Readable IDs ### Description `TweakDBManager` provides alternative functions that take `CName` instead of `TweakDBID` as the first argument, allowing for human-readable IDs recognized by CET TweakDB Editor. ### Methods - `static func SetFlat(name: CName, value: Variant) -> Bool` - `static func CreateRecord(name: CName, type: CName) -> Bool` - `static func CloneRecord(name: CName, base: TweakDBID) -> Bool` ### Note Using the `CName` version registers the name, enabling CET recognition. Using the `TweakDBID` version results in flats and records being seen only as hashes. ``` -------------------------------- ### Inline Records for Polymorphic Relationships Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Illustrates using '$type' for inline records in polymorphic relationships, such as defining different stat modifiers for a weapon. ```yaml Items.MyWeapon: $type: WeaponItem statModifiers: - $type: ConstantStatModifier statType: BaseStats.BaseDamage value: 50.0 - $type: RandomStatModifier statType: BaseStats.BaseDamage min: 0.0 max: 10.0 ``` -------------------------------- ### Append Unique Elements to Arrays in YAML Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Use `!append-once` and `!prepend-once` to add elements to an array only if they do not already exist. This prevents duplicate entries. ```yaml Vehicle.vehicle_list.list: - !append-once Vehicle.v_standard2_villefort_cortes_police ``` -------------------------------- ### YAML Tweaks - Inline Records Source: https://context7.com/psiberx/cp2077-tweak-xl/llms.txt Demonstrates defining related records inline within a parent record. The type is usually inferred, but `$type` must be used for polymorphic relationships. TweakXL can automatically create related records like UIIcons. ```yaml # r6/tweaks/my_vehicle.yaml Vehicle.v_my_archer_quartz: $base: Vehicle.v_standard2_archer_quartz_player vehicleUIData: # inline VehicleUIData record (type inferred) $base: Vehicle.v_standard2_archer_quartz_gt_inline0 horsepower: 250.0 # Polymorphic inline records require explicit $type Items.MyWeapon: $type: WeaponItem statModifiers: - $type: ConstantStatModifier statType: BaseStats.BaseDamage value: 50.0 - $type: RandomStatModifier statType: BaseStats.BaseDamage min: 0.0 max: 10.0 ``` -------------------------------- ### Implicit Localization Key Values Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Unquoted text or integers can implicitly represent localization keys when the context is known. This offers a concise way to reference keys. ```yaml Secondary-Loc-Key ``` ```yaml 12345 ``` -------------------------------- ### Explicit String Formats Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Define strings using double quotes. Escaping is required for special characters like backslashes within quoted strings. ```yaml "This is a string" ``` ```yaml "Quoted \ backslash" ``` -------------------------------- ### Merge Arrays from Another Source in YAML Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/YAML-Tweaks Use `!append-from` and `!prepend-from` to merge all elements from another array into the target array, automatically discarding duplicates. The source can be any flat or record property. ```yaml Items.RiflePossibleScopesList.itemPartList: - !append-from Items.SniperPossibleScopesList.itemPartList ``` -------------------------------- ### TweakDBManager - UpdateRecord Usage Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions After modifying record properties with SetFlat, UpdateRecord must be called to propagate changes to existing instances. ```swift TweakDBManager.UpdateRecord(record.GetID()); ``` -------------------------------- ### TweakDBManager - Human Readable IDs Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Provides overloaded functions in TweakDBManager that accept CName instead of TweakDBID for human-readable IDs. This allows CET TweakDB Editor to display names instead of hashes. ```swift class TweakDBManager { static func SetFlat(name: CName, value: Variant) -> Bool static func CreateRecord(name: CName, type: CName) -> Bool static func CloneRecord(name: CName, base: TweakDBID) -> Bool } ``` -------------------------------- ### TweakDBInterface - Data Access Source: https://github.com/psiberx/cp2077-tweak-xl/wiki/Script-Extensions Provides functions to access TweakDB records and flats. These methods allow reading data from the TweakDB. ```APIDOC ## TweakDBInterface ### Description Extends `TweakDBInterface` with additional functions for accessing records and flats. ### Methods - `static func GetFlat(path: TweakDBID) -> Variant` - `static func GetRecord(path: TweakDBID) -> ref` - `static func GetRecords(type: CName) -> array>` - `static func GetRecordCount(type: CName) -> Uint32` - `static func GetRecordByIndex(type: CName, index: Uint32) -> ref` - `static func GetRecords(keys: array) -> array>` - `static func GetRecordIDs(type: CName) -> array` ### Example Usage ```swift // Enumerate all records of a specific type for record in TweakDBInterface.GetRecords(n"Achievement_Record") { Log(ToString((record as Achievement_Record).EnumName())); } // Check if a flat exists and get its type name let flat = TweakDBInterface.GetFlat(t"PreventionSystem.setup.totalEntitiesLimit"); Log(ToString(IsDefined(flat))); Log(ToString(VariantTypeName(flat))); ``` ```