Where to best put your M4L files / dependencies?

Thijs Koerselman's icon

I find this subject rather fuzzy for M4L and I can't seem to find any clear documentation on it.

When you develop a M4L patch with abstractions where do you put your files? On OSX I normally create a project in the default generated "Documents/Max6 Projects" folder.

I know that you can put everything in one folder or all over the place and eventually freeze it. But when you edit/unfreeze a device, since Live9, it seems to generate a folder in "Documents/Max for Live Devices" with all the project files in a subfolder names "Yourdevice Project".

Or...after unfreezing it generates a folder (not file) "Yourdevice.amxd" in that same location :S What is what, and whatfor? Unfreezing also gives me a dialog to open something, but I have no clue what it wants and just click cancel.

Is it sensible to put your development files there also? Will they collide with unfrozen devices later? Is it only for temporary storage? And how does an amxd file relate to a maxproj file? Max seem to unpack an amxd file as if it were a project but you can't pack a maxproj into an amxd file?

Lots of questions. I hope someone has a clear answer or pointer so some docs, cause at the moment I feel like I'm freewheeling myself towards some future conflicts.

loadmess's icon

Hello,

I have been dealing with some "freezing" issues myself.
The best (and only) documentation I found was this:
https://cycling74.com/docs/max5/vignettes/core/live_dependencies.html
https://cycling74.com/docs/max5/vignettes/core/live_freezing.html
http://downloads.ableton.com/misc/maxforlive_production_guidelines.pdf
I guess a freezed device is like a zip file, a container for distribution. So when we unfreeze
a new folder is created with the contents.
One of the main difficulties is dealing with the assets of the device, databases, pictures, subfolders... etc in way that max can find them after freezing.

Igneous Rock's icon

I am currently struggling with this as well. I am amazed that I cannot find decent documentation for how to deal with my M4L object and dependencies, and right now it's a confusing mess split between the bowels of my "Ableton" folder and the "Max 7" folder.

Jeremy's icon

Every Max for Live device is actually a Project. When the M4L device is opened/saved, a folder (named as the device) is created in ~/Documents/Max 7/Max for Live Devices, and the dependencies of unfrozen devices are unpacked into that folder. When you freeze the device, project dependencies are then automatically bundled into the .amxd file.

Maybe you can provide some concrete devices/situations where this system is failing for you, so that we can suggest an appropriate workflow. And improve the documentation where necessary. I agree that this should not require much additional effort on the part of the device developer.

Lee's icon

I think this problem arises if you are not using Max projects and have your sources elsewhere (at least it does for me)

So, eg., if have all my source in myfolders/lee and this is separately pathed in

i freeze a device into lee.amxd - all is fine.
i unfreeze that device and it creates a new directory under mydocuments and unpacks the code - now I have 2 copies of it and things can get confusing as to which files you are editing (the ones under mydocuments or the ones under myfolders/lee)

simple solution to this is to remove the created directory under mydocuments whenever you unfreeze your device and then you are always using the code from myfolders/lee.

i'm currently starting to use max projects more and I guess this will resolve this situation as the source and unfreeze directory should theoretically be the same at that point...

anyway, not sure if that is your situation, but if it is, there you go :)

to_the_sun's icon

Lee,
Even if you delete the files in the Max for Live Devices folder, they will be re-created, and it seems the frozen device will always use its internal files even if you edit the ones in the Max for Live Devices folder. The only way to edit abstractions and such then becomes by opening them from the device itself. That's my understanding anyway; I'm slowly becoming less confused, but I can't say I understand it completely.

to_the_sun's icon

It may be that if you have your device open and unfrozen, you can edit the files in the Max for Live Devices folder and it will find them when you refreeze it. Just a hypothesis that I haven't tested. I'm having trouble understanding what the point of the Max for Live Devices folder even is.

Jan M's icon

@TO_THE_SUN
Maybe it helps if you think about think about frozen M4L devices similar as a complied program. It is the state where everything that is needed by the device is inside one file, to make sure it runs without outside dependencies in any Live set on every computer.

Like with compiled code: When you use an external library (in Max that would be an external or abstraction) a compiled program will always use the version it was compiled with.

But compiled programs are not editable. That's why when you unfreeze a M4L device an 'un-complied' version of the code/patch is created in the MaxForLive Devices folder.

To my understanding freezing is the last step in development. - basically when development is done. During dev i always work with unfrozen devices and use the global versions of external and non project-specific abstractions.

To avoid confusions between abstractions that I use globally in different projects and devices and those that are project specific I "namespace" project abstractions by prefixing them.

In general I think it is a good practice to keep all you M4L stuff inside the MaxForLive Devices folder and don't build them from outside locations.

Jan

to_the_sun's icon

Right, normally I would never freeze a device until it's ready for distribution. Recently I started using the amxd~ object however which forces you to freeze your device continually and therefore seems to be more trouble than it's worth for anything that's not in a completely finished state.

However, if you try to edit an abstraction saved in the Max for Live Devices folder, it will just be overwritten next time you unfreeze the device. What about if the device is already unfrozen and open? Then are the files in the folder the ones it will reference when it freezes again? If so, maybe you could edit them, but if the device is already open and everything you might as well just get to the abstraction in question by opening it through the device itself.

Anyway, I never had issues with this folder until I started using the amxd~ object. For one thing, why would freezing a device create text files there of the contents of coll objects (not set to Save Data with Patcher)?

Jan M's icon

@TO_THE_SUN

yes, the overwriting without prompting when unfreezing is a real bummer. I wrote a feature request / suggestion a few month ago to cycling74. I think there should be either a modal dialog or overwritten files should be moved to the _DeletedItems folder inside the M4L project, so we could at least recover them.

andrew's icon

