Reference

Deep dives for power users and integrators — the TDMap button in TouchDesigner, slot function tables, every preference, keyboard shortcuts, and the public script interface.

TDMap button

Install: drag TDMap.tox onto the project root (/). That placement is suggested — one instance per project.

When TDMap is in your project, a multi-functional button appears in the top-right corner of TouchDesigner's UI. It is the fastest way to open the app, queue parameters for mapping, and toggle Learn without reaching for the keyboard.

InputAction
Left-clickOpen the TDMap web UI in a floating window — same as Alt+Shift+D.
Drag & dropDrop a TD parameter onto the button to queue it, then move a physical control to map — or open the UI and assign from the queue.
Right-clickToggle global Learn mode — same as Ctrl+L or the toolbar L button.
Middle-clickOpen this component's parameter dialog in TouchDesigner.
Button colors: blue — idle · yellow — Learn active · pink — pickup waiting on one or more controls (the web UI highlights which slots in the grid).

Slot functions

A button doesn't have to be a MIDI mapping. Flip its mode to Function in the inspector and it becomes an action button: tap it to reset, snapshot, randomize, switch banks, open an editor, etc. The same applies to a push-knob's push when it's set to Function. Most actions are one-line picks in a dropdown — pick the action, optionally pick what it operates on, done.

Picking what the action operates on

Actions that change a parameter need to know which parameter. Four ways to point at one — visible as tabs above the action:

  • Hovered — whatever your mouse is over in TouchDesigner the moment you press the button. Great for "fix-it" buttons (reset, randomize, snapshot) that you point at things.
  • Adjusted — the last parameter you twisted via MIDI. Lets one button always undo / randomize / re-default whatever you most recently touched.
  • Knob — the push-knob's own assigned parameter. Only on push-knobs.
  • Target — a fixed list of parameters you pin in advance. Two flavors, mixable in the same list:
    • Par target — drag a TD parameter onto the pill. Sticks to that exact parameter.
    • Control target — drag another card onto the pill (or click "+ Add Control Target"). Resolves to whatever that other control is currently driving — so renaming or reassigning the target control transparently changes what this button operates on. Same idea as Slot mode and Modify targets.

Actions iterate the whole list — point one Reset button at six targets to reset all of them with one press.

Things buttons can do

Everything below is a one-line pick in the inspector's Function dropdown. Where a function has variants, they show as a row of buttons right under the dropdown.

Set, reset, snapshot, randomize a parameter

All of these take a target — pick Hovered, Adjusted, Knob (push-knobs only), or Target (a pinned list of par or control targets — drag pars / cards onto the pill). See Picking what the action operates on above.

FunctionOptionsWhat it does
ResetTarget picker (Hovered / Adjusted / Knob / Target).Send the parameter back to its default value.
Set as defaultTarget picker.Make the current value the new default. Useful for pinning your "happy place" on the fly (custom pars only).
Set current as minTarget picker.Pin the current value as the bottom of the parameter's range.
Set current as maxTarget picker.Pin the current value as the top of the parameter's range.
Toggle clampTarget picker.Flip min/max clamping on or off without changing the values.
RandomizeTarget picker.Roll a random value in range. Int/float pars try to differ from the current value; toggles get a random T/F; pulses fire ~50% of the time; menus pick a different item.
Set valueValue field (type follows the parameter — number, bool, menu name, pulse fire) + optional explicit Target list.Write a fixed value to the parameter. Without an explicit target, uses Hovered.
Set step sizeStep field — number input, scrolls in ×10 / ÷10 increments per click as a convenience.Set the global step size for relative encoders. Wires straight into the same step value as the toolbar's global setting.
Navigate banks & open editors
FunctionOptionsWhat it does
Bank ProNext / Previous / Switch + device picker (current / all / named device). Switch adds a bank dropdown (0-based index).Step through or jump banks on the chosen device(s). Next/Previous wrap around. All devices switches every device at once.
Open editorHovered / Selected / Selected↑ / Adjusted.Pop the TouchDesigner Component Editor (custom-parameter setup) for a COMP and jump to the relevant page + parameter. Hovered uses the par under your mouse. Selected uses the currently selected COMP. Selected↑ walks up to the parent COMP when the selection is a non-COMP op. Adjusted uses the owner of the last MIDI-adjusted parameter.
Open parametersSelected / Selected↑ / Adjusted.Pop TouchDesigner's standard Parameters window. Works for any op kind (not just COMPs). Same three variants as Open editor.
Promote to parent (bind)Hovered / Adjusted.Promote the targeted parameter to its owner's parent COMP and bind it back, via the bundled CustomParPromoter child COMP. If the par is part of a multi-par group (XYZ, etc.) that's already mapped on a TDMap slot, the whole pargroup is promoted as a unit. Any TDMap mappings that referenced the original par get re-targeted to the new promoted par automatically.
Learn a new mapping
FunctionOptionsWhat it does
Par LearnMomentary / Toggle. Momentary learns while held; Toggle flips learn on or off each press.Activate learn from hardware, then hover a TD parameter — the slot binds to it. Same as the inspector's PAR button, but as a hardware shortcut.
Fire your own code
FunctionOptionsWhat it does
CallbackFunction name + up to two string arguments.Calls a Python function in TDMap's callback DAT by name. The function is invoked as fn(source, arg1, arg2)source is a dict identifying which control fired (device, slot, channel, CC, value, etc.) so one callback can serve many slots and tell them apart at runtime.
Encoder-specific (push on a push-knob)
FunctionOptionsWhat it does
Push-Step (hold + twist)Coarser (×10) / Finer (÷10) / Fixed. Fixed reveals a step-size field used while held.Hold the push, twist the encoder to change step size on the fly.

