Magsbot Class, Session 6
Saturday April 12, 2003 2pm VRT
note: added remarks or paraphrases are in [brackets] and/or italicized, and the order of some chat has been changed for clarity.

DLP Anne: hi all
Magine: hi
ZebLith: Hello :)
DLP Anne: was getting lonely here lol
Magine: wow, 3.4 out next week huh?
ZebLith: can't wait ^^
DLP Anne: so they say lol
Magine: well let me see now...what shall we talk about today? :D
Magine: any questions from last time?
ZebLith: no questions :)
Magine: either of you try experimenting or playing around with the bot since last time?
DLP Anne: im playing with the bot some  lol but i get frustrated easy
Magine: what kinds of problems you having?
DLP Anne: its  a blonde thing lol
Magine: lol :P
DLP Anne: nothing I cant work out its the distractions in dlp is all
Magine: ah yes, distractions...i understand completely :D
ZebLith: lol :)  Well, I have just set it up for simple things, such as it will report to the $owner when someone enters or leaves.  and allows you to set $owner  that's it so far...
Magine: well today i'm going to talk about the custom buttons
Magine: and then we could talk about the programming language some more, but there is really so much to it, it would take a dozen more sessions to cover all that, so
Magine: i'm  going to rely on you guys to give a hint about the parts that aren't making sense to you [or that you want to know more about].
Magine: i'm hoping you've both looked at the help pages, right?
DLP Anne: yes a bit
ZebLith: not throughly, but I have used them occasionally
Magine: but you have a pretty good idea how to find something you want to look up....what category to look under and so forth?
DLP Anne: yes
ZebLith: yeah :D
Magine: ok...good. i probably need to revise the help, add frames or something, but i'm not a web page guru :D
DLP Anne: they look fine to me  and I say if it works dont fix it lol
Magine: ok, good :)
Magine: well, anyway...on to the buttons
Magine: first let's create a new category tab on the actions panel for our experiments
Magine: just right click anywhere on the actions panel (any tab),
Magine: and choose category>add
Magine: and enter some name for the category
Magine: now on the new category tab, right click [on the page] and choose "new" [from the popup menu]
DLP Anne: im not able to right click hmmm
Magine: not able to right click?
DLP Anne: it wont let me
DLP Anne: like on the build tab  i try right clicking and nothing
Magine: you click on the page itself, not the tab, actually....maybe i wasn't using the right word
DLP Anne: gawd  nevermind I see now its gonna  be a bad day
Magine: what i meant was, it doesn't matter what tab is selected when you click
Magine: when creating a new category.
Magine: so you have your new category tab (page) now?
DLP Anne: yes
ZebLith: yes ^^
Magine: then right click on that and choose "new" to start editing  a new button
Magine: or, you can just press Insert when the tab is selected
Magine: try entering
Magine: say "hello world"
Magine: and click ok
Magine: (give the button some name of your choice, of course)
[Mags]: hello world
Magine: then click it
[Chilaou]: Hello World!
Magine: got it, anne? :)
DLP Anne: hmmm lol
[Eve]: Hello World.
DLP Anne: yup
Magine: there ya go :)
Magine: ok
Magine: now to edit the button to make changes, just right click the button or the button name, and choose Edit.
Magine: for now just cancel though, don't need to make any changes yet
DLP Anne: k
Magine: you'll also see on that popup menu, that you can save buttons individually, or save categories individually
DLP Anne: right
Magine: you can also copy, cut and paste buttons to transfer them between categories
Magine: or even between magsbot programs if you have two running at once
Magine: you can select multiple buttons for delete, copy and cut,
DLP Anne: cool
Magine: but you can only save one button at a time, even if several are selected
Magine: (hm, maybe i need to enhance that)
Magine: to select multiple buttons, you click on the button NAME, not the grey button icon itself
Magine: and hold down ctrl or shift, the same as when selecting multiple files in windows
Magine: if you do want to save multiple buttons, you can do so by saving a whole category to one file
Magine: using category>save, of course.
Magine: all button files, even when you only save one button, contain the category name as well as the button
Magine: so when you use the main File/Action Buttons/Merge Buttons menu
Magine: it will stick the buttons that you are merging or loading into the right category
Magine: let's do that just to show you how. first select the new button you created (click on the button name so it's highlighted)
Magine: then, either right click and choose "save", or just press F4
Magine: and save your button.
Magine: did that work ok?
DLP Anne: yeah
ZebLith: yes :)
Magine: ok, now right-click your button and choose delete
Magine: poof, it's gone.
DLP Anne: yes
Magine: to get it back, just use the File/Action Buttons/Merge Action Buttons menu
DLP Anne: cool its back
ZebLith: ah :D
Magine: you can also look at the button file with a text editor
Magine: although it isn't recommended that you edit it that way unless you are super careful
DLP Anne: no problem lol i wont touch it LOL
Magine: because there are some non-printing characters [in the .btn file] that separate the category and button names and code.
Magine: the behavior table file is also just a text file, btw
DLP Anne: yes I already saw it in edit pad
Magine: if you've loaded your button back in, now right click it and choose "copy" then right click the page again and choose "paste"
DLP Anne: cool
Magine: or you can just click the button name to select it, and press ctrl-insert to copy and shift-insert to paste
Magine: of course normally you wouldn't want a lot of copies of the same button, so after copying it, you would edit it and change the name
DLP Anne: right
Magine: as well as making whatever other changes you would want to make [in the button's code].
Magine: click shift-ins a few times and make a lot of copies of your button
Magine: then hold down the shift key and select all but one of them, and hit delete (just like deleting multiple files in windows)
[Eve]: Hiya Magine.
DLP Anne: lol oops
Magine: hi eve :)
Magine: ok, if all that is clear, now let's see how you can call buttons from other buttons.
Magine: create a second button on your category there, with a different name,
Magine: and in it put this:
Magine: clickbtn "MyButtonName"
Magine: (whatever name you gave your first button)
[Mags]: hello world
Magine: when you click the second button, it will activate the first one
Magine: try it :)
[Chilaou]: Ohayougozaimasu!
[Eve]: Hello world.
ZebLith: great :)
DLP Anne: aha
Magine: you can also use clickbtn in the behavior table to call on buttons
Magine: but in that case, you would also use the category name
Magine: like clickbtn "MyCategory/MyButtonName"
DLP Anne: ok I  have a question
Magine: yes anne?
DLP Anne: why would you click that one to activate the first one?  why not just cllick the first one?
Magine: well you will see as we get to more complicated examples
DLP Anne: ok
Magine: suppose you have some code that you want to use in several places
Magine: instead of putting it in each place, you could put it in a button and call that button from the different places
DLP Anne: ahhh ok
Magine: and i'll give you an example in just a few minutes
Magine: but right now i want to show you about passing variables between buttons
DLP Anne: k
Magine: again edit your original button, and change it so it says
Magine: say $x
Magine: instead of say "hello world"
Magine: then edit your second button, and before the clickbtn "mybuttonname", put $x="hello world";
Magine: oh btw, button names ARE case sensitive,
Magine: so if the name has capital letters in them, then put the name exactly as it is
Magine: ok, done that?
DLP Anne: hmmm yeah
Magine: now click the second button
[Mags]: hello world
Magine: your bot will still say "hello world" (or whatever phrase you chose) but now it will be getting the string from the second button
Magine: try it :)
DLP Anne: not working here
Magine: ok, what do you have in button one, exactly?
DLP Anne: yes first oone does
Magine: it should have, exactly:
Magine: say $x
Magine: and button two should have this:
Magine: $x="hello world"; clickbtn "ButtonOneName"
Magine: (whatever the first button name is)
[Eve]: Hello World
Magine: there ya go :)
DLP Anne: there  i didnt have the ;
[Chilaou]: Ogenki desu ka?
ZebLith: there :)
DLP Anne: konichiwa
DLP Anne: LOL
Magine: yes, you always need the ; between commands
ZebLith: lol :D
Magine: domo arigato :D
Magine: mr. bot-o
DLP Anne: lol thats all I know in japanese
Magine: ok, all clear so far?
ZebLith: hehehe ^^  yeah :)
DLP Anne: yes
Magine: so far what we've seen is the way buttons operated in old versions of magsbot
Magine: but in 4.0 i added some commands to let you call buttons as functions
Magine: which is even more useful.
Magine: when you use the clickbtn command, as you have seen, any variables (like $x) are passed into the button being called.
Magine: that is, ALL local variables created in the calling routine (either button or behavior table) are passed into the button [and all variables are passed back out of the button]
Magine: but you can instead use the FTN command ("ftn" = abbreviation for "function")
Magine: which will call the button, but pass only the variables that you list in the FTN command.
Magine: let's edit the second button again to see what i mean
Magine: in the second button, remove the $x="hello world";
Magine: and instead of
Magine: clickbtn "mybuttonname"
Magine: put
Magine: ftn "mybuttonname" "hello world"
Magine: then in the first button,
Magine: add at the top:
Magine: args $x;
Magine: so now your first button should have
Magine: args $x; say $x
Magine: and your second button should have
Magine: ftn "mybuttonname" "hello world"
Magine: got that?
[Mags]: hello world
Magine: once you have that, click the second button again
[Chilaou]: Bienvenue!
ZebLith: ah :D
[Eve]: Howdy Folks
DLP Anne: yup
Magine: :)
Magine: another thing that's good about the FTN command is
Magine: it doesn't pass variables back out, either, unless you want it to.
Magine: when you use clickbtn it not only passes all local variables into the button,
Magine: but any variables changed or created within the button are also passed out.
Magine: but when you use the FTN command
Magine: only the variables you specify are passed in,
Magine: and within the called button, only the variables you specify are passed back out
       [variables are passed back out using the RETURNS, RETURN or RETURN_ commands, see below]
