General scripting advice

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

General scripting advice

Post by ggoblin »

I'm totally new to Moho scripting, I would appreciate some general advice on scripting, in particular what development environment you set up.

1. Do you install a seperate LUA distribution where you develop the non- moho specific parts of your code? I personally didn't see the point of this as everything is so closely tied to the Moho api?

2. Do you set up a test rig within Moho? What exactly does it consist of?

3. When you start a new script do you use an existing one and modify it or do you start from scratch, or from a skeleton script?

4. A lot of lines of code go into building the GUI. Do you use any script tools to build the GUI or do you feel its better to just script it yourself everytime?

5. How do you handle version control? When developing I'm guessing you cant just change the lua file name as the internal moho table names will clash in the script menu with older version of your script? Every time I make a change that I worry might break an existing working version (which as a beginner is all the time), I end up duplicating the original file and changing the extension name of the original to hide it from moho, so it doesn't clash with the new test version which I am about to save. The other way is to handle version control within your own script by commenting out chunks of code as backup when you make changes.. nightmare. There must be better ways.

6. Are there any debugging tools (other than the reliable print statement) or advice? Is there a quick way to pause execution and dump all the variable to screen for example, ie setting a break point?


Any other tips? The three I have learnt the hard way is
1) Ensure you use : for table functions and . for table attributes otherwise you may crash moho
2) Use explicit casting for layer types when you create them otherwise further down the line you may get unexpected behaviour when moho sometimes doesn't recognise what type of layer it is.
3) Remember to add MOHO. prexif when using any moho constants.

Thank you
User avatar
synthsin75
Posts: 9975
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: General scripting advice

Post by synthsin75 »

ggoblin wrote: Sun Jun 05, 2022 10:13 pm I'm totally new to Moho scripting, I would appreciate some general advice on scripting, in particular what development environment you set up.

1. Do you install a seperate LUA distribution where you develop the non- moho specific parts of your code? I personally didn't see the point of this as everything is so closely tied to the Moho api?
Get very familiar with the Moho shortcut to reload scripts (ctrl+shift+alt+L). Personally, I don't even use a text editor with Lua syntax highlighting, but I know many people do.
And yes, the Moho API is so central that developing outside of testing directly in Moho seems pointless.
2. Do you set up a test rig within Moho? What exactly does it consist of?
Hayasidist uses a test harness to give him feedback of the various variables as he's writing, but aside from print statements, he's the only one I've seen do that.
You will need to create enough in Moho to test whatever specific functionality you're writing.
3. When you start a new script do you use an existing one and modify it or do you start from scratch, or from a skeleton script?
Depends on if I'm modifying an existing script. I do keep skeleton scripts (tool, button, and layerscript) that have the basic script overhead (UI name, description, creator, prefs, mouse functions, etc..), for completely original scripts.
4. A lot of lines of code go into building the GUI. Do you use any script tools to build the GUI or do you feel its better to just script it yourself everytime?
Depends on how recently I've been doing UI. If it's been awhile, I will reference their use in other scripts, to make sure I'm not missing part of the handling (message, widget update, pref update, etc.). It can be easy to miss needed elements.
5. How do you handle version control? When developing I'm guessing you cant just change the lua file name as the internal moho table names will clash in the script menu with older version of your script? Every time I make a change that I worry might break an existing working version (which as a beginner is all the time), I end up duplicating the original file and changing the extension name of the original to hide it from moho, so it doesn't clash with the new test version which I am about to save. The other way is to handle version control within your own script by commenting out chunks of code as backup when you make changes.. nightmare. There must be better ways.
I have a "Disabled" folder in the menu and tool script directories, so I can move older/working versions there while I make changes to an installed script. Moho doesn't read scripts from folders it doesn't know to look in. I just copy/paste it to the disabled folder and append a name on the script to describe the latest working feature/state. If I need to revert, I just move it back into the script folder and remove the appended name. Changing the extension works too. Years ago, I did just comment out code blocks, but that just leads to overly large scripts to navigate.
6. Are there any debugging tools (other than the reliable print statement) or advice? Is there a quick way to pause execution and dump all the variable to screen for example, ie setting a break point?
Aside from Hayasidist's test harness, which I believe he has posted somewhere but I've never used myself...you can always stop a script mid-execution with:
if true then return end

