WYVRN Haptics Configuration
The WYVRN configuration supports Haptic effect playback. Haptic effect files (.haps) contain the data for playing haptics on Razer Sensa HD Haptics devices.
Tools
The main tools for creating the haptic part of the WYVRN folder are:
- Haptic Composer: creation and design of the haptic files
- Synesthesia App: debug console intercepting the WYVRN SDK API calls: InitSDK, SetEventName and UninitSDK (seen in the Synesthesia app as load; play and unload).
The Haptic Composer is a powerful design tool for creating high-definition haptic experiences that can be deployed across multiple platforms and devices. With an intuitive graphical interface, it allows designers to create, edit, and test haptic effects through a familiar timeline-based workflow.
The Synesthesia Console makes creating the WYVRN (Chroma - haptics) configuration for game integration super easy. The Synesthesia engine integrates the WYVRN enabled games with various Razer Chroma RGB and Sensa haptic devices to provide a synchronized gaming experience that involves dynamic chroma and haptic feedback based on in-game events. It can be downloaded from the following link: https://github.com/WyvrnOfficial/RazerSensa_DevKit/tree/master
The Synesthesia Console app can be found in the folder ReleaseConsole from this repository. The console version is provided for testing and QA purposes. The HapticFolders can also be found in the Synesthesia app folder under HapticFolders. The latest version of this folder can be found in C:\Program Files (x86)\Interhaptics\HapticFolders when Razer Chroma is installed together with Razer Synapse 4.
To use the console version instead of the production version of Synesthesia (included in Synapse/Chroma 4 as the HapticService background service) follow the steps below.
- Open Razer Chroma and open the Sensa HD Haptics tab. Check that Haptic Source is Sensa HD Games. If it is Audio-to-Haptics switch it to Sensa HD Games.

- Open Task Manager. Look for the Haptic Service background process and check if it is active. Restart it if it is not active.

