Hey all, I’ve been making some exciting progress on a pair of modules I’d like to release soonish, but before I did I wanted to do this informal survey of mistakes to avoid, especially mistakes that are hard to fix after the initial release.
One aspect I’ve been wondering is how well patches made with a module survive additions to that module in later versions. For example, if right now I have two options for something (controlled by a button) and then later I add a third option (likely making it a knob?), what helps VCV Rack keep the correct settings in existing patches when the upgrade occurs? (In my experience as a software engineer, many booleans become enumerations!).
I’d love to know what, if anything, helps that happen correctly; I’ve seen references to saving JSON config, but I think that has to do with configuration within the module’s menu (which I currently don’t foresee needing). Am I understanding that correctly?
Any other “get it right the first time” sharp edges I should protect against before the initial release?
I wrote my first oscillator without SIMD. Then I rewrote it for polyphony, and found that it used 9-10% CPU per core. Then I rewrote it to take advantage of SIMD optimizations. It then went down to 2% CPU per core.
Rack copes well if you add new parameters, and it will cope well if you add values to enumerations, even if they were booleans, because you would probably implement them as ordinary float parameters with either switches or snap knobs. So you are actually just extending the range.
Deleting params and ports is problematic.
Some people recommend saving at least one custom parameter which is a version number. Then if you need to change things radically in the future, you can tell that an older patch has been loaded, and potentially fix things up.
Top tip pre first release is to find a few trusted users to play with the modules for a while (confidentially if required) and give you feedback. They will often find any glaring bugs and highlight any usability issues, so they can be addressed before before the plugin goes out to the public.
Ah, about the ports and parameters point, when you say “don’t insert, append”, what list are referring to? The sequence of enums? The addInput/addParam/… calls? The configSwitch/configButton/… calls? All of the above?
What I’ve found is that the community is very understanding and forgiving. You might release your first modules with something like a “BETA” banner on them, and get feedback like @steve suggested. The community is an amazing resource for clever ideas! They’ve been a great help to me, offering advice on front panel designs to features and everything in-between. Get users involved early in the process!
It’s tempting to make a splash and say, “AH HA! I’ve just released GOLD!” and catch everyone by surprise. However, I wouldn’t worry about announcing your intentions to the community in advance. Personally, nobody has jumped in to try and one-up my modules before I release them. There’s not much incentive to do so.
My two cents:
Make sure that the module continues where it left off. If someone saves a patch and reloads it, they want to be hearing the same thing. (Sequencers should support a reset at least.)
Be sure that the module looks pretty in the library preview. If it’s a simple module, that shouldn’t be a big problem. But if you’re painting custom stuff on a display, it’s nice to show what that looks like in the preview.
Don’t stress. If you need to eventually phase out a module because you’ve created a replacement, you can mark the module as “deprecated” in the plugin.json file. People will still have access to your old module, but will understand that you’ve moved on:
As for enums, I’m not the best at them either. Enums are like an array. The first gets a value, like 0. The second gets “1”, and so fourth. (I’m so sorry if I’m wrong about this!) If you remove one of the enums, I think it would shift everything and break patches.
I only just today noticed the whole SIMD package in the API. I don’t think polyphony is a useful feature in what I’m making, but if I realize otherwise for anything I’m working on here, I will definitely note this.
I have been doing some performance measurement and tuning on them, and while I’m not certain my efforts are having a dramatic effect, I’m glad I started thinking about it when I did (after reading some other thread here, IIRC).
My preferred method is building from source, but you can just ship the dll. Traditionally many developers of plugins have shared beta builds and sometimes even have asked testers on other platforms to supply them back builds on other platforms. I’ve done this many times, it’s also a good way of getting a bit ahead on checking if they will build and run on other platforms than the one you develop on without problems. Your call! I’m on Mac here, and am happy to build from source for what it’s worth.
You ship the output of make dist, which is the plugin archive named *.vcvplugin which is also what Rack downloads from the library on install. You just plop those into the …/Rack2/plugins/ folder and Rack takes care of the rest.