Changelog

Release notes for TDMap builds delivered through in-app update (Patreon & Gumroad). Install from Preferences → Check for updates or the header Update badge when a new version is available.

1.1.21

Current release · Update install fixes, library & factory saves, bulk convert, empty device cleanup, MIDI port matching

  • HOTFIX: Saving a device layout could wipe the slot grid and leave you with an empty device after reload. Fixed.
  • In-app updates — After you install an update, the Web UI should come back on its own without toggling the webserver off and on. Connected browser panels refresh when needed. Install warns you first that TouchDesigner may look frozen for about half a minute while the swap runs.
  • Bulk convert — Select several slots, right-click, Convert to, and pick the new type from the side menu. Works on the grid and in Unassigned MIDI.
  • Deleting devices — Removing the last device leaves a clean empty state instead of a ghost grid. Delete the active device and TDMap selects another one if you still have any.
  • MIDI port matchingLoad as… and + Device pick the right TouchDesigner MIDI row more often when a controller exposes many ports (main MIDI vs MCU, HUI, editor, Bluetooth, and similar).
  • Docs — Refreshed MIDI mapping in TouchDesigner guide and small landing-site updates.

1.1.20

CEF clipboard paste, bulk learn queue, learning & channel routing fixes, trial updates, version gate

  • HOTFIX: Par assignments got collided via a previous fix on 1.1.19
  • Clipboard & paste (CEF) — Text fields in the TouchDesigner web panel get a right-click Cut / Copy / Paste menu. Cmd+C/V actions still don't work on Mac!
  • Modal dismiss — Backdrop and outside-click dismiss no longer close a dialog when you started selecting text inside it and released on the dimmed overlay. Context menus and auxiliary overlays are excluded from outside-dismiss targets.
  • Bulk learn queue from operator drop — Dropping an operator onto the Learn queue panel in the OP drop menu opens a parameter picker (same UI as bulk assign). Choose which pars to include, then Add to queue enqueues them in one step. Quick drop onto the queue zone skips the menu when you want the full set.
  • Learning — channel & push routing — Slot lookup for learn and queue capture now matches channel and index together, including push axes. Learn no longer steals MIDI owned by push buttons in function, modify, encoder, or script modes. Alternate Knob push no longer gets an auto push_action from par-learn. Per-slot LRN rejects CC/note indices already mapped to a different slot (cross-bank).
  • Same CC, different channels — Bank assignment rows are keyed by slot (block_idx), not CC index, so two controls on the same CC number but different channels no longer collide on save/load. Legacy tables keyed by CC index still resolve correctly. Retarget follows the same row keys.
  • Trial updates — An active 14-day Pro trial can install in-app updates again. Install re-validates with the trial server; expired or offline trials are blocked from downloading builds (Check still uses cache).
  • Version gate — Entitlement now compares a baked BUILD_VERSION in the shipped tox, not the editable shell Version par. Closes manually swapping in a newer .tox to bypass the authenticated installer for lapsed Patreon subscriptions (one live re-check when the running build is newer than last verified). Gumroad lifetime licenses re-stamp locally with no extra online call. Shell Version par syncs to BUILD_VERSION on init and Reinit (skipped in Dev when the par is deliberately lower).
  • Update check from TD — Pulsing the shell Updatecheck par runs Check and broadcasts results to the Web UI (update badge / target version), not only the native TD Update par enable flag.
  • Gumroad license keys — Activation accepts a 32-character hex key with or without dashes; normalized to XXXX-XXXX-XXXX-XXXX before verify.

1.1.17

Post-tour setup guide, trial tier intro, MIDI port matching, bank sync outbound

  • Post-tour setup guide — After the main tour, a short spotlight walkthrough opens the Device Manager and steps through Check MIDI Devices, matching In / Out ports, creating a TDMap device, and applying a Factory preset. Skippable; completion also marks the first-open Device Manager and Library hints as seen.
  • Trial tier intro — On first launch with an active 14-day Pro trial, a modal explains Base vs Pro (with the header tier preview switch) before the tour starts. Links to pricing and the Pro feature docs. Waits until auth / update gates are clear so it does not fight the login or update flow.
  • Onboarding order — First-run flow is now: sync → auth gate → trial intro (when applicable) → main tour → post-tour setup. Licensed installs skip the trial intro.
  • Tour — routing collision fix — During the tour, 14-bit / routing collision warnings no longer compare mock tutorial slots against your real project mappings (false positives on CC indices shared with demo data).
  • Tour — Device Manager step — Library and Device Manager tour cards are merged into one overview; the detailed MIDI wiring walkthrough lives in the post-tour guide instead.
  • MIDI port matching — Fuzzy match when linking TDMap devices to TouchDesigner MIDI rows is smarter: CamelCase names split correctly (LaunchControl vs Launch Control XL), extra tokens in the candidate name are penalized, and midiin / midiout suffix noise is ignored. Same logic on frontend and backend (device restore / auto-wire).
  • Hardware bank sync — outbound — Outbound SysEx / CC / Note bank sync now fires for whichever device's bank changed, not only the active UI tab (API, callbacks, and cross-device bank functions included). SysEx sends immediately on bank switch; LED feedback refresh stays deferred on the active device only.
  • Device Manager — Opening the Library tab refreshes the factory preset list; setup-guide anchor targets added for the post-tour walkthrough.

1.1.16