Magine: so if the button uses a variable named $x for instance
Magine: it may be an entirely different $x than one outside the button
Magine: which is a good thing, since when you create a button intended to be called from somewhere else,
Magine: you don't need to worry about [variables inside the button] interfering with variables [outside the button]
Magine: does all that make sense? :D
DLP Anne:  it will in time lol
ZebLith: I think I understood it. ;)
Magine: ok, now let's try this
Magine: in the first button,
Magine: add this:
Magine: $z="some phrase of your choice"
Magine: (make sure you put the ; between the commands)
Magine: so now in the first button you should have
Magine: ARGS $x; SAY $x; $z="guess what?"
Magine: and in the second button add
Magine: report $z
Magine: so in the second button you should have
Magine: FTN "test" "hello world"; REPORT $z
Magine: ok, now before you try to click that to see what happens :)
Magine: here is a trick question for you
Magine: what do you think will happen when you click button two now?
[Eve]: Howdy Folks
[Mags]: hello world
ZebLith: You'll get an error I think...
DLP Anne: hmmm said variable not found
Magine: well you were supposed to guess first :P
Magine: but that's right, you got an error
DLP Anne: LOL
Magine: can you tell me why?
ZebLith: because $z doesn't exist yet, and it calls it before the first button can set it.
Magine: nope
Magine: $z definitely exists [inside the button]
Magine: any other guesses? :)
Magine: no? okay, lets do this to figure it out. let's create a third button, and in it, put this:
Magine: $x="hello whirled"; CLICKBTN "test"; REPORT $z
Magine: (assuming your first button is named "test")
Magine: now click that third button and see what happens
[Mags]: hello whirled
[Chilaou]: Bienvenue!
Magine: any error that time? [no]
ZebLith: ah
Magine: both the second and third buttons are calling the first button, but what is the difference?
Magine: the second button is using FTN and the third button is using CLICKBTN
Magine: so what does that mean? :)
Magine: are you baffled? :)  what does FTN do that CLICKBTN  does not do?
Magine: or vice versa? :D

