PLUG'N SCRIPT
rapid plugin development
Tutorial
DSP
KUIML
How-to
Scripts
  • Overview
  • Tutorial
  • Reference
  • Built-in variables
  • Runtime model
  • Parameters mapping
  • Script converter
  • LetiMix
KUIMLParameters mapping
November 04, 2025

Parameter Mapping Explained

When writing a .kuiml file for a script, we often use names like custom_param0, custom_param1, custom_param2, etc. to access the parameters we added in the DSP section. But here’s the catch: these custom parameters are not the actual DSP parameters. Let’s break down why they exist, and why they sometimes cause issues.

Dynamic Script Loading

The real DSP parameters exposed to the GUI by the PnS engine are named like dsp.input0, dsp.input1, dsp.input2, and so on. This naming system is consistent across all Blue Cat Audio plugins.

However, Plug’n Script is different because it needs to load different scripts on the fly, each with its own parameter set. The problem is: a plugin inside a DAW can’t just change its parameter list on the fly — most DAWs don’t allow that.

So, Plug’n Script uses a workaround:

  • To the DAW, it exposes a fixed set of generic parameters, with ranges from 0 to 1, named like Param 0, Param 1, etc.
  • Inside the GUI, these generic parameters get linked to custom_params defined in the skin.
  • These custom_params are flexible — their names, ranges, default values, and other properties can change depending on the currently loaded script.
  • But since they only exist inside the skin, they are not exposed to the DAW.

Seeing It in Action

To understand this better, open the “LetiMix Debug” skin (included in LM Skin). It clearly shows how the mapping between the generic parameters and the custom ones works in practice.

I've loaded a simple "Gain" script that adds a single input parameter called "Gain" with ranges from -20 to 20 dB. 

As you can see it's linked to a dsp.input8 parameter, which is a "real" dsp parameter. And as already said "custom_param0" is an "alias" or "proxy" parameter that is created inside the skin.

When we change the value of "custom_param0" it changes the value of dsp.input8 and vice versa. The value of dsp.input8 param changes from 0 to 1, but is displayed as 0..100% by default.

Note for exported plugins

Plug'n Script itself reserves parameters dsp.input1-7 for it's internal purposes, dsp.input0 is by default a "bypass" parameter. That's why our script's first parameter is dsp.input8

But after we export the plugin, PnS removes 7 internal parameters and our first input parameter becomes dsp.input1. Also dsp.input parameters displayed in the DAW get proper names, ranges and units (provided in our script).

This is true if you export without option "Use generic parameters". If you "check" this option upon export, you'll get the same "generic" parameter names and ranges as inside Plug'n Script ("Param 0, 1, 2"). And your first input parameter will be dsp.input8 as well. This can be useful for some compatibility reasons. Still, it's much more convenient to not use this option and get normal parameter names and ranges after export (so don't check "Use generic parameters" if you don't need it specifically).

These two parameters are linked in the skin using PARAM_LINK, something like this (slighly simplified):

  1. <PARAM_LINK from="dsp.input8" to="custom_param0" normalized="true" />
  2. <PARAM_LINK from="custom_param0" to="dsp.input8" normalized="true" />

The links are "normalized" meaning the ranges of the parameters are matched. So if one parameter has range from 0 to 1, another from 0 to 10, when we set first parameter to 0.5 another is set to 5.

But how does "custom_param" gets information about it's current name and range from the script? Well, it's also exposed to the GUI using hidden dsp.private_output params and dsp.output_strings. 

Here I've loaded another script that exposes 4 input and 2 output parameters. Current number of input/output parameters is exposed using dsp.private_output1/2, and several more hidden parameters and strings are used. They transfer information to the GUI about "custom_param" attributes (min, max and default values, number of "steps", name, units, list of enumerated_values and value format).

So for providing each "custom_param" attributes Plug'n Script actually uses 8 additional parameters and strings.

Later in the skin all this information is linked to every "custom_param" like this:

  1. <!-- create custom_param0 -->
  2. <PARAM id="custom_param0" min="0" max="1" default="0" name="Param 0" />
  3. <!-- link values from DSP to its attributes, they will change dynamically depending on the script -->
  4. <PARAM_LINK from="dsp.private_output3" to="custom_param0.min"/>
  5. <PARAM_LINK from="dsp.private_output4" to="custom_param0.max"/>
  6. <PARAM_LINK from="dsp.private_output5" to="custom_param0.default"/>
  7. <STRING_LINK from="dsp.output_string8" to="custom_param0.name"/>
  8. <STRING_LINK from="dsp.output_string9" to="custom_param0.unit"/>
  9. <STRING_LINK from="dsp.output_string10" to="custom_param0.enum_values"/>
  10. <STRING_LINK from="dsp.output_string11" to="custom_param0.value_format"/>
  11. <!-- and finally link the value of the param itself to the dsp.param -->
  12. <PARAM_LINK from="dsp.input8" to="custom_param0" normalized="true" />
  13. <PARAM_LINK from="custom_param0" to="dsp.input8" normalized="true" enabled="false" id="backlink0" /> <!-- link back is disabled by default -->
  14. <PARAM_LINK from="custom_param0.capturing" to="backlink0.enabled"/>