Retarget pane pick, MIDI log filters, factory presets docs, controller undo docs

  • Retarget — Set from pane — In the retarget dialog, Set beside Find or Replace pulls the operator selected in your last network editor pane (same pane-follow as middle-click par chips). Find uses the parent path so the match targets the comp you picked, not the leaf parameter.
  • Retarget — Find validation — Find inputs that would match everything (bare /) are rejected in the UI and on the backend. Apply stays disabled until Find is valid; inline error text explains why.
  • MIDI log — SysEx & Out filters — The header MIDI-log popover and Device Manager console each get SysEx and Out checkboxes. Filter choices persist across sessions. Row rendering and byte display are improved; both consoles share the same recent-event selection logic.
  • MIDI numbering — Docs, tour, and tooltips now state that channels, CC, and note indices are 1-based (1–16 and 1–128), matching TouchDesigner. See Assigning parameters → MIDI numbering.
  • Controller undo — documentation — New Preferences → Controller undo section and landing feature callout explain TD native undo for MIDI par writes, the idle group window (default 1000 ms), and toolbar controls. Keyboard shortcuts updated.
  • Factory presets guide — New docs page lists shipped layouts, Intech Grid Editor / Profile Cloud notes, product links, and how to submit a preset for a future release. Linked from landing and sidebar.
  • Tour — First and last steps offer zoom, light theme, and TD dialog tint toggles; grid and inspector steps mention 1-based MIDI numbering.
  • Device names+ Device auto-suffixes duplicate display names so two controllers with the same TouchDesigner MIDI port label don't collide in the UI.
  • MIDI backend — Better SysEx detection, byteData fallback when TD omits it on a row, and display labels that mirror TD's internal unique device name suffixes.
  • Reranging fix — Non-custom parameters required at least min specified, now any range specification is allowed.

1.1.15

Keyboard inspector, velocity filter & count UI

  • Keyboard inspector — Click the Keyboard title (or empty header area) on a piano panel to open a device-wide inspector in the right-hand column. Set key count, start note, MIDI channel, panel position (above/below grid), and keyboard-wide Easing (Pro) and Filter (Pro). Easing and filter apply to every key on that device; new keys inherit the defaults. Per-key overrides in the slot inspector still apply until you change the keyboard-wide value again. Selecting a key switches back to the per-key inspector.
  • Velocity-sensitive buttons — Filter — The slot inspector now shows Filter for velocity hardware (note/CC velocity keys). Smoothing was already supported in the MIDI path; the control was missing from the UI.
  • Velocity-sensitive buttons — CountCount mode is hidden for velocity hardware. Count steps a parameter on each press; velocity keys drive the parameter from the continuous press value, so Count does not apply.

1.1.14

Velocity range mapping, bulk COMP assign drop

  • Velocity-sensitive buttons — Note/CC velocity now maps through the slot's assignment Min / Max range (and push-assignment ranges on velocity push-knobs). Previously velocity always used the parameter's native bounds, so custom ranges in the inspector were ignored.
  • Bulk assign — COMP drop — Dropping a COMP onto the bulk-assign Assign panel works again during TD-native drags. Drop handling now matches parameter drops: deferred hit-testing, elementsAtDragPoint (ignores the TD drag pill), and assign intent while the bulk-assign modal is open. Retarget field drops are unchanged.
  • Docs — New Callbacks reference: lifecycle events (onValueChange, onReady, bank/device switches, par learn, and more), function-mode user callbacks, source dict fields, and MIDI LED feedback override via onValueChange.

1.1.13

Auth privacy fixes, offline tier restore, controller undo

  • Auth & updates — privacy — Patreon sign-in, update checks, tox downloads, and tier writes now run from the UPDATER cook context over urllib (not webclient). Fixes This operator is private errors during OAuth, startup update check, and install on locked builds.
  • Offline tier restore — Patreon and Gumroad Pro/Base tier is applied from the signed local auth cache at startup, without waiting for a network manifest check. Legitimate lifetime and subscription users no longer appear stuck on Base when offline (especially Gumroad).
  • Patreon token refresh — Offline refresh failures keep the cached tier (EULA offline-use promise). A definitive Patreon rejection (revoked token) still locks the version gate when running a build newer than the last live-verified install.
  • Controller undo — MIDI-driven parameter changes register native TouchDesigner undo blocks on the locked component. Post-undo filter clear, display refresh, and hardware feedback run privacy-safe via deferred callbacks. UI/config edits are unchanged (not undoable via TD undo).

1.1.12

Per-bank control modes, modify current context

  • Per-bank control modes — Modify, Script, Function, Slot, and other per-bank push modes no longer bleed across banks on unlocked slots. Each bank stores its own mode (knob_modify / knob_script rows and existing is_push=2 function rows). Bank switches reset runtime modes before re-applying that bank's table; revisiting a bank restores its cached modes. Locked slots still carry modes across banks by design.
  • Modify mode — Current device / Current bank — New modify targets default to Current device and Current bank in the inspector (stored as sentinels that follow the active context at runtime). Device and Bank dropdowns include explicit Current options; card and inspector tooltips label resolved targets as (current) when applicable. Entering modify mode seeds a placeholder current-context target when none exist yet.
  • Modify persistence — Empty device ('') and current-bank (-1) modify targets now save and reload correctly per bank. Runtime routing resolves current context when applying modifiers, tinting modify groups, and building the Modified by stack.

1.1.11

Modify mode depth/strength/stack, slot pills, drag-to-inspect

  • Modify mode — depth & strength — Each modifier has a Depth slider (default 100%) that caps how strong it is on all of its targets. Each target row has its own Strength slider. Effective impact is live amount × depth × strength. The Modified by section on target controls lists every incoming modifier with a live amount bar; drag rows to reorder the stack (top runs first), or remove a modifier from the target side.
  • Modify mode — operationsBipolar replaces Offset, Limit, and Quant in the UI (50% = no change, 0% / 100% = −range / +range). Add, Sub, and Bipolar support Step: Range | Flat per target; Flat uses a fixed par-unit delta at 100% effective amount. Legacy Limit/Quant rows in older banks still apply on load.
  • Modify mode — drag & drop — Drop control cards onto a modifier's inspector (append zone or a target row) to add or replace modify targets. Card-layout drags show a live intent line on the ghost (e.g. ⊛ Modifier target, ◈ Slot target). Relative encoders and push-knobs in modify mode re-apply their targets when the amount changes; smoothed modify amounts go through the same re-apply path.
  • Modify mode — routing — Modifier stack order persists per target per bank (modify_incoming_order). Per-assignment range overrides and clamp flags are respected when modifiers write through multi-assignment and pargroup slots. Per-bank push mode is resolved from bank overrides when checking whether a button is in modify mode.
  • Slot pills unify — Assignment chips and ◈ slot pills share one tooltip and pointer model (parPill.ts): middle-click still reveals the owner in the network editor; left-drag starts the correct copy/swap drag. Slot pill tooltips include active state, par lines, inject target, and drag hint.
  • Hover-to-inspect while dragging — Card, slot-pill, piano-key, and function-target drags hover-inspect the slot under the cursor instead of changing grid selection mid-drag. Wired through the grid, keyboard panel, inspector, and function picker.
  • DocsModifiers and the in-component guide describe Bipolar, depth/strength, Step Range/Flat, and the Modified by stack. README Pro feature list updated.

