A naming convention for MT Pro variables, and an audit script for .bmtp files

Hi all,

Usual disclaimer first: I do not work for Bome and this is not official guidance — I am a user sharing what I ran into, and I used an AI assistant to help me read the file format, test the hypotheses and write it up.

After chasing a silence on my live rig for an evening, I found the cause was a naming problem. So I wrote down a convention, together with a script that audits a .bmtp file. Sharing it in case it is useful, and mostly to get it corrected.

The failure it came from. A translator computed a controller number into a variable and put it in the Outgoing Action’s controller slot. A dead-zone branch used ‘Exit rules, execute Outgoing Action’, so it fired before that variable was assigned, emitting CC <whatever was left> = 0. Because the variable was global, ‘whatever was left’ was not bounded by that translator, and some of the values landed in 120-127. Those are Channel Mode messages: All Sound Off, All Notes Off, Poly On. The rig went quiet and nothing in the MIDI monitor looked like a cause.

The convention, in short.

One. Locals are pp qq rr ss tt uu vv ww xx and nothing else. Every other name is global whether you meant it or not. Default to a local: they are scoped per incoming event, so two translators using pp can never interfere.

Two. Give each of the nine a fixed job — rr first data byte, pp second, qq channel, ss tt uu scratch, vv ww extra outputs, xx flag — so two values of the same type inside one chain have obvious homes.

Three. One global head letter per device, never per preset index. Presets get renumbered when you drag them, a keyboard does not. The second character carries the type.

Four. Never put a shared global in a controller-number slot, and use ‘Exit rules, don’t execute’ when a branch means ‘send nothing’.

Five. Write the legend in the translator name, in a Comment rule at the top of the chain, and in the preset’s Comments field. A literal backslash-n is a real line break there, and your own example projects use it that way, one variable per line.

The script reads a .bmtp and reports: names outside both documented ranges, globals written by more than one active preset, variables read in a preset that never writes them, variables read but never written anywhere, Outgoing Actions with a variable in the controller-number slot, and early exits that fire before the assignment they depend on. Read-only.

This overlaps with the ‘Cross-Reference List of all Variables in a MT Pro Project’ thread here and pestrela’s bome_analyse_project.sh, which I only found afterwards. Credit where it is due. Mine is a complement, focused on scope and collisions rather than cross-referencing.

The repository is on GitHub under Beennnn / bome-variable-naming. I cannot post links yet as a new member here, so I will add the URL in a reply once I am allowed to.

Where I need correcting. The scope ranges are assembled from the manual and from old forum threads. I have locals as exactly the nine doubled names, and globals as heads g h i j k l m n y z. If that is wrong or incomplete, in particular what oo or sg actually are, I would rather fix the document than have people rely on it.

Thanks,

(Posting in Bome Products since Tips & Tricks is read-only. A moderator is welcome to move it there if it belongs.)

Actually, there are 10 local variables. “oo” is also a local variable. As you said they are good for avoiding name collision, but you can’t pass those between translators (unless the receiving translator as the same incoming trigger). You can, however pass local variables as values between certain translators like “Perform” and “Timers”.
Passing variable is a recent feature so be sure you upgrade to the latest version to make that work.

I usually uses oo, pp and qq as standard the other seven I use as temporary variables. Care must be given within rules to keep track of what you are using. Sometime within a translator when I’m done with a local variable, I may actually have rules that use it again for a different purpose.

I prefer to use locals whenever possible.

I usually track all of my globals in the rules of a single translator under a preset called “Init” with a translator “Initialize Global Variables” . I usually trigger the rules by a translator with an incoming trigger of “Project Start”.

I often use global variables here when they are meant to be shared between translators. The trick is to keep track of them.

Keep in mind that if you exit rules, skip outgoing action and the MIDI - IN message had something. The MIDI message will pass through untouched based on how you have your MIDI Router set. This is a nuance that has tripped me up more than once.

For global you can now also include o-x that include any letters that are not the same as the first letter so for first letter o, you can last letter (or number) anything bu o and it would be a global variable (ie oa or o1 ,).

Thanks for posting this! I’m sure other users out there will find this useful. I’ll upgrade you shortly so you can post the link.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz