Getting started with Plugin development

Hello community. I think my questions have already been answered… I’ll give it a try anyway. With a view to learning the technique of plugin creation (given my level of knowledge, I feel like I’m about to climb Everest!), could the experts on this forum clarify the following points about which I still have doubts:

1- It seems to me that VCV Rack is multifaceted since, alongside the “standard” VCV Rack, which we use as users, the plugin creator will find a Rack SDK and/or a clone of the standard Rack. Can you explain the “philosophy,” the use, and the limitations of these two?

2- It seems to me that an important prerequisite is to specify how a plugin should be structured. In other words, what is the tree structure expected by VCV Rack and the file types it should contain. From exploring the source code of some plugins and from some of the tests I’ve carried out using the manual, I’ve deduced the tree structure below. I should point out that I’m working in the context of creating a Gabi plugin (that’s my first name… which I can easily spot in the jumble of lines of code…) which would include two modules Gabmod1 and Gabmod2:

Is this structure correct? Does it contain errors or omissions? Are there any variants? Thanks to the Sherpas who agreed to join me on this expedition!

1 Like

I’m still relatively new at this so hopefully someone else will clarify and/or correct me if any of this information is incorrect.

If you’re just developing a plugin, you do not need to build rack.

For building plugins, after you set up your development environment there’s a tutorial that is helpful to follow when you’re starting, then at some point you may outgrow the use of the helper.py script. The ‘philosophy’ is that you you start by mocking up the interface in inkscape and produce an svg that the helper script uses to generate some boilerplate. It’s a good way to start out but it can be annoying when you have to make changes which involves re-editing the svg, backing up your code before you re-generate new boilerplate and then copy-pasting the good parts of your code into the new boilerplate. (This is one reason why you may outgrow the helper.py script.)

As for structure, the basics are that your svg files go in res, your cpp/hpp files go in src, helper will create the Makefile and the plugin.json, and when you run make install, it puts the dll in the right place for vcv to find it.

Thanks for the help. Regarding .cpp files, it seems there are two types: one .cpp file is for the plugin itself, and the other .cpp files are each for a module. Only the latter are placed in /src. But I don’t know if this is a mandatory structure…

  1. No, VCV Rack is not “multifaceted”. There’s the free VCV Rack, there’s the paid VCV Rack (that also can be used as a VST plugin), and for module developers beside the SDK there’s an open-source version you may install for testing purpose.

  2. Yes, there’s a preferred directory structure. Of course, you can build your own structure, but I won’t recommend this for a beginner. So don’t try to re-invent the wheel and focus on the code inside your own modules. Make them run, make them stable, make them fast :sunglasses:

Thank you for your advice (all the more insightful since you’re featured in the library !). Far be it from me to reinvent the wheel. Understanding what exists is already complicated enough for me. I must be a neat freak… but putting everything in its place will help me find my way around.

If you want to understand why this directory structure is built the way it is, please read the Makefile (if you can’t read it, maybe this might help).

If you take a look inside plugin.cpp you will see that it simply puts together all of your modules.

I recommend naming modules by what they are made for. So Gabimod2.cpp is not a good name for maybe a module that provides a triangle-oscillator. Better name it TriangelOsc.cpp instead.

Off-topic: As I started making modules, I had only one module for a long time and I didn’t care at all about the directory structure. Later on, after making a handful other modules, it was time to refactor all sources and the directory structure. I like to have a .hpp file for every .cpp file, and I like to have separate files for the modules and for the GUI widgets. But this is only my personal preference.

Thank you very much for this wise advice. And that’s really how I view educational support: not just explaining “how” but also “why.” I found it very interesting to lift the curtain of the Makefile to see what’s behind it: the recommended tutorial is very clear and super well done. Okay, the road is still long, but it’s exciting. Thanks again!

1 Like

The sources you can organize as you wish. Convention is for all source to be in src.

Rack itself has a separate include at the same level as src, with any organizing folder structure under src mirrored under include. This makes sense for something that is consumed by others as an SDK, but it’s not necessary for plugins. I use a different structure.

If you get into making more complex modules, or want to understand more how Rack works, and how it’s widgets work, I find it’s very useful to build Rack from source (with necessary modifications to build it with optimizations off for easier debugging). Building and running your plugin within full Rack source can be faster to iterate because you don’t have to build and install the deployment package (.vcvplugin). Of course, this also makes Rack source local and easy to search, navigate, and step through under a debugger.

The standard makefile expects all resources that will be installed to be in res. This is the DISTRIBUTABLES += res line in the makefile. You will always need resources if you’re using SVGs for panels. If you have “factory” presets and selections, you can see the parallel conventions for these types of content that can be installed with your plugin. This is where Rack infrastructure expects them to be, so you must follow the convention.

I like to keep documentation in the same repo with the source. I don’t publish to a site, but it’s not the worst thing to browse the markdown docs right in the repo on github. Some keep the doc source elsewhere, and publish to a site. Others don’t bother creating any docs at all.

I keep working stuff separated from installed stuff, so I have folders for this.


My current plugin is quite complex, with extensive custom UI widgets, and modules that communicate among each other, so the structure is correspondingly more complex than a simpler plugin. My other projects have been much flatter.

Some stuff is here that I wouldn’t normally keep in source control, but since I’m now switching between Windows, Mac, and Linux, and sometimes need to work away from home, more goes in there so that it’s easier to switch which machine I’m working from.

My elaborate folder structure is like this (no include folder in sight :-):

.github/workflows  // github actions for building releases
.vscode   // local vscode configuration (not checked in)
boneyard  // stuff I'm not currently using but might want later
design    // svg master files, sketches, notes
dev       // (not checked into source control) scratch files
doc       // documentation source, starting with index.md
doc/image // all graphics files for the docs (svgs, screen shots)
res/fonts
res/logo
res/panels  // all the module panels
res/symbols // specialized svg graphics
res/themes  // (I have a fancy themeing system)
res/widgets // ui widget svgs
src
src/em  // a major subsystem for the plugin used by many modules
src/modules/<module> // Folder for each module (14 modules)
src/services // common services used across the plugin (mostly header-only) (33 files)
src/widgets // ui widgets (48 files)

Each module is usually composed of a module.hpp, module.cpp, and module-ui.cpp. If a if a source file is getting too big (around the 1000-line mark), I break it down further. So, in a few modules you can find module-ui-create.cpp (ui creation separate from other ui logic), module-file.cpp (file i/o) module-ui-events.cpp (when I need a lot of ui event overrides).

Some of the modules have widgets unique to that module, so I sometimes have a widgets folder under the module.

2 Likes

Thank you so much for these insights into the developer’s inner workings. So far, this organization is very inspiring, but it’s way beyond my capabilities: I’m still at the stage of your GenericBlank template!!! So you can gauge how far I still have to go… Thanks again!