1.1.10

Externalize, hover feedback, Device Manager + Library, script on encoders

  • Externalize — New Externalize pulse on the TDMap COMP saves the component to {app.userPaletteFolder}/TDMap/TDMap.tox, links it via externaltox, and creates the external TDMap_Config sibling when needed. Pulse once after your first drop and before saving a startup .toe so in-app updates swap the palette copy without embedding a frozen build. The updater refreshes the user-palette folder listing after each install.
  • Device Manager + Library — The header Library button is gone; saved layouts, factory presets, and global configs live under a Library tab in the Device Manager (toolbar devices icon). Demo mode opens the manager on Library by default. Tutorial and toolbar copy updated.
  • Hover MIDI feedback — Unmapped slots with Hover on now drive MIDI Out from whatever parameter is under the cursor in TouchDesigner (knobs/faders mirror value; buttons follow the slot's Action). Feedback refreshes as hoveredPar changes and clears when nothing valid is hovered. Fixed assignments still win when present.
  • MIDI feedback polish — Turning MIDI feedback off for a slot (or all slots) immediately sends hardware-off instead of leaving stale LEDs. A mapped parameter at its minimum is no longer treated as an "empty" clear. Button and encoder paths send LED updates for hover fallback and push-toggle state.
  • Script mode on encoders — Knobs and faders (including relative encoders and push-enabled controls) can run Script on the primary axis via new script_enabled, independent of push-button modes. The Script row stays on the primary mode selector even when push is enabled.
  • Open editor / Open parameters — ParentSelected ↑ is renamed Parent and always targets the parent COMP (editor) or parent op (parameters) of the network-pane selection, using the last network editor pane you touched in TouchDesigner. Legacy *_selected_or_parent configs still map to the new behavior.
  • Alternate Knob default — Enabling Alternate Knob defaults push Action to Hold (momentary) on gate hardware when it wasn't already momentary; latch/trigger hardware still defaults to toggle.
  • Easing UI — Per-assignment and slot-level easing controls show only where easing applies: absolute knobs/faders and velocity hardware (not relative encoders or non-velocity buttons).
  • TD drag hover — When the cursor leaves the WebUI entirely, onWebHoverOutside dismisses TD drag-hover chrome immediately (bypasses the brief flicker debounce used by onHoverEnd).
  • Values view — Alternate-knob () push assignments show live value bars in Values mode (same as primary assignments).
  • Library sync on connect — New WebSocket clients receive saved and global config lists on connect so the Library tab is populated without an extra request.
  • DocsInstall covers Externalize and startup order; Hover mode documents MIDI feedback; Assigning parameters documents middle-click Reveal in network editor on par chips; Slot functions lists Parent targets.

1.1.9

Bulk assign ParGroups, drag ghosts, undo, demo lockout

  • Bulk assign — ParGroups — Operator bulk assign now detects multi-member TD ParGroups. Assign as one >GroupName mapping (one slot) or expand to individual members per group. New preference: Bulk assign — par groups default to (single group mapping vs individual members). The confirm dialog lists parameters in a collapsible tree: TD pages, then par groups and standalone pars under each page. Toggle per group between group and individual assignment; page and group checkboxes include or exclude without collapsing the whole list.
  • Bulk assign — undo — Bulk operator assign records a single undo step for all slots it changes (assignment undo category re-enabled).
  • Drag ghosts — Control-card drag preview shows device · bank context (or Unassigned · hardware for unassigned MIDI) and a detail line for the current assignment or mode (function, slot, modify, alternate knob, push row, and so on). Detail is built from config, not the active view mode, so it stays accurate in grid, list, compact, mini, and values layouts. Ghost label persists across bank and device tab switches mid-drag.
  • Trial expiry — Demo lockout is offline-safe: when the calendar trial window ends, the auth gate and MIDI block immediately without waiting on a server round-trip. The MIDI entitlement cache no longer returns a stale entitled state past local demo expiry. UI countdown at zero re-syncs with the server when a few seconds of skew remain; otherwise lockout applies at once.

1.1.8

Bulk assign polish, device dialog, learn & trial fixes

  • Bulk assign — push-knob primary axis — Bulk assign no longer blocks the encoder's primary assignment when the push section is in function, slot (◈), alternate knob (⇧), or script mode. Those modes apply to the push button only; only Modify on the primary axis still blocks knob/fader assign.
  • Bulk assign — alternate knob mapping — New strategy option (default off): Also map to alternate knob (push assignment) on push-enabled knobs. Runs a second pass that fills push assignments on push-enabled knobs/faders, even when Alternate Knob isn't enabled yet (pre-maps the push axis for later). Grid fill uses a separate pool; selected slots mirrors each primary fit onto the push axis of the same control. Replace preview marks alternate fits with .
  • Bulk assign — fill direction — Eight grid traverse orders (row-by-row or column-by-column, each with both axis directions). The confirm dialog uses a compact picker (Traverse, primary direction, within-group direction) plus a live 3×3 preview instead of eight radio buttons.
  • Slot lock — per-bank vs locked carry — Locked slots now carry primary/push assignments, behavioral modes (function, slot target coords, modify), and alternate-knob assignments across banks. Per-bank hover, Note/CC message type, and slot-mode inject parameters stay with each bank and no longer leak from the locked snapshot. Bank MIDI overrides (channel, index, hover, msg types) still apply on top when you switch banks.
  • Device dialog — one modal+ Device, the device strip , right-click Device settings…, and + Create Device in Unassigned MIDI all open the same guided dialog (name, MIDI routing, grid, keys, advanced). Creating from unassigned pre-fills hardware name, device id, and channel; you confirm grid size and routing before slots move into a new device. Edit mode saves in place (no separate settings modal).
  • Learn — 14-bit auto-advanceAfter slot learn → Next control no longer stops after the first 14-bit fader. The 14-bit learn path now matches 7-bit LRN signaling so auto-advance walks the grid in order.
  • Trial expiry — When the in-app trial countdown reaches zero, the UI notifies the backend immediately (backup to the periodic watchdog). Start trial and Gumroad activate callbacks are deferred through the updater cook so demo start no longer hits TouchDesigner privacy errors on the WebSocket path.
  • Live demo — Major refresh: working Modify and Slot showcase devices, Unassigned MIDI flow, clearer virtual MIDI labels, in-browser config library browse (read-only factory presets), and TouchDesigner only modals when an action needs the real .tox (bulk operator assign, retarget, MIDI Device Manager, library file import/export, bank propagate, and more). Landing page copy refresh.
  • DocsUnassigned terminology throughout README and guides (replacing internal "homeless" wording). Bulk operator assign updated for fill-direction picker and alternate-knob strategy. Banks & retargeting slot-lock section clarified.

1.1.7

Alternate Knob feel, learn/bank fixes, TD drag-drop polish

  • Alternate Knob — separate feel (Pro) — Push-enabled knobs and faders with Alternate Knob can now override step, filter, and easing for the push assignment axis while alternate mode is active. Controls live under Push → Settings → Encoder feel (shift held). Relative knobs get optional step + filter overrides; absolute knobs and faders get filter + easing. Leave an override off to keep using the primary axis feel for that layer.
  • Learn mode — queue independence — Toolbar Learn (L / TDMap.par.Learn) no longer piggybacks on queue-learn or auto-replaces the param queue with the hovered par. Hover a TD parameter and move MIDI to assign it (smart-create when the grid has room). Queue learn stays its own workflow: param queue, CC on the queue panel, or Auto-enable Learn when items enter queue in Preferences.
  • Learn — bank desync recovery — When hardware and TDMap's active bank are out of sync, learn paths (queue learn, smart learn, unassigned overflow, 14-bit discovery) now scan other banks for matching per-bank MIDI overrides or device defaults before creating duplicate Unassigned MIDI slots. On match, TDMap switches to that bank and reuses the existing slot (or assigns the queued param).
  • Learn — routing fixes — Global Learn and queue learn respect push mode: assignment vs slot (◈) vs alternate encoder (⇧). Alternate-encoder shift routes learns and queue assigns to pushKnobPars; slot mode routes to slotKnobPars. Inspector PAR learn and function-target rows use the same paths. Learn button functions now toggle the same global Learn state as the toolbar (not a separate per-slot par-learn mode). Duplicate assignments are skipped when the hovered par already matches (pargroup-safe).
  • TD drag-drop — param queue chrome — Dragging a TD parameter over the header or device/bank tabs highlights the chrome as a safe queue drop zone (dashed border, same as dropping on empty UI). Dropping enqueues to the param queue instead of fighting slot routing. The TD drag cursor pill no longer blocks hit-testing under the pointer.
  • TD drag-drop — hover navigation — While dragging (in-app par pills or TD-native par/COMP drags), hovering an inactive device tab for 400ms switches devices; hovering bank tabs or mode buttons with data-drag-hover-activate auto-clicks them. Cards and piano keys get drag-over highlight and hover-to-inspect (700ms) during TD par drags.
  • Library / export — device MIDI routingknob_config and library export always write device-level routing (_base_*), not the active bank's per-bank override values. Applies to channel, index, push index/channel, and btn_msg_type / push_msg_type so bank-local CC vs Note overrides stay in bank_config only.
  • Device switch — bank sync — Switching the active device now runs hardware bank sync (when configured) before refreshing MIDI feedback, so the software bank catches up with the controller after a device-tab change.
  • First-time hints — Hint popovers wait for the first WebSocket sync (and hints_seen from tdmap-prefs.json) before rendering, so hints don't flash on every reload or race ahead of saved prefs in an external browser.
  • Inspector UXSettings sections auto-expand when you change slot mode (function / slot / assignment / alternate knob) so push feel controls aren't buried. Bulk Alternate Knob sets sensible default Hold / Toggle actions from push hardware type.
  • DocsAlternate knob guide expanded (feel overrides, Push-Step vs Alternate Knob vs Slot mode). Cross-links from feel, relative knobs, clearing mappings, and slot functions.

1.1.6

14-bit compat bypass fix, docs mobile nav

  • 14-bit MIDI compat — bypass fix — On TouchDesigner 2025.32460+, legacy per-channel midiin14_* CHOPs must stay bypassed in favor of the combined midiin_14bit_compat path. MIDI auto-bypass was treating them like ordinary midiin* ops and could unbypass them after Device Manager edits, warning resyncs, or other bypass reconciles. They now always stay bypassed on the new-TD compat path (constant bypass, expression cleared); reasserted every bypass sync and each frame on new TD so TOX-bound bypass pars can't drift back. HOTFIX: the compat-version check was reading tdu.Dependency with .eval() instead of .val, so the guard never fired.
  • Keys — library / factory round-trip — Device Keys settings (keyboard_enabled, channel, start note, count, octave offset, above-grid) now restore on apply to existing and global config load via _apply_imported_device_settings, same as grid and bank-sync fields. Keyboard slot mappings (is_keyboard) are included in library/factory knob_config save/load.
  • Library save — device MIDI channel — Saving a device config while a high-channel bank was active no longer writes that bank's effective channel into knob_config (device defaults). Export now uses the same _base_* routing as save_to_repo, so per-bank channels stay in bank_config only.
  • Docs — mobile nav — The docs sidebar toggle on narrow screens is labeled Topics (opens the guide list + search).

1.1.5

MIDI bypass stability, native offline warnings, Coaching tier Pro access, update-check watchdog

  • Coaching tier — Pro access — Patreon members on the highest tier (Coaching / $50+) now resolve to Pro, alongside the existing Lonerism tier. Tier detection uses PATREON_PRO_TIER_IDS (plural) on the backend.
  • MIDI auto-bypass — stability — Bypass now keys off each dev* pool slot's par.Id (TouchDesigner's MIDI mapper row id), not the folder name (dev3.par.Id == 6 no longer misses dev6). Unconfigured pool slots (par.Id == 0, e.g. template dev1 before hardware is assigned) are bypassed immediately, even with an empty mapper table. TD's spurious "warning cleared" callbacks are ignored while mapped hardware is still offline, which stops bypass from oscillating every frame on disconnected controllers. Compatibility passes no longer re-run on warning-only changes (fixes bypass flicker). Redundant bypass par writes are skipped when the value is already correct.
  • Offline-device warning — native UI — When the web banner would show under the device strip, TDMap also drives td_ui_mod.par.Warning, ui.status, and the native ticker (td_ui_mod.par.Text) with the same offline-device message. Clears back to the default status line when everything is connected again.
  • Offline-device warning — web UI timing — The banner waits for the first midi_devices payload (not rows.length), so an empty mapper table still flags unconfigured devices. MIDI device rows are pushed on every WebSocket connect and whenever the offline set changes, not only while the Device Manager is open.
  • MIDI feedback — Resolves midiout1 via the dev* COMP whose par.Id matches the device's mapper id (same lookup as bypass).
  • Update check watchdog — If an async manifest/auth check hangs, a timeout force-resets the in-flight Check so _check_running can't stay wedged forever.
  • Fixes — Reassigning a TDMap device's midi_id force-resyncs bypass immediately. Dev-mode logging no longer hardcoded on in release builds.

