Skip to content

Configuration

uncoil reads one JSON file: %APPDATA%\uncoil\config.json. The desktop app writes it; you can edit it by hand. uncoild watches the file’s modification time and reloads it on change, so edits apply immediately.

This is what uncoil runs when there is no config file at all:

%APPDATA%\uncoil\config.json
{
"effect": { "kind": "wave", "angle_deg": 35, "period_s": 14, "wavelength": 26, "reverse": false },
"brightness": 1.0,
"saturation": 1.0,
"fps": 30,
"display": { "off_when_display_off": true, "dim_level": 0.35, "fade_s": 1.2 },
"desk": {},
"openrgb_hardware_rainbow": false,
"openrgb": { "devices": [] }
}
KeyTypeDefaultMeaning
effectobjectwaveThe effect every device samples. See Effects.
brightnessnumber, 0–11.0Overall brightness.
saturationnumber, 0–11.0Colour saturation; 0 is white light at the effect’s brightness.
fpsinteger30Frames per second sent to each device, clamped to 5–60.
displayobjectsee belowHow lighting follows the display. See Display.
deskobject{}Where each device sits on the desk. See Desk.
openrgb_hardware_rainbowbooleanfalseOlder switch for the OpenRGB hand-off; true means openrgb.mode "hardware" when that isn’t set. See below.
openrgbobject{ "devices": [] }What uncoil does with OpenRGB for the motherboard, GPU and RAM: off, a hand-off at sign-in, or live. See below.

Effects are pure functions of desk position and time. Every device samples the same field, which is why a wave crosses from the keyboard onto the mouse and mat without a seam. kind selects the effect.

Rainbow bands travelling across the desk at an angle.

KeyDefaultMeaning
angle_deg35Direction of travel. 0 sweeps left to right, 90 back to front.
period_s14Seconds for one full colour cycle to pass a point. Higher is slower. Minimum 0.5.
wavelength26Width of one full rainbow, in key units (1u = 19.05 mm). Minimum 1.
reversefalseRun the wave the other way.
"effect": { "kind": "wave", "angle_deg": 0, "period_s": 8, "wavelength": 18 }

The whole desk cycles through the rainbow in unison.

KeyDefaultMeaning
period_s14Seconds per full cycle. Minimum 0.5.

One colour everywhere. color is required, as [red, green, blue] from 0 to 255; brightness still applies.

"effect": { "kind": "static", "color": [255, 96, 0] }

All LEDs dark. The devices stay connected and keep their normal-mode functions.

"effect": { "kind": "off" }

Fades in and out.

KeyDefaultMeaning
colors[]No colours: a new rainbow hue each breath. One: that colour. More: they take turns. Each is [r, g, b].
period_s4Seconds per breath. Minimum 0.5.

Random LEDs twinkle. Every device shares one field, so the twinkles are spread across the whole desk.

KeyDefaultMeaning
colors[]Colours to pick from; none means random hues.
density0.15Share of LEDs lit at once, 0–1.
twinkle_s1.5Seconds per twinkle. Minimum 0.1.

Flames rising from the front edge of the desk.

KeyDefaultMeaning
speed10.25–3.
height0.5Flame height as a share of the desk’s depth, 0.05–1.

A rainbow turning around a centre point.

KeyDefaultMeaning
period_s6Seconds per turn. Minimum 0.5.
reversefalseTurn the other way.
centernull[x, y] in desk key units; null is the keyboard’s centre.

reactive lights a key when it is pressed and fades it; ripple sends a ring across the desk from each pressed key. While either is in use (on its own or in a Studio layer), uncoild listens for key presses and turns each one into a desk position straight away; it never records which key it was. See SECURITY.md.

KeyDefaultMeaning
colornull[r, g, b], or null for a new rainbow hue per press.
fade_s1Seconds a press takes to fade.
speed12ripple only: ring speed in key units per second.
width1.5ripple only: ring width in key units.

The desk fills left to right with the system audio peak level, green to yellow to red. uncoild reads only Windows’ peak level for the default playback device, one number, never the audio itself.

KeyDefaultMeaning
sensitivity1Multiplies the level before it is drawn.

Layers of effects, bottom first. Each enabled layer is blended over the ones below it where its mask covers an LED. Reactive, ripple, starlight and the audio meter are transparent where they are dark, so they can sit on top of another effect.