You can then add in any print statements you want to test before the return command.
Any other tips? The three I have learnt the hard way is
1) Ensure you use : for table functions and . for table attributes otherwise you may crash moho
2) Use explicit casting for layer types when you create them otherwise further down the line you may get unexpected behaviour when moho sometimes doesn't recognise what type of layer it is.
3) Remember to add MOHO. prexif when using any moho constants.
It's hard to remember all the gotchas I ran into as a new Moho scripter, as I was also completely new to programming at the time. Sounds like you have previous programming experience and should be well-equipped to catch most those as you find them. And as with everything Moho, this forum is an invaluable resource.

One I forgot recently was that animation channels need to be cast as their type, just like layers do:
ChannelAsAnimBool
ChannelAsAnimColor
ChannelAsAnimString
ChannelAsAnimVal
ChannelAsAnimVec2
ChannelAsAnimVec3
https://www.mohoscripting.com/classes/ScriptInterface
User avatar
hayasidist
Posts: 3525
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: General scripting advice

Post by hayasidist »

synthsin75 wrote: Sun Jun 05, 2022 10:45 pm Hayasidist uses a test harness to give him feedback of the various variables as he's writing, but aside from print statements, he's the only one I've seen do that.
You will need to create enough in Moho to test whatever specific functionality you're writing.
my harness does a whole lot more than just format and print variables. For example, I can write an "incomplete" Lua function (including non-moho stuff - as in your q1), stick that file in a folder and the harness will provide a (very basic) UI / mouse interactions - IOW I can test "snippets" without having to write the whole script into which it will fit. The harness has "plug-ins" to provide information on moho objects - for example which points are in which shapes; active channels in layers etc etc ... it's a diagnostic tool for Moho.

I did upload a very early version (v 1.02 - some 10 years ago), but there were few takers, so I haven't bothered to update the uploaded version. It's here if you want to take a look at it: https://www.mediafire.com/file/s7aibsz3 ... 2.zip/file

Getting the current version (3.51 - which is functionally much much richer) "public releaser ready" (e.g. better integration of moho-diagnostic tools; user guide) is not currently on my to-do list.

===

As Wes pointed out, there are a few "gotchas" in the API. The introduction page in https://mohoscripting.com/ talks about those and gives a few "start here" ideas too.

There's also a "build an empty script" tool on that website: https://mohoscripting.com/new_script

About your observation " Ensure you use : for table functions and . for table attributes otherwise you may crash moho" -- it _is_ possible to call functions using the "." notation - see the "Moho crashes but your code looks right!" section in the introduction page. This is very useful if you want to store the function and call it indirectly. e.g. to get the right type of channel object whatever channel you throw at it:

correctlyCastChannel = castChannel (moho, someUnknownChannel)

Only useful, ofc, if you want to use the AnimChannels / common (e.g. GetValue etc) attributes but pointless if you're looking for channel-specific stuff such as AreDimensionsSplit

Code: Select all

local function castChannel (moho, ch)
	local chCast = {
		{MOHO.CHANNEL_VAL, moho.ChannelAsAnimVal},
		{MOHO.CHANNEL_VEC2, moho.ChannelAsAnimVec2},
		{MOHO.CHANNEL_COLOR, moho.ChannelAsAnimColor},
		{MOHO.CHANNEL_BOOL, moho.ChannelAsAnimBool},
		{MOHO.CHANNEL_STRING, moho.ChannelAsAnimString},
		{MOHO.CHANNEL_VEC3, moho.ChannelAsAnimVec3}
	}
	local i, s

	s = ch
	for i = 1, #chCast do
		if ch:ChannelType() == chCast[i][1] then
			s = chCast[i][2](moho, ch)
			break
		end
	end
	return s
end

===
And ... there are many scripters active in this forum ... if you have a question - just ask!
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: General scripting advice

Post by ggoblin »

Thank you so much for your feedback Wes and Hayasidist, I am going to go through it carefully before replying. I really appreciate it.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: General scripting advice

Post by ggoblin »

synthsin75 wrote: Sun Jun 05, 2022 10:45 pm Get very familiar with the Moho shortcut to reload scripts (ctrl+shift+alt+L). Personally, I don't even use a text editor with Lua syntax highlighting, but I know many people do.
And yes, the Moho API is so central that developing outside of testing directly in Moho seems pointless.
I found that combination a bit long so custom keyboard shortcut changed it to ALT-R. But I might switch back because everytime moho crashes (and thats a lot with my scripting attempts) it switches back to the default keyboard.

