Ricochet - Arrow Physics Framework - API Usage
Table of Contents
- Introduction
- Prerequisites
- Location of JSON Files
- Ammo Mapping
- Fracture Mapping
- Fracture Mapping - Filters
- Fracture Mapping - Modifiers
- Testing in the Game
📌 Introduction
Ricochet - Arrow Physics Framework is a modular system that lets mod creators define custom behaviors, visuals, and sounds for projectiles upon fracture. It provides a simple but flexible JSON-based mapping API to control how each arrow or bolt reacts when hitting different materials or objects.
Creators can assign durability values, fracture probabilities, and sound or impact effects to any projectile type. Filters and modifiers allow fine-grained control based on weapon type, ammunition, material, impact velocity, or even global conditions.
In short, the Ricochet Framework provides a flexible and fully configurable foundation that allows any mod to add fracture behavior to its arrows or bolts, without requiring a direct dependency on the framework.
🔹 Available Filters
Filters let you control when and how arrows or bolts break, based on simple criteria:
- Global factors: Game variables, percentage, material, keywords.
- Weapons & projectiles: Specific bows, arrows, or generic types.
- Impact conditions: Velocity, power, or whether the arrow hits an actor, an object or a surface.
These filters make it easy to customize fracture behavior for different situations.
🔹 Modifiers
Modifiers control the visual and sound effects when arrows break. You can choose which effects play, add extra sounds, or spawn broken arrow pieces.
- Custom sound effects for breaking arrows.
- Extra visual effects or debris.
- Control whether arrows stick or bounce.
With filters and modifiers, you can make arrow impacts feel varied, realistic, and immersive.
📌 Prerequisites
Before starting this tutorial, and to save time, make sure you have the following skills:
- Basic knowledge of Creation Kit: You should understand the basics of Creation Kit, including creating and modifying elements within this environment.
- Basic knowledge of JSON: An understanding of JSON files and their structure is essential for correctly creating and modifying the files needed for the Ricochet Framework.
- Understanding of impacts in Skyrim: While not essential, a general knowledge of impact systems in Skyrim will help you better understand how the Framework interacts with the game.
If you're not comfortable with any of these skills or tools, it is recommended to acquire them before following this tutorial.
Great, now that we're all set up, let's dive into using the Ricochet Framework API.
📌 Location of JSON Files
The JSON files should be placed in Data/SKSE/RicochetFramework. The exact organization of these files doesn't matter as long as they
remain in this directory.
You are free to organize them in subfolders as you see fit.
Similarly, there are no specific rules for naming the files: you are completely free to name them however you like.
In summary: as long as they are in this folder (or sub-folder), everything is fine. The rest is up to you! ✅
📌 Ammo Mapping
AmmoMapping defines how a specific arrow or bolt behaves when it breaks. Each entry specifies the original projectile (ammunition), its durability, the broken item it produces, and the possible broken states with associated effects.
Example: Defining a custom broken state for Falmer Arrows.
{
"AmmoMapping": [
{
"ID": "FalmerArrow",
"AmmoBase": "Skyrim.esm:0x38341",
"AmmoBroken": "Broken Feathers.esp:0x809",
"Durability": 20.0,
"BrokenStates": [
{
"Chances": 50.0,
"ProjectileSwap": "Broken Feathers.esp:0x827"
},
{
"Chances": 50.0,
"ProjectileSwap": "Broken Feathers.esp:0x828",
"ExtraProjectiles": ["Broken Feathers.esp:0x829"]
}
]
}
]
}
🔹 Properties
ID |
Description: Unique identifier for this AmmoMapping. Possible Values: Example: |
AmmoBase |
Description: The original projectile this mapping applies to. Possible Values: Example:
|
AmmoBroken |
Description: The object added to the actor's inventory when the broken arrow is picked up. Possible Values: Example:
|
Durability |
Description: It is the durability of the arrow, expressed as a percentage. Depending on the impact angle, velocity, and all other parameters provided by the framework, the arrow's durability will also determine whether it should break or not. Possible Values: Example:
|
BrokenStates |
Description: Array of possible outcomes when the projectile breaks.
Example:
|
With Ammo Mapping, mod creators can add fracture behavior and custom visual effects to any arrow or bolt, fully configurable and without creating hard dependencies on the Ricochet Framework.
📌 Fracture Mapping - Structure and Functioning
{
"FractureMapping": [
{
"Priority": 10,
"Override": false,
"Filters": {
"Ammunitions": ["Skyrim.esm:0x38341"]
},
"Modifiers": {
"Fracture": true,
"AmmoID": "FalmerArrow"
}
}
]
}
FractureMapping is an array in your JSON file that defines the conditions under which arrows or bolts can break upon impact.
Each entry specifies filters that determine when a fracture may occur and, if triggered, which configuration from AmmoMapping should
be used to handle the resulting behavior.
This link is established through the AmmoID field, which directly corresponds to the ID value defined in an AmmoMapping
entry.
When a projectile meets all the fracture conditions, the framework automatically applies the associated AmmoMapping, allowing you to
define
what broken model to spawn, and whether additional effects or projectiles should be generated.
The elements of FractureMapping are:
- Priority: Sets the evaluation order. Higher numbers are processed first.
- Override: Determines whether this entry replaces or merges with lower-priority entries.
- Filters: Conditions that must be satisfied for the fracture to occur.
- Modifiers: Actions that are applied when all filter conditions are met.
📌 Fracture Mapping - Filters
Each filter represents a condition that must be satisfied for the modifiers to be applied. You only need to define the filters you intend to use; it is not required to declare all of them. Filters within the same group are inclusive, meaning all specified filters in that group must be satisfied simultaneously for the effect to trigger.
However, within the arrays of each filter, the values work in OR: For example, if a weapon filter lists multiple specific weapons in
the Weapons array and you define multiple projectiles in the Projectiles array, the effect will only apply when at least
one of the listed weapons is used and that weapon must have shot at least one of the listed projectiles to satisfy the condition.
The only exception to this OR system is for Global Variables, which must all be validated for the filter to be considered fulfilled. In other words, if multiple Globals are defined, they function in AND, and each condition must be satisfied for the modifiers to apply.
📝 Before moving on to the filter list, here are a few clarifications on the use of FormID and EditorID in the JSON:
FormID: Any FormID must be formatted as follows:"Skyrim.esm:0x123456". This format is valid for all filters where a game element is required. If a FormID is incorrect or cannot be found, an error will be logged in theRicochetFramework.logfile.EditorID: This is the name of the element as it appears in the Creation Kit. Unlike FormID, the EditorID does not require the plugin name where the element is located. However, its use is limited to certain types of variables, notably Global Variables and Races. If you are unsure of an EditorID's compatibility for a given filter, it is recommended to use a FormID to avoid any issues.
Complete List of Filters
| Parameter | Description and Possible Values |
|---|---|
Globales |
Description: Defines conditions based on global game variables. Each entry consists of three elements: the global variable (EditorID or FormID), a comparison operator, and a value (integer or float). This is useful for triggering effects only when specific global game states are met. Possible Values: Array of 3 elements:
Example:
|
Weapons |
Description: Restricts effects to a specific array of weapons. This filter is ideal for applying effects to attacks performed with specific weapon. Only weapon forms are accepted. Possible Values: Example:
|
WeaponKeywords |
Description: Matches any of the listed keywords against the relevant weapon. Keywords make it possible to group and target weapons sharing a common trait. Possible Values: Example:
|
Ammunitions |
Description: Filters by specific ammunition types. Only ammunition objects (arrows, bolts, etc.) are accepted. Possible Values: Example:
|
AmmunitionKeywords |
Description: Matches any of the listed keywords against the ammunition used. This allows for easy grouping. Possible Values: Example:
|
Projectiles |
Description: Restricts effects to specific projectile forms. Use this to apply special logic depending on the projectile type (e.g., magic bolts, custom arrows). Possible Values: Example:
|
Materials |
Description: Checks if the hit object or target actor's material type matches any in the list. Typically used to differentiate surface or skin materials during impact events. Possible Values: Example:
|
HitObjects |
Description: Filters based on the specific object that was hit. Can reference either a placed reference (RefID) or its base object (BaseID). Only valid for bound objects (e.g., static objects, movable objects, or placed items). Useful for controlling effects when hitting specific environmental assets. Possible Values: Example:
|
Percentage |
Description: Defines a probability threshold for the effect to trigger. This value can also be driven by a global variable (EditorID or FormID) for dynamic control. Possible Values: Example:
|
MinPower |
Description: Sets the minimum charge power required for the filter to pass. The value typically ranges from
Possible Values: Example:
|
MaxPower |
Description: Sets the maximum charge power allowed for the filter to pass. The value typically ranges from
Possible Values: Example:
|
MinVelocity |
Description: Filters by minimum projectile velocity. Only applies when the attack involves a projectile or thrown weapon. Can be set to a global variable for dynamic scaling. Possible Values: Example:
|
MaxVelocity |
Description: Sets an upper limit for the projectile velocity filter. Useful to restrict effects to slower or faster projectiles only. Can reference a global variable. Possible Values: Example:
|
ArrowSticks |
Description: Boolean filter indicating whether the arrow or projectile sticks to the target upon impact. Can be used to trigger specific effects when projectiles embed into the actor or surface. Possible Values: Example:
|
IsActor |
Description: Boolean filter checking whether the hit target is an actor (NPC or creature). Useful when you want an effect to apply exclusively to living entities, excluding inanimate objects or static forms. Can also reference a global variable. Possible Values: Example:
|
📌 Fracture Mapping - Modifiers
Once the filters are validated, the following modifiers may be applied.
| Parameter | Description and Possible Values |
|---|---|
AmmoID |
Description: Links the projectile to a specific AmmoMapping entry. When the projectile meets all fracture conditions, the framework applies the associated AmmoMapping, defining which broken model to spawn and whether additional effects or projectiles are generated. Possible Values: Example:
|
Fracture |
Description: Boolean flag indicating whether the projectile can fracture upon impact, triggering the associated AmmoMapping effects. Possible Values: Example:
|
ImpactBounce |
Description: Determines whether a projectile will physically bounce upon impact. This is a boolean flag rather than a probability value. Possible Values: Example:
|
ImpactSound |
Description: Overrides the default impact sound with a custom sound descriptor form. Possible Values: Example:
|
ExtraImpactSounds |
Description: Array of additional sounds that are played upon impact alongside the primary impact sound. Possible Values: Example:
|
ExtraImpactEffects |
Description: Array of additional impact effects applied when the projectile hits. Each effect is played individually; no sound or decal is applied. Possible Values: Example:
|
📌 Testing in the Game
After configuring your JSON files, it is crucial to test your changes in the game to ensure they work as intended. If you encounter a crash when launching the game, it likely means that the structure of one of your JSON files is malformed (possibly an extra comma). Feel free to use tools like JSON Formatter to validate your JSON files or find potential errors.
Once the game is running, be sure to check the RicochetFramework.log file (located in
Documents\My Games\Skyrim Special Edition\SKSE) for any errors or issues with your JSON files. Regularly check this file during your
testing to identify and quickly correct errors. This will help you refine your configuration and ensure smooth integration into the game.