Preferences

Open the gear icon in the toolbar to find these. All preferences persist across sessions in a single tdmap-prefs.json file next to your configs.

Defaults for new controls

Default push modeAssignment / Function / Slot / Modify — what a brand-new button or newly enabled push-knob starts in. If you mostly use buttons for actions, set this to Function.
Default function & valueWhen the default push mode is Function, also pick the function name (e.g. Reset, Randomize) and any value it needs. New buttons pre-fill with these.
Multi-assignment by defaultNew slots start in multi-assignment mode (one slot drives many pars). Off by default.
MIDI feedback by defaultNewly created slots have MIDI Out feedback enabled. Useful if all your controllers have motorized faders or LED rings.

Behavior

Auto-toggle on assignmentWhen you assign a pulse / toggle / momentary par to a button, automatically pick the matching button action — so you don't have to think about it.
Smart LearnWhen learning a control, watch the first few movements and auto-classify it as a knob / fader / encoder / button + the right MIDI protocol.
Auto-save layoutPersist every change to the global config the moment it happens — no manual save.
Protect read-only & disabled parsBlock MIDI value writes to parameters TouchDesigner marks as read-only or disabled (mapping stays, value writes don't fire).
Loop menusMenu parameters wrap around at both ends when stepped past the edges (off = clamp).
MIDI-control string menusAllow MIDI to drive string-style menus (StrMenu). Off by default since the values are arbitrary strings, not ordered.
Middle-click "show in pane" — floatingWhen on, middle-click always opens a floating network editor (don't follow the network editor pane you last used in TD).

Feel

Global filter ProDefault exponential-smoothing amount for new slots. Per-slot override available in the inspector.
Global step / step modeDefault relative-encoder step size and adaptive vs fixed step. Per-slot override available.
Global pickup ProDefault pickup for new slots (absolute controls wait to match current value before taking over).

Workflow

Enable undo & group windowToggle Ctrl+Z and set how long rapid changes collapse into one undo step (so a knob sweep is one undo, not 200).
Slot-learn hold timeHow long you have to hold a slot button before "slot learn" mode arms.
Theme & zoomLight / dark theme, and a CEF-safe zoom (CSS transform, not browser zoom) so the panel renders sharply in any TD pane size.
Interactive tourReplay the onboarding walkthrough any time.

Keyboard shortcuts

Handled in TouchDesigner via the Keyboard In CHOP — shortcuts work even when the TDMap panel isn't focused. Open Preferences → Keyboard Shortcuts to rebind. Combos persist in your global config.

ActionDefaultWhat it does
Open UIAlt + Shift + DOpen the TDMap web UI in a floating window — same as left-clicking the TDMap button in TouchDesigner.
Learn (toggle)Ctrl + LFlip global Learn mode on or off. Same as right-clicking the TDMap button or the toolbar L button.
Learn (momentary)Ctrl + Shift + LLearn on while held, off on key release — quick one-off captures without leaving Learn armed.
Toggle step mode (adaptive / fixed) ProFlip the global relative-encoder step mode between adaptive and fixed. No default — assign your own.
Toggle pickup ProFlip global pickup on or off. With pickup on, absolute controls wait for the hardware to match the current parameter value before they start driving it.
Bank Switch (custom) ProAdd with + Add bank shortcut. Each row pins a device + bank target (index, Next, or Previous) to a combo.

On macOS, Cmd is treated as Ctrl for these combos (Ctrl+L⌘L). Shortcuts are suppressed while typing in a text field. The five built-in rows above can be cleared but not deleted; bank-switch rows are fully removable.

Public interface

The TDMap component is shipped locked so its extension methods aren't directly accessible from outside callers. Locking serves two purposes: keeping users from accidentally breaking internals on a live show, and making the package less appetizing to AI-training scrapers that crawl public TouchDesigner tox files for code to ingest.

To keep the component scriptable anyway, TDMap exposes a small set of public methods over a public-interface Text DAT. Each non-blank, non-#-prefixed line is parsed as a method call and run against the COMP — one call per line, comments allowed, per-line errors logged to the Textport. Drive that DAT however you like: Python .text = ... assignment, a Replicator emitting rows, an external tox piping commands.

Setup: open the TDMap COMP's custom parameters, go to the Integration page, and pulse Create Public Ext Interface. That creates the Text DAT next to the COMP, ready to edit or drive from another script.

Execution triggers: the lines run automatically whenever the DAT's text changes, and also whenever the COMP's Runpublic custom parameter is pulsed. Use the pulse path when you want to re-fire the same lines without re-writing them — e.g. from a button, a CHOP event, or another script.

Arguments are parsed as Python literals from text — strings, numbers, booleans, lists, dicts, keyword args all work. You cannot pass live TouchDesigner objects (no op('/...') handles, no parameter refs, no module access — eval runs in a restricted scope). Pass a path as a string instead: write '/proj/synthA', not op('/proj/synthA'). If you need a value from elsewhere in TD, resolve it in your driving script first, then write the resulting literal into the DAT.

The intended pattern is to write into the Text DAT from a script rather than typing by hand — that way you compose lines once in real Python, with normal references and helpers, and only ship the final text to the DAT. For example, a DAT Execute attached to your project's state could push fresh navigation calls into TDMap whenever a scene change happens:

# In a script anywhere in your project
tdmap_input = op('/proj/tdmap_input')  # the Text DAT TDMap watches
synth_path = synth_comp.path  # resolve refs HERE, not in the DAT

tdmap_input.text = f'''
# Re-point all mappings at the new synth COMP
RetargetBanks('/proj/synthA', '{synth_path}', device='*', banks='*')
SelectDevice('knobs')
SelectBank(0)
'''.strip()

Example lines (what ends up in the DAT):

# Open a specific device + bank programmatically
SelectDevice('knobs')
SelectBank(2)

# Retarget mappings after renaming a COMP
RetargetBanks('/proj/synthA', '/proj/synthB', device='*', banks='*')

# Auto-load a stored layout on startup
SetDefaultGlobalConfig('live_set.json')

Methods

Mapping
RetargetBanksFind/replace operator-path prefixes across bank tables. find_prefix is a literal substring or, if it contains * ? [, a tdu.match pattern matched segment-by-segment against the leading /-segments of each op_path (e.g. '/noise*''/noise1'). device and banks are tdu.match patterns (None = active, '*' = all).
LearnToggle global MIDI learn mode. None toggles, True/False set explicitly.
Navigation
SelectDeviceSwitch the active device.
SelectBankSwitch the active bank. device=None = active device.
Library
LoadGlobalConfigReplace the entire TDMap state with a saved bundle.
SaveGlobalConfigPersist current state to a bundle.
SetDefaultGlobalConfigMark a bundle as the auto-restore default on TDMap init.
Lifecycle
CreateDeviceAdd a new TDMap device (name, channel, midi_id).
RemoveDeviceDelete a device by name (irreversible).
CreateBankAdd a bank to a device; returns its idx.
RemoveBankRemove a bank by idx.
Feedback
SendAllFeedbackRe-send MIDI feedback (LED / motor / ring) for every slot on the active bank — useful after external state changes the engine didn't observe.
Debug
TestStub that just calls debug('test') — smoke-test the DAT wiring.
Why lines, not direct method access? Locked TouchDesigner components don't expose Python extension members to outside scopes, so the Text DAT is the controlled seam — TDMap parses each line, validates it, runs it under a restricted eval scope. The cost is a tiny indirection; the win is that the component stays one piece you can ship without exposing internals.