[this is a bit of a side track here]
DLP Anne: mine isnt working
Magine: not at all anne?
DLP Anne: says test cannot be found
Magine: right, sorry, i said you should use your first button name instead of "Test"
DLP Anne: and it shut down
Magine: shut down? :O
Magine: the program shut down??
DLP Anne: yeah just closed on me lol
Magine: hmmm
DLP Anne: and my catagory is gone lol
DLP Anne: but go ahead I print these out so I will redo it later
Magine: yeah if the bot crashed and you hadn't saved the buttons [your changes will be lost].
Magine: press F7 to save all the buttons, BTW
DLP Anne: k
Magine: ok so anne,
Magine: create your category, and create three buttons
Magine: the first should contain
Magine: ARGS $x; SAY $x; $z="guess what?"
Magine: the second should contain
Magine: FTN "firstbuttonname" "hello world"; REPORT $z
Magine: and the third should contain
Magine: $x="hello whirled"; CLICKBTN "firstbuttonname"; REPORT $z
Magine: then press F7 to save that
Magine: i can't imagine why it shut down though :D
ZebLith: baffled? xD
Magine: anyway, while you are doing all that
Magine: zeb, any guesses why button three works but button two gives and error?
[Mags]: hello whirled
[Mags]: hello world
[Eve]: Hello World
Magine: well, it's simply because $z is created in button one, and when you call button one using CLICKBTN in button three, the $z gets passed out to button three
Magine: but when you call button one using FTN in button two, nothing gets passed out
Magine: so button three doesn't get the $z. [it exists only inside the button.]
Magine: does that make sense to you?
ZebLith: okay I think I have a question but I have to formulate it correctly... ;)
ZebLith: oh wait, I see.  scratch that.  NOW things make sense. ^^
Magine: anne how about you? do you understand what's going on here? :D
DLP Anne: sorta yes :)  im a tad slower than Zeb but i will catch on
Magine: ok, so now how could we fix button one so it would pass $z back out? answer: we would use the RETURNS command.
Magine: so edit button one, and add
Magine: returns $z
Magine: (remembering that ; between commands as always)
[Eve]: Hello World
[Mags]: hello world
[Mags]: hello whirled
[Chilaou]: Bienvenue!
DLP Anne: cool
ZebLith: oh, okay.  :D
Magine: now you will get rid of that error.
Magine: you can use the RETURNS command to pass out several variables too [not only one]
Magine: you could have RETURNS $z @n $x
Magine: whatever variables you want to pass back out
Magine: (assuming the variables exist that is)
Magine: now there is another way you can pass variables out also
Magine: using either the RETURN or RETURN_ commands
Magine: what those do is to pass back a single value.
Magine: to show you how that works,
Magine: create a fourth button
Magine: and in it put this
Magine: $z=$ftn["test","hello world"]; REPORT $z
Magine: (replace "test" with the name of the first button we created)
Magine: then also edit the first button, and change RETURNS $z to RETURN $z
[Eve]: hello world
Magine: then try the new, fourth button.
[Mags]: hello world
[Chilaou]: Mondes Actifs
[Eve]: hello world
Magine: acutally, let's change button four again
Magine: make it just say this
Magine: report $ftn["firstbuttonname","hello world"];
Magine: that's a better example
[Mags]: hello world
[Mags]: hello world
[Mags]: hello world
[Eve]: hello world
[Chilaou]: Mondes Actifs
Magine: in that case, you would still get an error if you tried to report $z, because $z isn't being passed out (once you remove the RETURNS command)
Magine: instead, the value of $z is being passed out as the value returned by the button itself.
Magine: if want the button to return a number instead,
Magine: you would call it using @ftn instead of $ftn
Magine: and use RETURN_ instead of RETURN in the button being called.
Magine: so, to review....
Magine: if you call a button using CLICKBTN,
Magine: it passes all variables in, and all variables back out.
Magine: and if you call a button using the FTN command, and use the ARGS command within the button,
Magine: then only the variables you specify are passed in,
Magine: and only the variables that you specifiy within the button using the RETURNS command are passed out.
Magine: and finally, if you call the button using $ftn or @ftn, then only the variables you specify are passed in,
Magine: and only the variables that you specify using RETURNS are passed out, as well as a single value that you specify using RETURN or RETURN_
Magine: i guess that's getting pretty confusing now huh? :D
DLP Anne: yeah for me it is
ZebLith: a little... ^^;
Magine: oh and also...
Magine: with the ARGS command, you don't need to use the same names as the names of the variables being passed in...you can rename them, so to speak
Magine: like if you call the button with FTN "buttonname" 12 "testing"
Magine: and have ARGS @n $x within the button
Magine: then the button will get variables @n and $x, containing values 12 and "Testing".
Magine: another thing,
Magine: with RETURN and RETURN_, you are passing back a value,
Magine: whereas with RETURNS you are passing back variables
Magine: so you could not do
Magine: RETURNS 12
Magine: or RETURNS "testing".
Magine: well, no doubt i have lost you completely :D
Magine: maybe it will become clear with some practical examples
Magine: first let me explain about the button names in different categories.
Magine: if the button you are calling is in the same category, as we've been doing,
Magine: then you only need to use the button name.
Magine: but if you want to call a button in another category,
Magine: then you need to use the category/name
Magine: for instance,
Magine: on the Chat category tab, there is a button named [SayLong]
Magine: let's now create another button in our test category
Magine: and in it, put this
Magine: ftn "Chat/[SayLong]" "this is a test"
Magine: (if you left the "Chat/" part off, then you would get an error saying the [SayLong] button couldn't be found, when you clicked your new button)
[Mags]: this is a test
Magine: try the new button
[Chilaou]: This is a test. :D
Magine: all the [SayLong] button does is to break up really long strings into several smaller ones
Magine: so if you want the bot to read a really long string, that would otherwise cause an error with the AWB
Magine: you can use the [SayLong] button
Magine: as a function, that is
DLP Anne: sheesh again mine not working and I  have it axactly like you said
Magine: ok, you created a new button that had exactly this:
Magine: ftn "Chat/[SayLong]" "hello world"
Magine: in it?
[Eve]: Hello World
Magine: there ya go :)
DLP Anne: hmmm no I had this is a test lol
Magine: well whatever, that doesn't matter :D
DLP Anne: as you all can see im stuggling on this one
Magine: "this is a test" should work too :D
Magine: i know it's difficult
DLP Anne: it didnt tho lol worked when I put in hellp world
Magine: i take it for granted because this sort of passing of variables in what most all programming languages do some way or other, so it's a familiar concept
Magine: it didn't work?
Magine: you had quotes around it?
[Mags]: help world
DLP Anne: no when I changed This is a test  to Hello world it worked
Magine: change it back to "this is a test"
[Mags]: this is a test
[Eve]: This is a test
Magine: there ya go :)
DLP Anne: well dang now it does
DLP Anne: weird
Magine: maybe you left off a quote the first time?
DLP Anne: maybe  hmmm
Magine: anyway you see how you can use buttons as functions this way
DLP Anne: yes
Magine: oh BTW, you'll noticed many button names have brackets around them
Magine: the brackets mean that the button is not designed to be clicked on directly,
Magine: but only to be called as a function the way we've been doing today.
Magine: for instance, if you clicked on the first button we created today,
Magine: you would get an error message,
Magine: because it's really designed to be called as a function, not clicked on directly.
Magine: so normally you'd probably put it's name in brackets
Magine: both in the button name itself
Magine: and also when calling it
Magine: so, anyway....
Magine: as i was showing you, when you call a button from another category,
Magine: or anytime you call a button from the behavior table,
Magine: you would put the full name, including the category
Magine: like Chat/[SayLong], etc.
DLP Anne: k i understand that part
Magine: the one exception is buttons in the root or . category
Magine: you can call them from anywhere without the category name
Magine: let's do one more button as an example
Magine: suppose you're doing something and you want the bot user to choose the name of a nearby person
Magine: you can use the [PickAv] button in the root category to do that.
Magine: let's create a new button now, and in it, put this:
Magine: REPORT $ftn["[PickAv]"]
Magine: then click that button
Magine: as you will see, it presents a list of nearby avs and lets you pick one, then it returns that name
DLP Anne: yes
Magine: instead of REPORT, you could assign the result to a variable for your routine to use, like
Magine: $x=$ftn["[PickAv]"]
Magine: let's do something practical for another example
Magine: edit the new button and change it to this:
Magine: $x=$ftn["[PickAv]"]; @av=@sessionof[$x]; say $fmt["%s is at %s, %s",$x,@avz[@av],@avx[@av]]
[Mags]: [Eve] is at 15853, -775806
Magine: then click it
Magine: what it does is:
Magine: first [PickAv] lets you choose a name
Magine: then the @sessionof function gets the avatar session from that name
[Chilaou]: ZebLith is at 15049, -774395
Magine: then the say command reports the coordinates of the av
Magine: using the @avz and @avx functions.
Magine: @avz and @avx (and @avy and @avyaw) get the avatar's position from the session number.
        [the @avz, @avx, etc. functions actually retrieve location data
         that magsbot stores during AVATARCHANGE events]