1.1.4

(HOTFIX) MIDI auto-bypass, offline-device warnings, device manager polish, 14-day Pro trial

  • MIDI auto-bypass — TDMap now bypasses a device's MIDI input/output operators when that device is inactive, reports a hardware warning, or has no working hardware behind it, so a disconnected or erroring controller can't stall the project or emit stray values. Detection runs on project load and whenever TouchDesigner's MIDI device table changes, and is tracked per device — an error on one controller never silences the others.
  • Preference — Auto-bypass MIDI on warning (on by default) — gates the warning-driven bypass. With it off, warnings are still tracked and surfaced in the UI but never bypass the operators.
  • Offline-device warning — a banner under the device strip flags TDMap devices whose linked MIDI input/output isn't currently connected (or isn't assigned), with a one-click shortcut to the MIDI Device Manager. Dismissable, and it reappears if the offline set changes. See MIDI Device Manager.
  • Device Manager — In/Out link — a link toggle between each row's input and output. While linked (the default), changing the input auto-matches the output to the same hardware; unlink for independent control. Registering a newly-seen input also auto-pairs the matching output.
  • Device Manager — per-device settings — each row in the Devices tab has a gear that opens that device's full settings modal, layered on top of the manager (with the manager still open behind it).
  • Device Manager — auto-rescan — opening the manager, the New Device modal, or Device Settings now triggers a MIDI hardware rescan so dropdowns reflect freshly-plugged controllers.
  • Unassigned placeholder — selecting #0 (unassigned) for a device is a deliberate "no hardware linked yet" placeholder and no longer creates a phantom row in TouchDesigner's MIDI table. The redundant + Add #0 button is gone, and duplicate #0 entries in the dropdowns are fixed.
  • Device naming — creating a second device with an existing name now shows the deduplicated label (e.g. Foo_2) in the UI to match the backend; device-name matching is more accurate (e.g. LaunchControl XL2 no longer matches MIDIIN2 (Launch Control XL)).
  • 14-day Pro trial — the in-TouchDesigner free Pro trial is now 14 days (was 7).
  • Fixes — Device Settings no longer loses a freshly-picked MIDI device after opening and closing the MIDI Device Manager; MIDI table-change handling is consolidated behind a single de-duplicated broadcast so the UI doesn't refresh in redundant loops.
  • HOTFIX — On create delayed check for midi device errors, otherwise crashes...

