REDNODE / DOCS

TweakDB API

Status: planned, agreed with the user on 2026-10-13 (“We need to do it”). Phases T1 to T3, right after W2’s in-game test and before overlay phase O7 Display. The user chose the recommended answers below on 2026-10-13: reads in the plugin, writes through TweakXL, undo per package.

TweakDB is the game’s database of tuning data: items, weapons, vehicles, characters, perks, status effects, UI icons. It holds records (Items.Preset_Yinglong_Default, of a type such as gamedataWeaponItem_Record) and flats, the single values inside them (Items.money.quality). Most gameplay mods change TweakDB.

What works today

Need Today Gap
Read a value api can call the game’s TweakDBInterface getters: GetFloat, GetInt, GetString, GetCName, GetForeignKey, GetVector3, their array forms and more. A record path such as "Items.money" works where a TweakDBID is expected. Unverified in game You must know each flat’s type to pick the getter, and get a default when it is missing
Read a record About 960 Get...Record functions (GetItemRecord, GetWeaponItemRecord) return record objects, typed from the game’s data No way to list the records of a type, or to ask what type a record is
Change a value or add a record Not in the base game. TweakXL, installed on the user’s PC (1.11.3), adds TweakDBManager: SetFlat, CreateRecord, CloneRecord, UpdateRecord, batches Its values are Variant, which REDnode cannot convert yet. Its functions are not in the generated types (base game only)
Read without the game running REDbridge’s README lists a tweakdb method group (records, record, flats, query) Not in REDbridge 0.5.1 yet
Static edits TweakXL’s YAML files in r6/tweaks, outside REDnode None; they stay the way to ship fixed edits

Design

import { tweakdb } from 'rednode';

// T1: read, no other mod needed
await tweakdb.get('Items.Preset_Yinglong_Default.quality');      // 'Quality.Legendary' (a TweakDBID, as its path when known)
const rec = await tweakdb.record('Items.Preset_Yinglong_Default'); // a game object, typed gamedataWeaponItem_Record
await rec.DisplayName();
await tweakdb.records('gamedataVehicle_Record');                   // every record of that type, as paths

// T2: write, needs TweakXL
await tweakdb.set('Items.Preset_Yinglong_Default.magazineCapacity', 60);
await tweakdb.clone('Items.MyYinglong', 'Items.Preset_Yinglong_Default');
await tweakdb.batch((b) => {
  b.set('Items.MyYinglong.displayName', 'LocKey#12345');
  b.set('Items.MyYinglong.quality', 'Quality.Iconic');
});
Decision Decided Why
How to read The REDnode plugin reads TweakDB itself, through the RED4ext SDK (TweakDB::GetFlatValue, GetRecord, GetRecordsByType). A flat comes with its own type, so get needs no type and converts with REDnode’s existing JSON conversion No dependency for the common case. Faster than one getter call per flat
How to write Through TweakXL, declared with "requires": { "tweakxl": ">=1.10" } (W2) TweakXL is the maintained standard: it handles record inheritance and the extra flats records need, and its edits work with every other TweakXL mod. The SDK could write too, but REDnode would copy that logic and could clash with TweakXL in players’ games, as rebuilding Codeware would have (see World API)
Undo REDnode remembers each flat’s value before a package first changes it, and puts it back when that package stops (switched off, restarted, hot reloaded) Edits made at runtime last until the game closes. Without undo, a mod’s old edits stay after the player switches it off, and hot reload stacks them
Names Paths in, paths out where known. A TweakDBID is a hash, so a value that points to another record comes back as a path only if the name is known: from REDnode’s calls, from TweakXL’s registered names, or from a names list (research below). Otherwise as "0x..." The game keeps no names at runtime
Types tweakdb.record returns the record’s generated class (gamedataWeaponItem_Record), so its methods are typed. A RecordTypes map lets records('gamedataVehicle_Record') and record<...>() check names Record classes are already in gameapi/2.31/rtti.json (signatures only)
No TweakDB data in the repository The repository keeps only types. Paths, values and names are read from the player’s game at runtime The rule in CLAUDE.md: never commit game data, TweakDB included

Phases

Phase Builds Test proves
T1 Read Plugin: tweakdb.get, tweakdb.record, tweakdb.records, tweakdb.type (a record’s type) on the game thread. tweakdb in the rednode package with TSDoc and examples. An MCP tool tweakdb for agents (REDagent can look values up while writing a mod). A sample app that shows a weapon’s record A mod reads a weapon’s flats and lists every vehicle record, with no other mod installed
T2 Write Variant conversion in the plugin (to a flat’s own type, or a type given). tweakdb.set, clone, create, update, batch through TweakXL’s TweakDBManager. Undo per package. kernel.requirements() tells the mod when TweakXL is missing. The sample changes a weapon’s magazine size and puts it back A changed value shows in game; switching the mod off restores it; hot reload does not stack edits
T3 Offline and tools When REDbridge ships its tweakdb methods: the same reads through kernel.bridge() without the game, for REDcode and REDagent. Game API reference pages for record types with notes in gameapi/notes/ REDagent answers “what fields does a vehicle record have” without the game running

Research before T1 and T2

Question How to find out
Which edits take effect at once, and which need a new object or a save reload. Items already in the inventory, spawned NPCs and vehicles likely keep values they copied Test in game during T2: change a held weapon’s magazine size, then drop and pick it up, then reload a save. Record the results in gameapi/notes/
Where to get record and flat names for IDs that come back as hashes. Candidates: TweakXL’s registered names, WolvenKit’s TweakDB names list (through REDbridge), CET’s names file Check each source’s license and size; prefer one the player already has
Thread safety. The SDK warns that creating flat values while other threads read is unsafe Reads run on the game thread, as every REDnode game call does. Writes go through TweakXL, which handles its own locking
TweakXL calls through rtti.call: static natives on TweakDBManager, TweakDBBatch objects A spike at the start of T2, before building on it

Order

Decided with the user on 2026-10-13: right after W2’s in-game test, then overlay phase O7 Display.