Max 8 / Live 9 - my personal process for getting around this ridiculous issue

  1. work on your device out of whatever directory

  2. add the folder "<device name> Project" to "Documents/Max 8/Max for Live Devices" (if it doesn't exist already - for me usually it does not)

  3. add a subfolder depending on the type of file. this will either be: /code (.js or other?), /externals , /media (images), /patchers (abstractions)

  4. freeze. I think at this point the .amxd will take on the project folder as it's own. you can check by deleting the folder, freezing and unfreezing. it seems to just work.

this feels performing surgery. absolute insanity. totally not the kind of issue I would expect from proprietary software and a company with full-time employees, but, whatever. it works now. just a huge bummer cause it prevented me from sharing my code for a while.

Mattijs's icon

Here is how we deal with freezing at Showsync. For every new version of Videosync and Beam we have to distribute potentially updated versions of our Max for Live devices, obviously in a frozen state.

On our development machines though (in git repositories, in our case) we have only a single, non-frozen, version of any .amxd and only a single version of any dependency. We prefer not to have these source folders in a default Max search path but rather to selectively add the folders containing dependencies to the search path using Options / File Preferences.

If there is ever a reason to unfreeze a distributed version of a plugin, perhaps for debugging, afterwards we quickly remove the folder with copies of dependencies that is created in Documents/Max/Max for Live Devices.

These are the reasons that we try to avoid unfreezing devices as much as possible:

  • Having copies of dependencies creates a risk of unintentionally editing the copies instead of the originals, losing work if the copies are subsequently deleted.

  • Multiple devices, unfrozen or never frozen, may have different dependencies with the same names. One device can use a filterlow.maxpat abstraction which is a lowpass dsp filter and another device can use a filterlow.maxpat which passes only values above a threshold. If both abstractions are in the Max search path, it is unclear for any of the two devices which version of the dependency will be used at which point. Both devices may well end up loading a different dependency than the one they started out with. Having untracked copies of dependencies in the Max search path increases this risk.

  • After saving a Live set with a newly unfrozen device, the Live set now depends on files in the Documents folder without the user getting notified about it. After doing Collect all and Save (which I generally also avoid btw), when moving the Live set to another machine, the device will be broken. Depending on the context, the dependencies may be gone and it may not be possible to recover the device.

Finally, though this may go beyond the scope of most, for some time now, frozen versions of our devices actually never have to exist on our development machines at all since our devices are frozen automatically by our hosted continuous integration system, using a script we developed specifically for this purpose.

Hope that helps!


Krishnan Anantheswaran's icon

More than 2.5 years later (on Live11 and Max 8.5.3) the current state doesn't seem to have improved by much :(

My biggest beef is that the .amxd file needs to live in one place for Live to find and the rest of the patchers/ JS files etc. typically live in another set of folders that are under version control.

My compromise is that I create the device by embedding a single bpatcher in it such that the device itself can be recreated from scratch by simply including the bpatcher. The bpatcher and all associated files are under source control. This reduces the surface area of messing up the amxd file and not knowing what happened.

This is not bulletproof in that this makes it harder to send scripting messages to the device and so I typically have to include the scripting code at the device level (or maybe there is a way to do this as well that I haven't yet figured out)

Mattijs Kneppers's icon

Hi Krishnan,

My biggest beef is that the .amxd file needs to live in one place for Live to find

I'm not sure I understand this: as far as I know the .amxd files can be anywhere on your disk and can be loaded in Live Sets by dragging them in.

For me, the .amxd files live in the same repository and are version controlled in the same way as their dependencies.

allforabit's icon

Does it not still duplicate dependencies to the documents folder when you open a device via Live (which I think most people would do to get debug info from the running Live instance)? See threads here https://cycling74.com/forums/max-for-live-and-git and here: https://cycling74.com/forums/bpatcher-keeps-creating-duplicate-files-and-using-old-version

Separately do you have any further details on how you got consolidation and building of devices working in ci? From what I can see there isn't a command line interface to max.

Mattijs Kneppers's icon

Does it not still duplicate dependencies to the documents folder when you open a device via Live (which I think most people would do to get debug info from the running Live instance)

For visibility, I replied about this to https://cycling74.com/forums/bpatcher-keeps-creating-duplicate-files-and-using-old-version. In short, as far as I'm aware, duplicating dependencies should only happen when unfreezing.

This is the reason I work on devices unfrozen. Of course, this means that their "source" folder should be added to the Max search path. Either the dependencies live next to the device, in which case they are automatically found by Max, or you add the folder(s) with the dependencies to the search path manually, in menu > Options > File Preferences.

Separately do you have any further details on how you got consolidation and building of devices working in ci? From what I can see there isn't a command line interface to max.

That's correct, we have reverse-engineered Max' freezing process for this and re-implemented it in typescript. I hope we'll be able to release this one day, but so far it's still a messy script that can only be used by the people who wrote it :p

mattyo's icon

I've been bumping into yet another version of this issue someone might perhaps have some advice on. I have an .amxd, which I have frozen and unfrozen, whose dependencies are not in the ~/Documents/Max 8/Max for Live Devices/ path. A folder with the project name does appear in there, but none of the patches I actually use get moved/copied to it. At the moment, the .amxd/top level patch is in a subfolder inside the Ableton User Library, the one abstraction I use so far is in a random place in my Max Library folder, and a coll that's shared between instances of the device is the only thing in the ~/Documents/Max 8/Max for Live Devices/MyDevice path.

Obviously, this is causing me some agita, as I'm worried about adding more abstractions/data structures/whatever is going to cause more disorder, but I'm also nervous about just reassembling it all by hand in the place where, to my understanding, dependencies for a non-frozen patch should be, which is in ~/Documents/Max 8/Max for Live Devices/. Anyone have an wisdom on how to deal with this?

thanks,

\M