I use Notepad++ which has Lua syntax highlighting. I think it has option for extending that for APIs but it would need a list of Moho API keywords to do that.
Hayasidist uses a test harness to give him feedback of the various variables as he's writing, but aside from print statements, he's the only one I've seen do that.
You will need to create enough in Moho to test whatever specific functionality you're writing.
Usually with interpreted languages you get better debugging facilities than with compiled ones. I'm surprised how little feedback we get scripting Lua in Moho, often just crashing with no stack dump, etc.
Depends on if I'm modifying an existing script. I do keep skeleton scripts (tool, button, and layerscript) that have the basic script overhead (UI name, description, creator, prefs, mouse functions, etc..), for completely original scripts.
I started with a script that had some of the functionality I needed as as a start point and then deleted what I didn't need and built on that, rather than start from scratch. There are parts of the skeleton I still don't understand - a lot of lines related to language localization BASE_STR etc. So I have just left them alone for now.
I have a "Disabled" folder in the menu and tool script directories, so I can move older/working versions there while I make changes to an installed script. Moho doesn't read scripts from folders it doesn't know to look in. I just copy/paste it to the disabled folder and append a name on the script to describe the latest working feature/state. If I need to revert, I just move it back into the script folder and remove the appended name. Changing the extension works too. Years ago, I did just comment out code blocks, but that just leads to overly large scripts to navigate.
When I created a disabled directory off the scripts/menu directory and placed my disabled script in it, moho seemed to pick it up automatically. It created a new sub menu called disabled with my script inside it.. I suppose I could just ignore that extra menu folder? But I think everytime moho starts it checks all the scripts for syntax errors so am worried it might slow my start up process?
And as with everything Moho, this forum is an invaluable resource.

One I forgot recently was that animation channels need to be cast as their type, just like layers do:
ChannelAsAnimBool
ChannelAsAnimColor
ChannelAsAnimString
ChannelAsAnimVal
ChannelAsAnimVec2
ChannelAsAnimVec3
https://www.mohoscripting.com/classes/ScriptInterface
Yes in my short time here I have found the forum to be Moho's biggest strength, everything it lacks in other areas, due to the size and resources of the company, it makes up for by the generosity of its users on the forum. It might be small, but its the most supportive community I have come across.

I haven't reached animation channels yet, but I will make a note about casting them, thank you.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: General scripting advice

Post by ggoblin »

hayasidist wrote: Mon Jun 06, 2022 9:48 am my harness does a whole lot more than just format and print variables. For example, I can write an "incomplete" Lua function (including non-moho stuff - as in your q1), stick that file in a folder and the harness will provide a (very basic) UI / mouse interactions - IOW I can test "snippets" without having to write the whole script into which it will fit. The harness has "plug-ins" to provide information on moho objects - for example which points are in which shapes; active channels in layers etc etc ... it's a diagnostic tool for Moho.
I think the ability to write 'test snippets' would be very useful, especially for learners who are not familiar with the API which at times is not very well documented. I will check it out, thank you.


As Wes pointed out, there are a few "gotchas" in the API. The introduction page in https://mohoscripting.com/ talks about those and gives a few "start here" ideas too.
Yes I was pleasantly surprised when I read it - it warns against the exact two pitfalls I had fallen in - lol :D . Very perseptive.
There's also a "build an empty script" tool on that website: https://mohoscripting.com/new_script
The "build an empty script" tool sounds very useful - I see its even got a video tutorial, I will check it out, thank you.
About your observation " Ensure you use : for table functions and . for table attributes otherwise you may crash moho" -- it _is_ possible to call functions using the "." notation - see the "Moho crashes but your code looks right!" section in the introduction page. This is very useful if you want to store the function and call it indirectly. e.g. to get the right type of channel object whatever channel you throw at it:

correctlyCastChannel = castChannel (moho, someUnknownChannel)

Only useful, ofc, if you want to use the AnimChannels / common (e.g. GetValue etc) attributes but pointless if you're looking for channel-specific stuff such as AreDimensionsSplit

Code: Select all