"effect": {
"kind": "studio",
"layers": [
{ "name": "Base", "effect": { "kind": "wave" }, "mask": { "kind": "all" } },
{ "name": "Mouse", "opacity": 0.5, "effect": { "kind": "static", "color": [255, 96, 0] },
"mask": { "kind": "devices", "ids": ["razer-basilisk-v3-pro"] } },
{ "name": "WASD", "effect": { "kind": "reactive" },
"mask": { "kind": "keys", "device": "razer-blackwidow-v4-pro-75", "shapes": ["W", "A", "S", "D"] } }
]
}
Layer keyDefaultMeaning
name""Shown in the app.
enabledtrueA disabled layer is skipped.
opacity10–1.
effectrequiredAny effect above except studio.
mask{ "kind": "all" }all, devices with ids, keys with a device id and shapes (key and LED names from the device file), or lights with [device, shape] pairs on any devices, e.g. { "kind": "lights", "lights": [["razer-blackwidow-v4-pro-75", "W"], ["razer-basilisk-v3-pro", "Logo"]] }. The app’s Lighting page writes a whole-desk layer plus devices and lights layers when you give devices their own effect.

Colours for wave, spectrum and the other rainbow effects come from FastLED’s “rainbow” hue map rather than a plain HSV wheel. It is tuned for real LEDs, so no band of the rainbow looks wider or brighter than the rest.

uncoil listens for Windows’ console display state, the same signal Synapse uses.

KeyDefaultMeaning
off_when_display_offtrueFade the lighting out when Windows turns the display off.
dim_level0.35Brightness multiplier while Windows has dimmed the display (0–1).
fade_s1.2Seconds for each fade.

Once faded out, uncoil sends a few black frames and then idles; the devices hold the last frame. On wake it re-prepares every device (some reset during sleep) and fades back in.

Where each device sits, keyed by device id, in key units: x to the right, y toward you. For a keyboard the point is the top-left of the key area; for every other device it is the device’s centre. Devices not listed use their defaults:

DeviceDefault xDefault y
keyboard00
mouse20.753.1
mouse mat11.1253.375

A connected device the config doesn’t place, beyond the first of its kind, is put next to the others of its kind (a second keyboard below the first, another mouse to the right). Devices without lighting never appear on the desk.

To move the mouse a little further right:

"desk": { "razer-basilisk-v3-pro": { "x": 22.5, "y": 3.1 } }

Device ids are the id in each device file. Because the wave is computed from these positions, a correct desk layout is what makes the bands line up from one device to the next.

In live OpenRGB mode the PC’s OpenRGB devices join the desk too, with ids openrgb:<name> (the device’s name in lower case, other characters as -, for example openrgb:asus-rog-strix-b550-f-gaming-wi-fi; a second device with the same name gets -2). Unplaced, they stack in a column left of the keyboard. To move one, give its centre like any other device:

"desk": { "openrgb:corsair-vengeance-pro-rgb": { "x": -6, "y": 2 } }

The app’s Devices page lists them by name under “Through OpenRGB”; uncoil --json status gives their ids under openrgb.devices.

Off by default. uncoil drives Razer devices itself; for the rest of the PC (motherboard, GPU, RAM) it can use OpenRGB. openrgb.mode says how:

modeWhat happens
"off"Nothing. The default.
"hardware"At sign-in, OpenRGB runs once to put each device in openrgb.devices on its own built-in (hardware) effect, then exits. uncoil doesn’t drive those devices.
"live"OpenRGB keeps running in the background as a local SDK server, and uncoil sends it the desk effect, so the motherboard, RAM and GPU follow your Razer devices.

Without mode, the older "openrgb_hardware_rainbow": true means "hardware"; when both are there, mode wins. The app’s Settings page sets mode for you.

Both modes need:

  1. OpenRGB installed at C:\Program Files\OpenRGB\OpenRGB.exe. For RAM and many motherboards OpenRGB also needs PawnIO, its SMBus driver on Windows; see OpenRGB’s own instructions.
  2. The -OpenRgb install (scripts\install-task.ps1 -OpenRgb), which registers the elevated uncoil-openrgb task and the administrators-only folder OpenRGB keeps its settings in (%ProgramData%\uncoil\openrgb). RAM lighting sits on the SMBus, which needs administrator rights, so the unelevated daemon can’t do this itself. (A daemon installed with -Elevated runs the hand-off or the server itself at start.)

Either way, if OpenRGB is already running in your session, it is closed first, and RAM is left alone while Corsair iCUE runs, because both would write the same bus.