Magine: z=north/south,  x=west/east,  y=up/down
Magine: those are in SDK coordinates, but you could use the $AWB function to translate them.
DLP Anne: when I try toi save  it says numeric value expected
Magine: ok, does it say exactly
Magine: $x=$ftn["[PickAv]"]; @av=@sessionof[$x]; SAY $fmt["%s is at %s, %s",$x,@avz[@av],@avx[@av]]
DLP Anne: yeah
[Mags]: DLP Anne is at 16553, -775720
[Chilaou]: [Gardener] is at 21000, -775000
Magine: (to [Eve]) version
[Eve]: Magsbot 4.0 b23 - AW SDK Build 31 - Bot Bone Build 11
Magine: anne, press F5, type
Magine: enlist control magine
Magine: say when :)
DLP Anne: when
Magine: eve do $x=$ftn["[PickAv]"]; @av=@sessionof[$x]; SAY $fmt["%s is at %s, %s",$x,@avz[@av],@avx[@av]]
[Eve]: Your wish is my command!
Magine: eve do say $error
[Eve]: Avatar not present: @sessionof[$x]««
[Eve]: Your wish is my command!
[Eve]:
Magine: oh yeah, duh, i can't do it that way, someone has to pick an av :D
Magine: eve do $x=Magine; @av=@sessionof[$x]; SAY $fmt["%s is at %s, %s",$x,@avz[@av],@avx[@av]]
[Eve]: Your wish is my command!
[Eve]: Magine is at 16053, -774671
Magine: i don't think you have the right stuff in the button, anne
Magine: $x=$ftn["[PickAv]"]; @av=@sessionof[$x]; SAY $fmt["%s is at %s, %s",$x,@avz[@av],@avx[@av]]
DLP Anne: ok let me look again
Magine: copy and paste that :)
[Eve]: DLP Anne is at 16553, -775720
Magine: there ya go :)
DLP Anne: must of had a typo somewhere
[Mags]: Magine is at 16.053N 16.053W -774.671a -71.2, 0
[Eve]: ZebLith is at 15061, -774415
DLP Anne: haha cant hide now
Magine: if you want regular AW coords, change it to
        $x=$ftn["[PickAv]"];
        @av=@sessionof[$x];
        SAY $fmt["%s is at %s",$x,$AWB[@avz[@av],@avz[@av],@avx[@av],@avyaw[@av]]];