1.1.3

MIDI auto-bypass, offline-device warnings, device manager polish, 14-day Pro trial

  • MIDI auto-bypass — TDMap now bypasses a device's MIDI input/output operators when that device is inactive, reports a hardware warning, or has no working hardware behind it, so a disconnected or erroring controller can't stall the project or emit stray values. Detection runs on project load and whenever TouchDesigner's MIDI device table changes, and is tracked per device — an error on one controller never silences the others.
  • Preference — Auto-bypass MIDI on warning (on by default) — gates the warning-driven bypass. With it off, warnings are still tracked and surfaced in the UI but never bypass the operators.
  • Offline-device warning — a banner under the device strip flags TDMap devices whose linked MIDI input/output isn't currently connected (or isn't assigned), with a one-click shortcut to the MIDI Device Manager. Dismissable, and it reappears if the offline set changes. See MIDI Device Manager.
  • Device Manager — In/Out link — a link toggle between each row's input and output. While linked (the default), changing the input auto-matches the output to the same hardware; unlink for independent control. Registering a newly-seen input also auto-pairs the matching output.
  • Device Manager — per-device settings — each row in the Devices tab has a gear that opens that device's full settings modal, layered on top of the manager (with the manager still open behind it).
  • Device Manager — auto-rescan — opening the manager, the New Device modal, or Device Settings now triggers a MIDI hardware rescan so dropdowns reflect freshly-plugged controllers.
  • Unassigned placeholder — selecting #0 (unassigned) for a device is a deliberate "no hardware linked yet" placeholder and no longer creates a phantom row in TouchDesigner's MIDI table. The redundant + Add #0 button is gone, and duplicate #0 entries in the dropdowns are fixed.
  • Device naming — creating a second device with an existing name now shows the deduplicated label (e.g. Foo_2) in the UI to match the backend; device-name matching is more accurate (e.g. LaunchControl XL2 no longer matches MIDIIN2 (Launch Control XL)).
  • 14-day Pro trial — the in-TouchDesigner free Pro trial is now 14 days (was 7).
  • Fixes — Device Settings no longer loses a freshly-picked MIDI device after opening and closing the MIDI Device Manager; MIDI table-change handling is consolidated behind a single de-duplicated broadcast so the UI doesn't refresh in redundant loops.

