The problem is what should such a standalone look like for sclang? A standalone only has one entry - should it boot the server, should it show the IDE, should it show just a terminal, should it run headless, should it show just a GUI? It is hard to reason about this b/c there are many ways what a sc project actually is.
That’s a good point and I don’t really have an easy answer at this point. I guess that it varies from project to project. However, in most cases you probably want to launch sclang with some GUI, which in turn allows the user to start the Server.
With Pd, standalones are mostly trivial because IDE, language, GUI and the audio engine are all a single program. (Well, the GUI actually runs as a separate process, but that’s not really relevant to end users.)
Having multiple SC versions installed is somehow brittle
Yes, but ideally it really shouldn’t.
I think the fundamental issue with SC is that there are no scoped project environments. By default, classes and Server plugins are loaded a.) unconditionally and b.) from global search paths. For other resources like .scd files, sound files, etc. there is no well-defined search mechanism at all. If users want to load such resources from a relative path, they have to manually obtain an absolute path, e.g. with resolveRelative, and then continue from there. This is problematic because the output of resolveRelative depends on the current document.
Imagine a readSoundFile function implemented in ./foo/utils.scd that is called from ./bar/module1.scd and ./baz/module2.scd and with media files located in ./media: on each call site you have to obtain the correct absolute path to the sound file. Ideally, you would rather want a common search environment that is shared between all these files.
In Pd, every patch/abstraction has a so-called “canvas environment” which defines which search paths are considered and in which order. The [declare] object allows to specify additional (relative or absolute) search paths. Abstractions inherit the canvas environment of the parent canvas. The canvas environment is considered practically everytime something needs to be located on disk:
- externals
- abstractions
- sound files
- text files
- etc.
It’s probably not hard to see how this makes it very simple to create self-contained projects: you just put all your stuff (including any dependencies) relative to the main patch and add the necessary (relative) search paths – if any – with the [declare] object.
I really think that SC needs a document project structure with (inherited) search environments. I imagine something like a resolvePath method that takes a relative path and tries to find the first match in a list of search environments. The actual file operations, in particular on the Server, could still do with absolute paths; the user only needs to call resolvePath to locate a resource in the project tree. Similarly to Pd’s [declare] object, there should be a way to add paths to the search environment. We should establish a parent/child relationship between documents so that the search environment can be inherited.
Finally, there should be project-based search paths for class files and Server extensions. The former can already be emulated with the language config file resp. LanguageConfig.addIncludePath, but the latter is pretty painful.
(You can set the UGen plugin search path with ServerOptions.ugenPluginsPath, but this actually replaces all the default search paths and therefore also excludes the built-in plugins… In practice, you need to do something like this:
s.options.ugenPluginsPath = [
Platform.resourceDir +/+ "plugins",
"deps/plugins".resolveRelative
];
Another thing: Pd externals have platform specific extensions, so you can even distribute binaries for all platforms in a single bundle.
In fact, I have been thinking about proposing a bundle structure for Server extensions so that projects may contain plugin binaries for multiple platforms. The VST3 spec also has such “merged bundles” and I think these are better than just platform-specific extensions. Since SC 3.15 already contains several big changes to the plugin API, it might be a good chance to also introduce a bundle structure. Obviously, this needs to coordinated with your efforts on magnet since it would affect the packet structure.