[Mags]: DLP Anne is at 16.553N 16.553W -775.72a -216.9
[Mags]: ZebLith is at 15.061N 15.061W -774.415a -27
[Eve]: Magine is at 16.053N 16.053W -774.671a -71.2
Magine: and to add a bit of error checking,
Magine: [add this:]
        $x=$ftn["[PickAv]"];
        if @eq[$x,""]{break};
        @av=@sessionof[$x];SAY $fmt["%s is at %s",$x,$AWB[@avz[@av],@avz[@av],@avx[@av],@avyaw[@av]]];
Magine: that way if the user doesn't pick any name, you won't get an error message.
[Eve]: Magine is at 16.053N 16.053W -774.671a -71.2
Magine: is it clear how that works?
DLP Anne: yes
Magine: ok, we've gone past our scheduled time....
DLP Anne: yeah i see lol  this gets intense
Magine: if you want some homework, try this sometime:
Magine: take a look at what's inside the [PickAv] button on the . tab
Magine: and see if you can figure it out :D
DLP Anne: LOL
Magine: and i'll explain it next time :)
DLP Anne: ok
ZebLith: heh... okies ^^
Magine: if there is something in particular that doesn't make sense, feel free to post on the forum
DLP Anne: kk
Magine: i'll be sure and check it this week since i'm sure i've confused you both :D
DLP Anne: lol
ZebLith: hehe ^^
Magine: alrighty, time for me to go get some sun :)
Magine: bye for now, and thanks for coming :)
ZebLith: thanks again Magine ^^
DLP Anne: bye Magine and thanks for all :)
Magine: yw zeb  and anne :)
Magine: bye bye, poof :)



