Creating Custom Gear
The current method of creating custom gear is incredibly annoying and tedious. A better solution will be available in the future, but for now this is the best I have 😭
The Basics
Once you have created a custom profile, you can now customise the gear as you wish.
The gear datablock is located in path_to_profile/datablocks/gear
and consists of multiple parts.
To familiarise your self with the different gear parts, I recommend reading up on the official docs for gear construction here.
Gear Parts
Guns in game are comprised of the following gear parts:
Tool
Tool Delivery
Tool Screen
Tool Targeting
Tool Payload
Tool Main
Guns
Sight
Flashlight
Front
Grip
Receiver
Mag
Stock
Melee
Melee Handle
Melee Head
Melee Neck
Melee Pommel
The datablocks for each part can be found in the path_to_profile/datablocks/gear/parts
As long as the rundown doesn't import custom parts then these datablocks can remain unchanged from vanilla, however some rundowns change the IDs of parts or add custom parts. In this case you will have to edit the corresponding datablock in the profile such that the gear parts match the corresponding datablock of the custom rundown.
The datablock format for the replay viewer is very similar to the format of datablocks in-game, thus it is fairly trivial to convert between the two.
Further more there are some gotchas for parts that have a fold animation (The revolver parts).
Animating Folding Parts - Revolver, Hel Revolver, Sawed Off Shotgun
The parts with folding animations exist under receiver.js
for Receiver parts and front.js
for Front parts. For these parts, additional properties have to be assigned, namely:
fold
- The name of the object that acts as the pivot point for the foldfoldAnim
- The animation for the part that performs the foldbaseFoldRot
- The starting quaternion rotation for the foldfoldOffsetRot
- The offset quaternion rotation for the fold
Front Parts - Front_Short_Shotgun_2
GearPartFrontDatablock.set(47, {
path: `${root}/Front_Short_Shotgun_2.glb`,
// -- Important fold properties for the part to fold during reload --
fold: "BreakPoint",
foldAnim: GearAnimDatablock.Revolver_Front_1_Reload_1,
aligns: [{
alignType: "Muzzle",
alignName: "Front_M"
}, {
alignType: "ShellEject",
alignName: "Front_SE"
}, {
alignType: "Magazine",
alignName: "Front_Mag"
}, {
alignType: "Flashlight",
alignName: "Front_Flash"
}, {
alignType: "Sight",
alignName: "Front_Sight"
}, {
alignType: "SightLook",
alignName: "Sight_align"
}, {
alignType: "RightHand",
alignName: "RightHand"
}, {
alignType: "LeftHand",
alignName: "LeftHand"
}]
});
Front Parts - Front_Revolver_1_Gripalign
GearPartFrontDatablock.set(36, {
path: `${root}/Front_Revolver_1_Gripalign.glb`,
// -- Important fold properties for the part to fold during reload --
fold: "a_RevolverFold",
baseFoldRot: {
x: 0,
y: 0,
z: 0.7071,
w: 0.7071
},
foldOffsetRot: {
x: 0,
y: 0,
z: 0.7071,
w: 0.7071
},
foldAnim: GearAnimDatablock.Revolver_Front_1_Reload_1,
aligns: [{
alignType: "Muzzle",
alignName: "Front_M"
}, {
alignType: "ShellEject",
alignName: "Front_SE"
}, {
alignType: "Magazine",
alignName: "Front_Mag"
}, {
alignType: "Flashlight",
alignName: "Front_Flash"
}, {
alignType: "LeftHand",
alignName: "LeftHand"
}, {
alignType: "SightLook",
alignName: "Sight_align"
}, {
alignType: "RightHand",
alignName: "RightHand"
}]
});
Front Parts - Front_Revolver_2
GearPartFrontDatablock.set(35, {
path: `${root}/Front_Revolver_2.glb`,
// -- Important fold properties for the part to fold during reload --
fold: "a_Fold",
baseFoldRot: {
x: 0.7071,
y: 0,
z: 0,
w: 0.7071
},
foldAnim: GearAnimDatablock.Front_Revolver_2_Reload_0,
aligns: [{
alignType: "Muzzle",
alignName: "Front_M"
}, {
alignType: "ShellEject",
alignName: "Front_SE"
}, {
alignType: "Magazine",
alignName: "a_Mag"
}, {
alignType: "Flashlight",
alignName: "Front_Flash"
}, {
alignType: "LeftHand",
alignName: "LeftHand"
}, {
alignType: "SightLook",
alignName: "Sight_align"
}]
});
Receiver Parts - Receiver_Short_Shotgun_2
GearPartReceiverDatablock.set(22, {
path: `${root}/Receiver_Short_Shotgun_2.glb`,
// -- Important fold properties for the part to fold during reload --
fold: "BreakPoint",
foldAnim: GearAnimDatablock.Revolver_Front_1_Reload_1,
aligns: [{
alignType: "Flashlight",
alignName: "Receiver_Flash"
}, {
alignType: "Sight",
alignName: "Receiver_Sight"
}]
});
Receiver Parts - Receiver_Revolver_1_Gripalign
GearPartReceiverDatablock.set(16, {
path: `${root}/Receiver_Revolver_1_Gripalign.glb`,
// -- Important fold properties for the part to fold during reload --
fold: "a_RevolverFold",
baseFoldRot: {
x: 0,
y: 0,
z: 0.7071,
w: 0.7071
},
foldOffsetRot: {
x: 0,
y: 0,
z: 0.7071,
w: 0.7071
},
foldAnim: GearAnimDatablock.Revolver_Front_1_Reload_1,
aligns: [{
alignType: "SightLook",
alignName: "Receiver_Sight"
}, {
alignType: "Flashlight",
alignName: "Front_Flash"
}, {
alignType: "Sight",
alignName: "Receiver_Sight"
}]
});
Receiver Parts - Receiver_Revolver_2
GearPartReceiverDatablock.set(17, {
path: `${root}/Receiver_Revolver_2.glb`,
// -- Important fold properties for the part to fold during reload --
fold: "a_Fold",
baseFoldRot: {
x: 0.7071,
y: 0,
z: 0,
w: 0.7071
},
foldAnim: GearAnimDatablock.Front_Revolver_2_Reload_0,
aligns: [{
alignType: "SightLook",
alignName: "Receiver_Sight"
}, {
alignType: "Flashlight",
alignName: "Front_Flash"
}, {
alignType: "Sight",
alignName: "Receiver_Sight"
}]
});
Gear Builder
The actual definition for weapons can be found in path_to_profile/datablocks/gear/models.js
Here you will find all the definition and animations for gear. You will notice that the ID for each piece of gear is the full gear string from the in-game gear datablocks. Do be aware that these are different to the ones that are written by the rundown developers.
To pull these IDs from a replay, simply open the browser developer console in the viewer, with a replay loaded, and enter the following command:
console.log([...(player.view.replay().getSnapshot(Infinity).data.get("IdentifierData").gearTable.values())].join("\n"));
This will log a line separated list of all the gear IDs used in the loaded replay.