- Open the Synesthesia app downloaded from https://github.com/Interhaptics/RazerSensa_DevKit and test the setup with WYVRNFakeClient, or any WYVRN enabled game (i.e. Marvek Rivals) and the following commands load; active; play which will appear when starting the app.
When the application launches and initializes Chroma, the command to load the haptic configuration file is sent. When the SetEventName WYVRN API is called, the play command is sent.
Example:
Command Received: "load;Marvel Rivals"
Command Received: "play;Effect1"
...
Command Received: "unload;Marvel Rivals"
Haptic Folders and Files
The system uses a specific folder structure to manage haptic assets. Each game or application has a dedicated folder, named with a <Game_ID>, which contains all the necessary files for its haptic and Chroma effects.
- Haptic Folder: The folder's name serves as the
Game_IDused in external commands. - Configuration File: Each haptic folder must contain a single configuration file with a
.configextension. This file, structured in JSON format, defines the links between external command IDs and the corresponding haptic or Chroma events. - Haptic and Chroma Files: These files have
.hapsand.chromaextensions, respectively. They contain the haptic or Chroma effect data and are created using the Haptic Composer or Chroma Studio. These files are triggered via the.configfile.
External Commands
Communication with the Synesthesia process is handled through a series of simple, semicolon-separated commands. This allows the game to load, play, and stop haptic effects dynamically.
The general format for a command is:
[COMMAND ID];[ARGUMENT_1];[ARGUMENT_2]
Four main commands are available for haptic control:
| Command | Command ID | Argument 1 | Argument 2 |
|---|---|---|---|
| Load game haptic effects | load | Game_ID | |
| Unload game haptic effects | unload | Game_ID | |
| Play haptic event | play | Game_ID | External_Command_ID |
| Stop haptics event | stop | Game_ID | External_Command_ID |
Load
The load command pre-loads all haptic effects for a game, preventing runtime delays when an effect is triggered for the first time. This should be called when the game launches.
load;[Game_ID]
Unload
The unload command is used to free up resources by unloading a game's haptic effects. This should be called when the game is closed or the user navigates away from it.
unload;[Game_ID]
Play
The play command triggers a specific haptic event defined in the game's .config file. If the corresponding game's configuration is not already loaded, the system will load it first.
play;[Game_ID];[External_Command_ID]
Stop
The stop command halts haptic events. Its behavior varies based on the arguments provided:
stop;[Game_ID];[External_Command_ID]: Stops the specified event for the given game.stop;[Game_ID]: Stops all currently playing haptic effects related to that game.stop;: Stops all haptic effects from any game on all devices.
Configuration File
The .config file is a JSON file that acts as the brain for your game's haptic integration. It maps the External_Command_ID sent from the game to one or more haptic events.
ExternalCommands
The ExternalCommands array is the primary component of the configuration. Each entry links an External_Command_ID from the game to a corresponding set of Haptic_Events.
Example:
{
"ExternalCommands": [
{
"External_Command_ID": "PlayerRunning",
"Haptic_Events": [
...
]
}
]
}
Haptic Event Properties
Each haptic event can be customized with several properties that control its playback behavior.
{
"Haptic_Effect": "footsteps",
"Mixing": "Merge",
"Priority": "Medium",
"Loop": "infinity",
"Targeting": [
...
]
}
Haptic_Effect: The name of the.hapsfile to play (without the extension).Loop: The number of times the effect should be played. Use an integer for a specific count or"infinity"for an endless loop. The default is 1.Priority: Determines which effects are rendered when multiple events are active. Only the event with the highest priority will play. The levels areVeryHigh,High,Medium(default),Low, andVeryLow.Mixing: Used when two events of the same priority are active.Override(default) stops all other effects on the target, whileMergeallows both to play simultaneously.Targeting: An array specifying which body parts should play the effect and with what modifications.
Targeting Properties
The Targeting object defines where and how a haptic effect is applied.
{
"Target": "Leg",
"Spatialization": "Global",
"Gain": 0.5
}
Target: The body part(s) to send the effect to. The available targets are extensive, includingAll,Arm,Hand,Leg,Foot,Chest, and more. Targeting a parent group (e.g.,Arm) will also activate its subgroups (Upper_arm,Lower_arm,Hand).Spatialization: Sets the position of the effect. Can beLeft,Right, orGlobal(default).Gain: A normalized multiplier for the effect's intensity, from 0 (0%) to 1 (100%). The default is 1.
Advanced Interruption Control
You can manage complex interactions between effects using InterruptCommands and Groups.
- InterruptCommands: This property, placed within an
ExternalCommandobject, lists otherExternal_Command_IDs that should be stopped immediately when this command is triggered. - Groups: The
Groupsfeature allows you to bundle multipleExternal_Command_IDs under a single group ID. This group ID can then be used in anInterruptCommandslist, making it easy to stop a whole category of effects at once.
Example of using Groups and InterruptCommands:
{
"Groups": [
{
"ID": "AllMotor",
"Members": [
"Engine_Start",
"MotorRPM_Heavy",
"MotorRPM_Light",
"MotorRPM_Medium"
]
}
],
"ExternalCommands": [
{
"External_Command_ID": "Engine_Stop",
"Interrupts_Commands": [
"AllMotor"
],
"Haptic_Events": [...]
}
]
}
Fallback Commands
The WYVRN configuration provides additional flexibility through fallbacks and aliases, which apply to both haptics and Chroma.
- SetEventName Fallback: The API call itself can include a fallback.
SetEventName("EVENT_A;fallback=EVENT_B")will first search forEVENT_A, and if no match is found, it will then search forEVENT_B.
Configuration File
###General Structure
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Synesthesia.GameConfiguration",
"description": “List links between external commands and haptic events",
"type": "object",
"properties": {
"Groups": {
"description": "Group of externalCommand you can re-use in interruptCommand",
"type": "array",
"items": {
"type": "object",
"$ref": "Synesthesia.Groups.schema.json"
}
},
"ExternalCommands": {
"description": “List of links between external commands and haptic events",
"type": "array",
"items": {
"type": "object",
"$ref": "Synesthesia.ExternalCommand.schema.json"
}
}
}
}
Configuration File - Group
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Synesthesia.Groups",
"description": "Group of externalCommand you can re-use in interruptCommands",
"type": "object",
"properties": {
"ID": {
"description": “ID of the group you can use in interruptCommands",
"type": “string"
},
"Members": {
"description": “List of the actual interruptCommands contained in the group",
"type": "array",
"items": {
"type": "string"
}
}
}
}
External Command - Substructure
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Synesthesia.ExternalCommand",
"description": "a link between an external command and haptic events",
"type": "object",
"properties": {
"External_Command_ID": {
"description": "External command ID that will trigger the following haptic events",
"type": "string"
},
"Haptic_events": {
"description": "List of haptic events to triggers",
"type": "array",
"items": {
"type": "object",
"$ref": "Synesthesia.HapticEvent.schema.json"
},
"InteruptCommands": {
"description": "List commands to trigger, must match existing External_Command_ID",
"OneOf": [
{
"type": "enum",
"enum": ["All"]
},
{
"type": "array",
"items": {"type": “string"}
}
]
}
}
}
}
Haptic Event - Substructure
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Synesthesia.HapticEvent",
"description": "a link between an external command and haptic events",
"type": "object",
"properties": {
"Haptic_Effect": {
"description": "Name of the haptic effect to play. Should be the same as the related .haps file",
"type": "string"
},
"Mixing": {
"description": "Used mixing strategy for this event. Override will stop all haptic events on the given targets before playing",
"type": "string",
"enum": ["Override", "Merge"],
"default" : "Override"
},
"Priority": {
"description": “Priority of this event. Only the event with the higher priority are rendered, even before looking at mixing strategy.",
"type": "string",
"enum": ["VeryLow", "Low", "Medium", "High", "VeryHigh"],
"default" : "Medium"
},
“Loop": {
"description": “Number of time the effect must be played. Use a negative value or “infinity” for a infinity loop.",
"type": “integer“ (or “infinity”)
"default" : 1
},
"Targeting": {
"description": "List of targets to deploy the effect",
"type": "array",
"items": {
"type": "object",
"$ref": "Synesthesia.Targeting.schema.json"
}
}
}
}
Targeting Data - Target Enum Complete
Targeting a group will play an effect on all devices labelled in the given groups. Some groups are a combination of multiple ones and will activate all subgoups (as ex. «Leg» will activate «Upper_leg» and «Lower_leg».
All, Top, Down, Arm, Head, Chest, Waist, Leg, Upper_arm, Lower_arm, Hand, Skull, Neck, Upper_leg, Lower_leg, Foot, Palm, Finger, Sole, Toe, Thumb, Index, Middle, Ring, Pinky, Hallux, Index_toe, Middle_toe, Ring_toe, Pinky_toe, First, Second, Third