Since this class might have been a little confusing, I've added an alternative explanation below...

The CLICKBTN and FTN commands both allow you to activate buttons on the actions panel from within your program.

With both of these commands, when using them from within the behavior table you should specify the category tab name as well as the button name, unless the button is in the root "." category.  Like this:

CLICKBTN "SomeCategory/MyButton";
or
FTN "SomeCategory/MyButton";
When using CLICKBTN or FTN within a button (as opposed to the behavior table), you can leave off the category name if the calling button is in the same category as the button being called.

The difference between CLICKBTN and FTN (FTN is for "function") is that when you use CLICKBTN, all local variables are passed to the button, and all local variables are passed back out, including any variables that are created in the button itself, or any changes that are made to variables in the button. But when you use FTN instead, then no variables are passed in. Only the values (not variables) that you specify are passed in, and those are renamed for use within the button. Also, FTN does not pass back any variables unless you specify them using the RETURNS command (explained below). The reason for this is so that when you use FTN, you don't need to worry about variables within the button changing the variables outside of the button, so you don't even need to care what variable names are used within the button.

How FTN works is like this:

FTN "SomeCategory/MyButton"  $x 12 "some string";
Within the button that FTN is calling, you would use the ARGS command to assign names to the values being passed to it:
ARGS $z @n $s;
The value of $x that was passed by the FTN command would be stored in $z within the button. Likewise, @n would be assigned 12 and $s would be assigned "some string" within the button. If you create some variable named $x within the button, it will be an entirely different variable that will have no effect on the variable $x outside the button. Of course you could have used ARGS $x @n $s, but I used a different variable name ($z) for the first argument in the example to show that it doesn't matter, the name within the button is unrelated to anything outside the button.  (ARGS is for "arguments", which is another word for "parameters" that are passed to a function, in programming lingo.)