When defining gear, you need to specify the model, animations and offsets. There are 3 main types:
Melee
Guns
Tools
Gear Builder - Melee
GearDatablock.set(
// Define the Identifier for the Gear
Identifier.create(
"Gear", undefined, // Header - You should not need to change this
// The Gear string mentioned previously
`{"Ver":1,"Name":"IsoCo Stinger","Packet":{"Comps":{"Length":7,"a":{"c":2,"v":28},"b":{"c":3,"v":162},"c":{"c":4,"v":40},"d":{"c":44,"v":16},"e":{"c":48,"v":18},"f":{"c":50,"v":13}},"MatTrans":{"tDecalA":{"scale":0.1},"tDecalB":{"scale":0.1},"tPattern":{"scale":0.1}},"publicName":{"data":"IsoCo Stinger"}}}`
), {
// The function which returns the model used for this gear
// The provided Gear string is passed to this function for use
// by a gear builder
model: gearJSON => {
// Here we are using the GearBuilder to construct the gear
// from the gear string
const model = new GearBuilder(gearJSON);
// We can specify the positional offset of the model when it is held
// or wielded by the player character
model.equipOffsetPos = {
x: 0.1,
y: 0.3,
z: 0
};
// We can specify the rotational offset (as a quaternion)
// of the model when it is held or wielded by the player character
model.equipOffsetRot = {
x: 0,
y: 0,
z: -0.1736482,
w: 0.9848078
};
return model;
},
// The type of the gear - determines which animations to use
// - "melee" => melee animations as specified by "meleeArchetype" property
// - "pistol" => pistol animations
// - "rifle" => rifle animations
// - "consumable" => consumable animations
type: "melee",
// Since we are using the "melee" type, we need to specifiy what animations to
// use for specific states
//
// Since multiple melees use the same archetype of animations
// you will find that this is stored in a variable elsewhere for reuse
meleeArchetype: {
equipAnim: PlayerAnimDatablock.Equip_Melee,
movementAnim: PlayerAnimDatablock.spearMovement,
jumpAnim: PlayerAnimDatablock.Spear_Jump,
fallAnim: PlayerAnimDatablock.Spear_Fall,
landAnim: PlayerAnimDatablock.Spear_Land,
attackAnim: PlayerAnimDatablock.spearSwing,
chargeAnim: PlayerAnimDatablock.spearCharge,
chargeIdleAnim: PlayerAnimDatablock.spearChargeIdle,
releaseAnim: PlayerAnimDatablock.spearRelease,
shoveAnim: PlayerAnimDatablock.spearShove
},
// The display name of the gear
name: "Spear"
});
Gear Builder - Guns
GearDatablock.set(
// Define the Identifier for the Gear
Identifier.create(
"Gear", undefined, // Header - You should not need to change this
// The Gear string mentioned previously
`{"Ver":1,"Name":"Van Auken CAB F4","Packet":{"Comps":{"Length":18,"a":{"c":1,"v":1},"b":{"c":2,"v":2},"c":{"c":3,"v":108},"d":{"c":4,"v":2},"e":{"c":5,"v":41},"f":{"c":6,"v":2},"g":{"c":7,"v":1},"h":{"c":8,"v":19},"i":{"c":9,"v":9},"j":{"c":10,"v":10},"k":{"c":11,"v":10},"l":{"c":12,"v":23},"m":{"c":16,"v":6},"n":{"c":19,"v":9},"o":{"c":21,"v":12},"p":{"c":23,"v":5},"q":{"c":25,"v":3}},"MatTrans":{"tDecalA":{"position":{"x":0.05,"normalized":{"x":1.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":0.05,"sqrMagnitude":0.00250000018},"scale":0.3},"tDecalB":{"position":{"x":0.1,"normalized":{"x":1.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":0.1,"sqrMagnitude":0.0100000007},"scale":0.3},"tPattern":{"angle":-135.0,"scale":0.2}},"publicName":{"data":"Van Auken CAB F4"}}}`
), {
// The display name of the gear
name: "Carbine",
// The type of the gear - determines which animations to use
// - "melee" => melee animations as specified by "meleeArchetype" property
// - "pistol" => pistol animations
// - "rifle" => rifle animations
// - "consumable" => consumable animations
type: "rifle",
// "gunArchetype" applies to either "pistol" or "rifle" animation types
// and "gunFoldAnim" relates to which animation the left hand should follow
// during reload sequence.
gunArchetype: {
gunFoldAnim: GearAnimDatablock.SMG_Front_4_Reload_1
},
// The function which returns the model used for this gear
// The provided Gear string is passed to this function for use
// by a gear builder
model: gearJSON => {
// Here we are using the GearBuilder to construct the gear
// from the gear string
const model = new GearBuilder(gearJSON);
// We can specify where the left hand should be placed on the gun
model.leftHandGrip = {
x: 0.05,
y: -0.1,
z: 0
};
// We can specify the positional offset of the model when it is held
// or wielded by the player character
model.equipOffsetPos = {
x: 0,
y: 0.05,
z: 0.1
};
return model;
}
});
Gear Builder - Tools
GearDatablock.set(
// Define the Identifier for the Gear
Identifier.create(
"Gear", undefined, // Header - You should not need to change this
// The Gear string mentioned previously
`{"Ver":1,"Name":"Stalwart Flow G2","Packet":{"Comps":{"Length":12,"a":{"c":2,"v":11},"b":{"c":3,"v":73},"c":{"c":4,"v":15},"d":{"c":27,"v":15},"e":{"c":30,"v":5},"f":{"c":32,"v":4},"g":{"c":33,"v":4},"h":{"c":36,"v":1},"i":{"c":37,"v":2},"j":{"c":40,"v":2},"k":{"c":42,"v":7}},"MatTrans":{"tDecalA":{"scale":0.1},"tDecalB":{"scale":0.1},"tPattern":{"scale":0.1}},"publicName":{"data":"Stalwart Flow G2"}}}`
), {
// The function which returns the model used for this gear
// The provided Gear string is passed to this function for use
// by a gear builder
model: gearJSON => {
// Here we are using the GearBuilder to construct the gear
// from the gear string
const model = new GearBuilder(gearJSON);
// We can specify where the left hand should be placed on the gun
model.leftHandGrip = {
x: 0.05,
y: -0.1,
z: 0.12
};
// We can specify the positional offset of the model when it is held
// or wielded by the player character
model.equipOffsetPos = {
x: 0,
y: 0.1,
z: 0.1
};
return model;
},
// The type of the gear - determines which animations to use
// - "melee" => melee animations as specified by "meleeArchetype" property
// - "pistol" => pistol animations
// - "rifle" => rifle animations
// - "consumable" => consumable animations
//
// If not specified, "rifle" is used by default - all tools in-game use "rifle"
// type: "rifle",
// "gunArchetype" applies to either "pistol" or "rifle" animation types
// and "gunFoldAnim" relates to which animation the left hand should follow
// during reload sequence.
//
// If not specified, no animation is used during reload - Tools don't reload
// gunArchetype: {
// gunFoldAnim: undefined
// },
// The display name of the gear
name: "C-Foam Launcher"
});
Custom Model
You can also load a custom gear model using GearGLTFModel
instead of GearBuilder
:
GearDatablock.set(Identifier.create("Gear", undefined, `{"Ver":1,"Name":"Executioner","Packet":{"Comps":{"Length":8,"a":{"c":2,"v":31},"b":{"c":3,"v":215},"c":{"c":4,"v":134},"d":{"c":42,"v":12},"e":{"c":44,"v":12},"f":{"c":48,"v":15},"g":{"c":50,"v":10}},"MatTrans":{"tDecalA":{"scale":0.1},"tDecalB":{"scale":0.1},"tPattern":{"scale":0.1}},"publicName":{"data":"Executioner"}}}`), {
model: () => {
const model = new GearGLTFModel(module.rel("../../hatchet.glb"));
model.gltf.scale.set(0.2, 0.2, 0.2);
model.gltf.rotation.set(Math.deg2rad * 20, Math.deg2rad * 150, 0);
model.gltf.position.set(-0.04, 0.22, 0);
return model;
},
type: "melee",
meleeArchetype: exports.batArchetype,
name: "Hatchet"
});
Last updated