v0.2.1 - settings per instance, and editor edits that reach the plugin
Correction, added 2026-08-29. The section "There is no save hook" below is wrong. It rested
onStorePresetandLoadPresetfiring zero times on a save, and that was measured on the wrong
vtable slots — the primary pair. Resolve holds anAudioPlugin*and calls the thunks. On the
right pair,LoadPresetfires once per effect on every project load andStorePresetfires on
every save. A hosted plugin's settings live in the project from
v0.2.3 onward. The rest of
these notes still stands.
Delirio asked whether the same EQ twice in one chain could hold two different settings. It could not. Finding out why turned up four defects, three of them mine.
One file per instance, not per plugin
The same plugin twice in a chain shared one settings file, so both copies came back with whichever was touched last. An instance is now identified by its position among the live effects hosting that plugin, in Resolve's own load order.
Live is the load-bearing word. Nothing here is ever freed, so counting every effect ever claimed would give the second project's first EQ the number 1, and the same project reopened a third number again. EffectIsLive reads our vptr back off the instance through SafeRead: once Resolve frees it, that word is unmapped or somebody else's.
Editor edits never reached the plugin
performEdit was return V3_OK and nothing else, behind a single component handler shared by every effect — it could not have said which plugin was speaking. VST3 splits a plugin in two, and the host is the only thing connecting the editor to the processor. So the processor never heard about anything you did in a plugin's own window.
Each effect now owns its handler and queues the change, and the next process() call carries it over as a real parameter change.
Both halves of the state, not one
SaveState asked the component only. A VST3 keeps settings in two places and the SDK does not require them to share anything, so a plugin that keeps its values controller-side reported nothing at all. Both halves are now stored and restored in the SDK's order. Blobs written by v0.2.0 are still read.
Edits with the transport stopped
A parameter change only reaches the processor inside a process() call, and Resolve only makes those while audio runs — so anything you changed with playback stopped went nowhere. The host thread now issues the SDK's parameter flush: a process() call with no audio, carrying only the changes.
Measured, not assumed
Two Waves F6-RTA in one chain, set to different curves: edits routed per instance to different parameter ids, 5020 and 4892 bytes saved, both restored byte-exact across a full Resolve restart, and 84 changes delivered with the transport stopped.
Two things that are still true
There is no save hook. A project save asks the effect nothing — StorePreset, LoadPreset and GetParameterValue all fire zero times on Ctrl+S while other traced slots on the same object fire normally. Resolve persists the parameter values it already holds, which a hosted plugin's internal edits never touch. That is why the store runs on a timer and on every project load, and it is the reason the next real piece of work is publishing the plugin's parameters as the effect's own.
Some editors stay silent. Waves F6-RTA pushes all 84 parameters on a preset recall, and reported nothing for one band dragged by hand. Where the editor does not tell the host, nothing on this side can see it.
Settings are still opt-in: FXBRIDGE_STATE_STORE=1 /opt/resolve/bin/resolve
The binary
Built in an Ubuntu 20.04 sandbox. Floor GLIBC_2.16, CXXABI_1.3.9, GLIBCXX_3.4.22, zero undefined symbols when checked inside that same old rootfs. That does not prove Resolve runs on a distribution that old — the bridge was tested there, the host application was not.
sha256 80863b8eae1197e27cc456a7e8d60de2bf9a50caa4ecc3379d245ff669dab66d
Not a supported product. It patches structures inside Resolve's process at run time and can take Resolve down mid-edit. Save often.