If you want to see how it's done really (not slightly simplified like here), you can open the default skin folder and find files "mapping.inc" and "mapping_utils.inc". The same principles are used in LetiMix skin (mappings are in the file "common.inc")

This "trick" allows Plug'n Script to create individual script parameters on the fly, without the need to reload the plugin or restart the DAW. For the DAW the number of DSP parameters and their properties remain the same. And for the script-writer the parameter name and range ("custom_param0") stays the same after exporting.

Accessing parameters after export

We really don't need "custom_params" trick when our plugin is exported. But it stays there for the compatibility reasons, so that we can have the same simple .kuiml with same parameter names and it would work fine. However "custom_param" becomes a "rudiment", and after export it is wiser to use "dsp.input" params directly. 

  1. <!-- a variable that holds param's name -->
  2. <VARIABLE id="GAIN" value="custom_param0" />
  3. <REPEAT count="($SCRIPT_EDIT_MODE$==0)">
  4. <!-- applied when plugin is exported -->
  5. <VARIABLE id="GAIN" value="dsp.input1" override="true" />
  6. </REPEAT>

  7. <!-- to check what we have -->
  8. <TEXT value="$GAIN$" />
  9. <PARAM_TEXT_CONTROL param_id="$GAIN$" />

Something like this would work fine. If you want to make it even easier to manage parameter names in KUIML, you can do it like this (works in LM Skin):

  1. <VAR id="N" value="0" />
  2. <VAR id="PARAM_NAME" value="custom_param" />
  3. <IF_EXPORTED>
  4. <!-- when exported we use dsp.input params directly -->
  5. <VAR id="N" value="1" />
  6. <VAR id="PARAM_NAME" value="dsp.input" />
  7. </IF_EXPORTED>
  8. <VAR id="MODE" value="$PARAM_NAME$$N$"/><NEXT_N />
  9. <VAR id="GAIN" value="$PARAM_NAME$$N$"/><NEXT_N />
  10. <VAR id="CHANNELS" value="$PARAM_NAME$$N$"/><NEXT_N />
  11. ...
  12. <PARAM_TEXT_CONTROL param_id="$GAIN$" />

This would work fine both in PnS and after export.

Changing custom_param value from the script

Many of us struggle, when we try for the first time to write a GUI script that changes input parameter. Suddenly we find out that though the knob in the GUI turns, the parameter in the DSP is not updated. Don't give up!

Take a look at the last line in the parameter linking example that says: 

  1. <PARAM_LINK from="custom_param0.capturing" to="backlink0.enabled"/>

It enables the "link back" from the "custom_param0" to "dsp.input8" only when custom_param0 is "capturing". Meaning its value is changed by user via mouse or keyboard. Why is this done that way? Why not just always keep custom_param and dsp.input param linked both ways? Blue Cat Audio explains that otherwise there is a possibility of a bad linking "loop" when you load a preset or change parameter via MIDI.

So how to do we do this then? For example, this script would only change the parameter in the GUI (custom_param0), but not the input value in the DSP (dsp.input8).

  1. <ACTION ... script=" 
  2. double new_gain = 2;
  3. custom_param0 = new_gain;
  4.  " />

To make it work we have to add "BeginCapture" and "EndCapture" calls like this:

  1. <ACTION id="apply_gain" name="Apply gain" type="Script" script=" 
  2. double new_gain = 2;
  3. custom_param0.BeginCapture();
  4. custom_param0 = new_gain;
  5. custom_param0.EndCapture(); "
  6. requires="custom_param0*"
  7. />

Now this parameter is marked as "capturing" and its value is updated in the dsp.input parameter as well. These BeginCapture/EndCapture calls are also required for some DAWs to update parameter value or write automation. If you omit them, in some DAWs it may work, in some it will not.

Note: if you have popup errors trying to use "BeginCapture", try to explicitly add them as "REQUIRED_OBJECTS" to the main skin (XML file you're using), like this:

  1. ​<REQUIRED_OBJECTS object_ids="custom_param0.BeginCapture;custom_param0.EndCapture" />

Or, if you're modifying dsp.input8 directly from the .kuiml you may need this

  1. ​<REQUIRED_OBJECTS object_ids="dsp.input8.BeginCapture;dsp.input8.EndCapture" />

Compare the numbers

Just for fun, here's the same script in Plug'n Script (on the left) and as an exported plugin (on the right).

Compare the number of exposed parameters. 

The exported plugin has only the input parameters we've added in the script (4 parameters + default bypass), and their names, ranges and units are specified.  Plug'n Script has 48 generic params (by default) + 7 for internal purposes.

The exported plugin dsp.inputX parameters already have correct ranges, names and units, so mapping them to "custom_params" is unnecessary and done just for backward compatibility.

Conclusion

Now you know that "custom_params" are just aliases created in the skin, so you should use them wisely! The good decision would be to use "dsp.input" params directly after export (just be aware that their names change after export - like dsp.input8 becomes dsp.input1), as shown in the examples above.

Good luck with your scripting!

P.S. Take a look at article "How to add params more conveniently".


Comments

Please, authorize to view and post comments.

2020 - 2026 © Site by LetiMix · Donate  |  Plug'n Script and KUIML by Blue Cat Audio