If you want to pass variables back out of the button called using FTN, then you can use the RETURNS command within the button to list the variables to be passed back, like this:

RETURNS $s @n;
In the example above, $s and @n would be passed back to the calling routine. Note that it is variables and not values being passed back, so something like this:
RETURNS  128  "blah";
...would make no sense.

Yet another way you can call action buttons is by using the @ftn and $ftn functions. These act exactly like the FTN command, except with the additional ability of passing back a single value directly.  The @ftn function passes back a numeric value and the $ftn function passes back a string value, from the called button.

For example, you would use @ftn like this:

@v=@ftn["SomeCategory/MyButton",$x,12,"some string"];
And within the button, you would pass back a value that will get assigned to @v outside the button, by using the RETURN_ or RETURN commands. (You would always use RETURN_ with @ftn to pass back a numeric value, and RETURN with $ftn to pass back a string value.) For example, within a button called using @ftn you might put:
RETURN_ @m
Note that unlike the RETURNS command, you are passing back a value, not a variable, so this would be equally valid:
RETURN_ 12;

Or even this:

RETURN_  6+12/8;

Also (unlike the RETURNS command), RETURN and RETURN_ only pass back a single value.

To avoid confusing people who may be familiar with the C "return" statement, let me point out that in Magsbot the RETURNS, RETURN and RETURN_ commands do not cause the button to be exited at that point, they only specify what is going to be passed out when the button code does finish. You would use the BREAK command (outside of any loops) to exit the button early.  Also note that only the first call to RETURNS, RETURN_ or RETURN that is executed will be significant. If you assign one value using RETURN then assign another value later in the code, the second assignment will be ignored.

Another thing to note: if you pass values to a button and neglect to have an ARGS command, or if your ARGS command doesn't include names for all of the values passed in, then no error message will be given when the button is called, but, of course, the unnamed values won't be available within the button and may cause an error message when the button tried to use them.  Similarly, if you specify variable names using an ARGS command and do not actually pass anything in to assign to those variables, there will be no error message when the button is called, but the variables in the ARGS command that weren't assigned anything won't exist within the button, and you will get a "variable not found" error message if you try to use them.  However if you want to create a button with optional arguments, you could check within the button to see if the variable got assigned, and if not, assign it some value within the button code. Like this:

FTN "SomeCategory/MyButton"  47 "foobar";
And within the button:
ARGS @n $x $z;
IF @isvar[z]=0 {
   $z="" };
In the above example, the ARGS command within the button expects three arguments, that will be assigned to @n, $x and $z; but only two arguments (47 and "foobar") are passed to the button, so within the button $z is unassigned, until it gets assigned a value within the button.


I hope that clarifies the above lesson somewhat. :)