1.1.2

per-bank note/CC overrides, propagate routing, MIDI feedback, MIDI restore, drag-drop

  • Per-bank note/CC overrides — bank MIDI overrides now store message type (Note vs CC) per slot, not just channel and index. The same grid position can listen for a note on one bank and a CC on another. Inspector Override for this bank snapshots channel, index, and types; switching banks restores device defaults, then re-applies each bank's override row.
  • Propagate bank routing — when a bank has per-bank MIDI overrides and you finish MIDI LRN (or open the bank menu), TDMap can copy learned routing to other banks that still differ. The confirm dialog lists only banks that need updates; choose CC / note indices, Note / CC (message type), and/or MIDI channels independently, with per-bank checklists (message-type and channel axes stay off when indices also differ). Bank tab right-click → Propagate routing to other banks… runs the same flow on demand. See Banks & retargeting.
  • Hardware bank sync on load — devices with SysEx, CC, or Note bank-sync mapping push the active bank to the hardware on project load, then refresh controller LEDs.
  • MIDI feedback — function-button Par Learn → Toggle drives latched on/off LED feedback (not a momentary flash); momentary buttons still flash on press. Multi-select inspector shows MIDI Out Feedback for button-only selections. Recent MIDI popover: configurable row count (1–16), optional SysEx log rows, and outbound SysEx in the log.
  • Create bank — when you snapshot routing on a new Empty bank, the default override MIDI channel is bank index + 1 (bank 0 → channel 1, bank 1 → channel 2, and so on).
  • MIDI device restore — auto-saved global configs now include midi_device_rows (TouchDesigner's /local/midi/device snapshot). Restore from saved… in the MIDI Device Manager compares the live table to that layout and applies only what you confirm; saved snapshot takes priority over fuzzy name matching. Output ports are paired from input when the saved row had in but no out. Rows with deliberate online in/out assignments are never overwritten.
  • PreferencePrompt to restore MIDI device table on startup (off by default). When enabled, the confirm dialog appears after load if the table differs from the saved layout. Manual restore always available. See MIDI Device Manager.
  • Drag & drop — dropping a COMP onto the TDMap COMP learns it as ownerComp (device / bank script namespace), alongside existing parameter drops. Drop dispatch is centralized so par / COMP / operator paths route consistently.
  • Auth UI — Gumroad license key field masks characters with a brief reveal while typing; backspace and delete behave correctly in TouchDesigner's CEF panel (no double-delete glitches).
  • Docs — guide refresh across the site (install, banks, buttons, feel, hover, bulk assign, public API, and more), including per-bank Note vs CC overrides and the three-axis propagate dialog. Changelog on the landing page is generated from markdown release files when you run npm run build:docs.
  • Fixes — bank routing propagate preview reaches the UI reliably over WebSocket; propagate preview accounts for inactive banks' effective routing (including message type); cross-bank MIDI lookup respects Note vs CC; residual learn-session edge cases around chained LRN sequences.

1.1.1

docs site, learn & feedback polish, API defaults, narrow UI

  • Product docs — rebuilt static docs at tdmap.functionstore.xyz/docs: searchable single-page index, per-topic deep links, Python syntax highlighting. New guides for assigning parameters (drag, PAR, Learn, queue learn, Smart Learn) and Unassigned MIDI (map before you have a device grid). Learning-path order updated (Preferences, shortcuts, and core mapping workflows higher).
  • Help in the UI — header ? opens documentation in your default browser (ui.viewFile). Middle-click the green connection dot to open the TDMap web UI in a browser tab.
  • Narrow layouts — header toolbar and device strip wrap more cleanly on small windows: controls right-align when they wrap, + Device stays on the same row as device tabs, connection status is a compact dot.
  • Device & bank tabs — inline ✕ / duplicate controls removed from tabs; use right-click context menus instead. Bank names reject * ? [ ] (validated on create/rename).
  • Public API defaultsRetargetBanks and SetOwnerComp with omitted device / banks now target every device and every bank (project-wide). AssignSlot omits bank to use that device's active bank. Status messages use bank display names. See Public interface.
  • MIDI Learn — per-slot LRN swallows residual encoder bursts so auto-advance doesn't double-assign; 14-bit learn fixed for relative encoders and multi-device setups; global Learn-all smart-create stops when the grid is full.
  • MIDI feedback — buttons with par assignments send normalized value feedback (0–127); note-mapped controls and piano keys use Note On/Off instead of CC. Slot-mode buttons keep three-level state feedback.
  • Bulk operator assign — refined slot matching (separate menu vs button preferences), better overflow reporting when pars are already mapped on the target device/bank.
  • Fixes — deleting a device purges in-memory caches (re-adding the same name no longer resurrects old mappings); 14-bit slots loaded from library get a 0–16383 from range when needed; MIDI device lookup rebuilds immediately on device add/remove.

1.1.0

Python public API, bulk operator assign, mapping workflow

  • Python public API — call capital-letter methods directly on op.TDMap from any TouchDesigner script (SelectBank, RetargetBanks, AssignSlot, SetOwnerComp, config load/save, …). Active-agnostic — does not depend on which UI tab is open; pass explicit device / banks where they scope work. SelectDevice is UI-only (not public). See Public interface.
  • AssignSlot — new public method to map a live Par onto a grid cell from Python: AssignSlot(par, device, row, col, bank=0). Row and column are 1-based (r2·c1 labels on cards).
  • Public API signatures — omit device to target every device (where applicable). RetargetBanks also defaults banks to all. AssignSlot always requires device. SetOwnerComp resolves bank by index or name.
  • Bulk operator assign — drag a whole operator or COMP from the network onto the TDMap COMP to bulk-map its parameters onto existing Par/Slot controls. Section-aware fill order respects empty grid rows as layout dividers. Confirm dialog with strategy options (button-first, keyboard fill, row/column major). See Bulk operator assign.
  • Drag-to-fill fields — drop a COMP path onto ownerComp fields in device / bank settings and onto Find / Replace in the Retarget panel to prefill from the dragged operator.
  • Multi-device drag & drop — cross-device par-chip and assignment drops route to the correct device; fixes for drops landing on the wrong bank context.
  • Docs — public-interface section rewritten for the op.TDMap facade; README updated with Python examples, Text DAT advanced path, and AssignSlot signatures.

1.0.19

Clear-mapping tiers, library persistence, docs

  • Clear params vs Clear all assignments — bank and device context menus now expose two tiers: Clear params removes TD parameter mappings (primary, push, slot-mode ◈, Alternate Knob shift); Clear all assignments also resets function, slot, modify, and script modes to assignment. Slot, row/column, and multi-select clear use the params tier. MIDI routing, bank overrides, and slot layout stay. See Clearing parameter mappings.
  • Device-wide clear — right-click a device tab → Clear all params / Clear all assignments across every bank.
  • Library persistence — saved and factory device configs now round-trip device script_owner_comp, bank_sysex_template, and per-bank hardware bank sync settings.
  • Add Device — collapsible Advanced section (default ownerComp, hardware bank SysEx template), prefilled from presets on Load as….
  • Docs — product docs expanded with clearing mappings, devices & library, and disambiguation from Clear CC / remove-slot actions.

1.0.18

Values view, banks on Base, multi-device fixes

  • Tier — banks on Base — multiple banks per device, hardware bank sync (SysEx / CC / Note), keyboard bank shortcuts, and bank API calls (CreateBank, SelectBank, …) are now included in Base. Pro keeps filter, pickup, easing, and function / slot / modify modes.
  • Values view — menu pars show str(par.eval()) as live text; button and push actions update the values view the same way knobs do; pargroup members stream by individual par name.
  • Multi-device view — slot inspector and multi-slot bulk inspector route edits to the correct device (_device); button action and other fields update in the UI on non-active device sections. Shift/Ctrl multi-select per section. Live modify-amount bars follow the device receiving MIDI.
  • Unassigned controls — toolbar N unassigned below chip when unassigned MIDI is off-screen (click to scroll); subtle amber border on the Unassigned panel when slots are waiting. No overlay on the grid.
  • Bank settingsOverride all / Clear all overrides when editing the live bank; inline Retarget form with per-bank scope; bulk MIDI channel for overridden slots in one dialog.
  • Button scriptsiop / ipar resolve internal shortcuts on ownerComp; device → bank → slot ownerComp chain fixes for script context.
  • Updater — version-gate and install-flow hardening; clearer Patreon re-verify when a newer build is detected outside the in-app updater.
  • Website — pricing, docs, and changelog updated for banks and hardware sync on Base.

1.0.17

Auth & update gate fixes

  • Auth cache — fixes for Patreon sign-in and tier detection edge cases after update.
  • Version gate — records the live-verified component version so manually dropped-in builds trigger a one-time Patreon re-check instead of silently unlocking.

1.0.16

Button & push scripts, ownerComp

  • Button script mode (Base) — assign a slot to Script and edit inline Python with CHOP-style callbacks (onOffToOn, onOnToOff, onValueChange, whileOn, whileOff). Each callback receives val, prev (where applicable), ownerComp, and a source info dict (same shape as lifecycle callbacks).
  • Push script mode (Base) — the push axis on knobs and faders can run its own script with the same editor and callback set; source['is_push'] is True on push dispatches.
  • ownerComp hierarchy — set a default ownerComp on the device, bank, or per slot; scripts resolve op('…'), ext, and parent relative to that COMP. Retarget find/replace now updates ownerComp paths alongside assignments.
  • Script namespaceop.A / op.Shortcut global OP shortcuts work; ext.SomethingExt resolves from ownerComp. TDMap internals are not exposed to user scripts.
  • 14-bit & routing — MSB/LSB pairing and conflict handling fixes; improved routing for unassigned targets and cross-slot drag-and-drop.
  • Config UI — numpad * / + input in the script editor; init and device-guess refinements.
  • Docs — product docs page on the landing site; README and guide updates for scripts and ownerComp.

1.0.15

Multi-slot selection & bulk editing

  • Multi-select — Ctrl/Shift-click slots in the grid; selected slots show a ring highlight and a selection count in the header.
  • Bulk inspector — when multiple slots are selected, the inspector switches to a bulk panel: assign the same target, push mode, action type, MIDI feedback, easing, or function to all selected slots at once. Mixed values show a Mixed · set on chip.
  • Context menu — right-click the grid for select-all, clear, invert, same-row/column/bank shortcuts, and bulk clear-params / clear-CC / lock / unlock.
  • Copy behavior — copy one slot’s assignment and config settings onto other selected slots.
  • Multi-device — channel-to-multi routing and related multi-device improvements.
  • Landing — header Update badge relabeled to Install when a new build is ready.

1.0.14

Hardware bank sync & faster switching

  • Hardware bank sync — keep TDMap and multi-bank controllers in step (e.g. Novation Launch Control XL). Set a device-wide SysEx template in ⚙ Device settings — hex body without F0/F7, with ?? where the bank index byte goes. Per bank, open Bank settings…Hardware bank sync: Off, SysEx, CC, or Note; use LRN to capture the next bank-change message from the hardware. TDMap sends the sync message when you switch banks (tab, shortcut, slot function, or script); inbound SysEx / CC / Note switches TDMap automatically. Echo from your own outbound SysEx is suppressed; synced tabs show a dashed outline.
  • Device & bank settings⚙ Device settings on the device tab centralizes grid size, MIDI device / channel, piano keys, and the bank SysEx template. Bank settings… (right-click a tab or create / duplicate flow) covers name, hardware sync, and bulk MIDI channel for bank-overridden slots in one dialog.
  • Faster bank & device switching — optimistic bank-tab clicks, lightweight bank-switch updates instead of a full UI resync, and per-device / per-bank runtime caches so large layouts stay responsive when hopping banks or devices.
  • Slot learn — Preferences After slot MIDI learn (LRN button) can advance to the Next control after each successful capture. Reliable hand-off from the backend after learn completes; fixes learn-advance on slots with bank overrides and on unassigned MIDI rows.
  • MIDI monitor — SysEx in and out in the MIDI Device Manager console and popover, with direction arrows and hex bytes.

1.0.13

Keyboard panel, presets & MIDI routing

  • Piano keyboard panel — optional keys strip above or below the grid (reorderable). Oct ± shifts which notes the full-size keys show without transposing incoming MIDI. Ghost strips on the sides show mappings outside that window; ↓ / ↑ jump to the nearest octave with an off-range mapping.
  • Presets & librarycontrol names round-trip in saved and factory device configs. Importing a preset keeps per-slot MIDI channels (e.g. grid on ch 1, drum pads on ch 10); only slots on the preset’s default channel remap when you pick a new device channel. Load / Load as… in the device library opens the Add Device dialog with MIDI Device, channel, grid, and keys — same fuzzy name match as + Device (e.g. Arturia MiniLab → Minilab3 MIDI).
  • Routing warnings — 14-bit and routing collision badges only compare slots on the same TD MIDI Device (midi_id), so two controllers on different device rows no longer false-alarm each other.
  • Safer edits — confirm dialog before removing a device or bank (tab ✕, context menu, and MIDI Device Manager).

1.0.12

Config library import & export

  • Export / import libraries — back up and share saved device and global config libraries to JSON files from the config library panel. Import merges new entries and skips duplicates by filename.
  • ParGroup assignments — ParGroup targets serialize all steppable members (not just the first) so multi-par groups round-trip correctly in saves and exports.
  • Device manager — refinements to the MIDI Device Manager and Add Device flow.

1.0.11

Updater & licensing polish

  • In-place updates — the updater selects the TDMap COMP for reload instead of the config DAT, so installs land on the right operator.
  • Gumroad — lifetime license keys support up to three machines per key (documented on the licensing page).
  • Landing — site copy and layout updates for the free-download flow.

1.0.6

Free download & clearer licensing

  • Free download — the TDMap component is now a free download straight from the site. It’s one build for everyone; sign in with Patreon or Gumroad to activate it (or run the 7-day trial). Get TDMap →
  • Keep your version for as long as you like — once you’ve signed in on a computer, that version keeps working there offline, indefinitely — for both Patreon and Gumroad. You do not have to stay subscribed to keep using TDMap; an active license is only needed to install updates or activate a new computer. (Staying subscribed is hugely appreciated — it’s what funds new features.)
  • Update protection — if a build newer than the one your license last verified shows up (e.g. a .tox dropped in by hand instead of installed in-app), Patreon members do a quick one-time membership re-check online before the editor opens — an active membership verifies silently. Gumroad lifetime licenses are exempt (you own every future version) and never need to phone home. Prefer not to re-check? Just keep running the previous version.
  • Clearer licensing page — a plain-language summary of Patreon vs Gumroad, what’s checked and when, and exactly what happens if a Patreon subscription ends. See how licensing works.

1.0.5

One build for every tier & the free trial

  • One download for every tier — TDMap now ships as a single build. Sign in with Patreon or Gumroad and your Base or Pro tier applies automatically — no more picking the right file or re-downloading to switch tiers.
  • 7-day free trial — try the full Pro feature set inside TDMap for 7 days without signing in (one trial per machine). The trial validates with our server at launch and about once an hour while running — so the clock can’t be extended by changing your computer’s date — and pauses without losing time if it can’t reach the internet. When the week is up, your mappings are kept and you’re invited to subscribe or buy. See the trial details.
  • Sign in once, keep working — your tier is cached and used indefinitely. TDMap doesn’t re-check on every launch and never silently downgrades you; if your Patreon tier dropped, installing an update gives you a clear choice to keep your current build or switch.
  • Clearer auth gate — “Demo Ended” vs a recoverable “Trial Paused — reconnect” state, and click-through from the demo timer to buy without losing your mappings.

1.0.4

Licensing polish & update policy

  • Smarter update checks — checking for updates uses your local sign-in and works offline. Patreon is only re-verified live when you install an update; Gumroad lifetime keys behave the same way.
  • Patreon tier sync — Base → Pro upgrades are picked up when you check for updates (no need to sign in again). Pro → Base downgrades do not silently remove Pro: you get a one-time choice to keep the Pro build or switch to Base (only when you check for updates, not on every launch).
  • Signed auth cache — credentials on disk are HMAC-signed and bound to your machine. Editing the auth file or copying it to another PC invalidates the cache.
  • Gumroad tab — masked license key field; activation rate-limiting after repeated failed attempts; dedicated Sign in with Patreon action (no longer tied to “check for updates”).
  • Preferences & mobile — sign-out / check-for-updates footer layout fixes; landing site and in-app layout improvements on small screens.
  • Update badge — header badge no longer sticks around when you are already on the latest build.
  • Legal & docslicensing overview and EULA on the website; EULA links in the auth gate and Preferences.

1.0.3

Licensing & in-place updates

  • Patreon authentication — sign in with your Function Store Patreon membership (Base or Pro). OAuth is cached per machine; membership is verified live when you install an update (tier may sync when you check).
  • Gumroad authentication — activate with a lifetime license key from your Gumroad purchase (up to three machines per key by default, if you need more, email us!). Re-verify on check without burning seats on the same machine.
  • Tier-based releases — your entitled tier selects the Base or Pro channel in the release manifest; tier upgrades can prompt installing the matching build.
  • In-place updates — fetch the manifest, download the signed .tox, verify SHA-256, and reload TDMap in place. TDMap_Config and your mappings stay outside the swap.
  • Update UX — background check after startup when already licensed; header Update badge and Preferences for check / install; auth gate on first launch or after sign-out.

1.0.2 and earlier

Prior releases

  • Earlier builds shipped before Patreon / Gumroad licensing and the public update flow. Use Check for updates in TDMap to move to the latest release for your tier.