local function castChannel (moho, ch)
	local chCast = {
		{MOHO.CHANNEL_VAL, moho.ChannelAsAnimVal},
		{MOHO.CHANNEL_VEC2, moho.ChannelAsAnimVec2},
		{MOHO.CHANNEL_COLOR, moho.ChannelAsAnimColor},
		{MOHO.CHANNEL_BOOL, moho.ChannelAsAnimBool},
		{MOHO.CHANNEL_STRING, moho.ChannelAsAnimString},
		{MOHO.CHANNEL_VEC3, moho.ChannelAsAnimVec3}
	}
	local i, s

	s = ch
	for i = 1, #chCast do
		if ch:ChannelType() == chCast[i][1] then
			s = chCast[i][2](moho, ch)
			break
		end
	end
	return s
end

===
And ... there are many scripters active in this forum ... if you have a question - just ask!

Unfortunately I don't know enough Lua (or moho API) to appreciate the finer points, but I will come back to it once I have learnt more. That function looks very handy, but thinking aloud, I can't understand why we are so dependent on casting. For example in the example I cited previously (viewtopic.php?p=205133#p205133), how does moho 'forgets' its a group layer, when all the information is provided. We shouldn't need to cast in such unambigeous cases. Yes casting can be a very powerful tool for creating generic code which will work across many types, but in this case I get the feeling we are casting due to weaknesses in the API. I might be wrong as it might be more to do with Lua as a language - it seems to do a lot with a few keywords.. perhaps it relies on casting to achieve it.

Thank you for your insights, they are very helpful.
User avatar
synthsin75
Posts: 9975
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: General scripting advice

Post by synthsin75 »

ggoblin wrote: Tue Jun 07, 2022 9:38 pm
synthsin75 wrote: Sun Jun 05, 2022 10:45 pm I have a "Disabled" folder in the menu and tool script directories, so I can move older/working versions there while I make changes to an installed script. Moho doesn't read scripts from folders it doesn't know to look in. I just copy/paste it to the disabled folder and append a name on the script to describe the latest working feature/state. If I need to revert, I just move it back into the script folder and remove the appended name. Changing the extension works too. Years ago, I did just comment out code blocks, but that just leads to overly large scripts to navigate.
When I created a disabled directory off the scripts/menu directory and placed my disabled script in it, moho seemed to pick it up automatically. It created a new sub menu called disabled with my script inside it.. I suppose I could just ignore that extra menu folder? But I think everytime moho starts it checks all the scripts for syntax errors so am worried it might slow my start up process?
I just checked, and I only have a disabled folder in tools, not menu. I forgot that at some point Moho became aware of added folders in menu scripts. Yeah, if Moho can find it, it's namespace table and functions could conflict with other versions being developed. Menu scripts either tend to be simple enough for me to still just comment out code, or I use them as button scripts in the tool folder. Menu and button scripts are the same. Both use the "Run" function, but buttons need an icon for the tool bar.
User avatar
hayasidist
Posts: 3525
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: General scripting advice

Post by hayasidist »

ggoblin wrote: Tue Jun 07, 2022 9:55 pm I can't understand why we are so dependent on casting. For example in the example I cited previously (viewtopic.php?p=205133#p205133), how does moho 'forgets' its a group layer, when all the information is provided. We shouldn't need to cast in such unambigeous cases.
Specific channel types arrived in V12 - prior to that there was just the generic channel type - additional functional richness specific to certain channels (such as split dimensions) are a likely rationale for the change.
Specific layer types have been around a long time (for ever?). But yes - if the return type is documented as (e.g.) GroupLayer it seems strange to return generic layer type rather than a GroupLayer type.
ggoblin wrote: Tue Jun 07, 2022 9:55 pm I think the ability to write 'test snippets' would be very useful, especially for learners who are not familiar with the API which at times is not very well documented. I will check it out, thank you.
The version on mediafire is an early version that required the snippets to be included physically in the harness... the version I'm using now has them in separate callable files. As I said, I've made many refinements over the 10 years since the initial upload!
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: General scripting advice

Post by ggoblin »

ggoblin wrote: Tue Jun 07, 2022 9:38 pm

I use Notepad++ which has Lua syntax highlighting. I think it has option for extending that for APIs but it would need a list of Moho API keywords to do that.
Mohoscripting.com is brilliant, I justs found the Moho API syntax highlighting and autocompletion files for Notepad++ at

https://mohoscripting.com/npp_tools

Thank you for providing these, makes coding so much easier. :D
Post Reply