The task runs at sign-in, so turning a mode on, or switching between hardware and live, takes effect at your next sign-in (with -Elevated, when the daemon restarts). It writes no log; its result is the task’s Last Run Result in Task Scheduler: 0 ran and exited cleanly, 1 turned off or nothing configured, 2 failed (see Troubleshooting). In live mode the task stays Running for as long as OpenRGB does.

"openrgb": {
"mode": "hardware",
"devices": [
{ "match": "ASUS", "mode": "rainbow" },
{ "match": "Vengeance", "mode": "rainbow wave", "ram": true }
]
}

openrgb.devices lists what to hand off; there is no built-in device list, so nothing happens until you add an entry.

KeyMeaning
matchPart of the device name as OpenRGB lists it (passed to OpenRGB.exe -d).
modeThe OpenRGB mode to put it in (passed to -m).
ramtrue for RAM on the SMBus: skipped while Corsair iCUE runs. Default false.

match and mode must be plain names: 1 to 64 letters, digits, spaces and -_.()+#&:/, not starting with - or a space and not ending with a space. Anything else is skipped, so a config entry can never become an OpenRGB option.

"openrgb": {
"mode": "live",
"live": { "port": 6742, "exclude": ["Vengeance"] }
}
KeyDefaultMeaning
live.port6742The SDK server’s port on 127.0.0.1, 1024–65535. The task starts OpenRGB on it and the daemon connects to it.
live.exclude[]OpenRGB devices to leave alone: any whose name contains one of these, ignoring case.

uncoil drives every device OpenRGB finds except Razer devices (anything with “Razer” in its name or vendor, so also products like the Lian Li O11 Dynamic Razer Edition case), hidden ones, ones with no LEDs, the ones exclude matches, and RAM while iCUE runs. The OpenRGB it starts has every Razer detector turned off.

The devices appear on the desk as a “PC” column left of the keyboard, in the order motherboards, RAM, GPUs, the rest, so the effect reaches them the way it reaches a mouse or a mat. Move them with desk if your case sits elsewhere. Brightness, saturation, the frame rate (at most 30 for OpenRGB devices) and the display fade apply to them too.

Things to know:

  • The SDK server has no password. While it runs, any program on this PC can change the motherboard, RAM and GPU lighting through it; that is how OpenRGB’s SDK works. uncoil starts it listening on 127.0.0.1 only, so other machines can’t reach it. See SECURITY.md.
  • Turning live off stops uncoil sending frames straight away; the PC’s lights stay as they were last set, and the OpenRGB server keeps running until you sign out or end the uncoil-openrgb task in Task Scheduler.
  • The app’s Settings page shows the connection: connected with the number of devices, waiting for the server, or the error.

The desktop app keeps its preferences in a separate file, %APPDATA%\uncoil\app.json, which the engine ignores. The app’s Tray & notifications page edits it:

KeyDefaultMeaning
close_to_trayfalseClosing the window hides it in the tray instead of quitting.
start_in_trayfalseStart hidden in the tray when you sign in: a per-user startup entry (the Run key under your account) launches uncoil-app.exe --tray. Also keeps the app in the tray when the window closes.
battery_notificationstrueNotify when a wireless device’s battery is low, and when charging reaches 100 %. Checked every 10 minutes while the app is open or in the tray.
battery_threshold20Percent for the first low-battery notification, 15–50; a second one comes at 10 %.
PathWritten byContents
%APPDATA%\uncoil\config.jsonyou, the appSettings (this page).
%APPDATA%\uncoil\app.jsonthe appThe app’s own preferences (above); the engine never reads it.
%APPDATA%\uncoil\devices\*.tomlyouExtra or overriding device definitions, read at start. Experimental unless the file sets support; files over 1 MB are skipped.
%LOCALAPPDATA%\uncoil\status.jsonuncoild, every 2 sRunning devices, fps, retries, errors, and the daemon’s own memory, CPU and size.
%LOCALAPPDATA%\uncoil\uncoild.loguncoildDevice opens and losses, display changes, reloads, writes to device memory. Trimmed past 256 KB.
%LOCALAPPDATA%\uncoil\onboard-writes.jsonluncoildOne line per write to a device’s own memory. keymap reset uses it to restore a key’s value from before uncoil first wrote it.
%ProgramFiles%\uncoil\uncoild.exeinstall scriptThe installed daemon (install.log next to it says what the last install did).
%ProgramData%\uncoil\openrgbOpenRGB, the uncoil-openrgb taskOpenRGB’s settings for the hand-off or the live server; administrators only. In live mode the task writes OpenRGB.json there (Razer detectors off, server on 127.0.0.1). Created by -OpenRgb or -Elevated installs.