Tips for Programming SM

edited November 2009 in ScreenMonkey General
Here are some programming tips that might help someone else out there trying to write macros for ScreenMonkey (SM)

1. If your script won't execute, check the game log to see if SM detected an error. Many times SM does but it does so silently. Instead of beeping at you and then stopping (like compilers usually do), SM will continue to execute nine times out of ten.

2. If your script won't execute - does it echo back your "Action" command? Many times, SM will just print "X says Y". This means that your routine did not function at all. This could be because of a typo, program error, or something else. It is a bit frustrating to have SM just say this but at least you are getting some kind of feedback on what is happening.

3. If your script will print the "Action" command (like "X reports") but nothing else - it is usually because there is a problem with your script's syntax. For me, the thing that gets me is that Javascript uses the plus (+) sign to add strings together whereas VBScript uses the ampersand (&). Be sure you are using the right syntax.

4. Microsoft has an entire section of their website dedicated to how to use VBScript. When you are going to be programming in VBScript - be sure to bring this resource up on another web page so you can refer back to it.

5. Subroutines CAN be called with parenthesis. However, SM will sometimes complain that you can not do this. The answer is to use the CALL statement in front of the subroutine. The weird thing is - some subroutines WILL allow you to use parenthesis and some will NOT. Those that will - just call them. Those that won't - use the CALL statement.

6. Functions can be called from within SM. Use the:

function F(<args>)
<Do something>
F = <something>
end function

...setup and then just call it via the:

myvar = F(<args>)

7. Sometimes SM will (for no apparent reason it seems) barf on trying to call your functions or subroutines. The trick here is to ensure that you did not accidentally put extra spaces, misspell the sub/function name, and so forth. These little things will bite you quickly and leave you scratching your head over what is going on as well as make it seem that SM just doesn't like you. :-)

8. It is BEST to always start from scratch when writing a sub/func. What I mean is - I gathered everything at the front of my program (ie: curSession, curPlayer, cur....etc). However, it is much better to encapsulate subroutines so that they do not need any outside information. Just pass in the parameters (like maybe what player you are looking for).

9. Make use of the PUBLIC command when dealing with arrays. It is much easier to say:

public thePlayers(100)

than it is to try to pass the array in to a subroutine and then get it back out. Using the PUBLIC command makes the array available
to any sub/func.

10. When writing subroutines, first write a routine to split up the incoming request. An easy way to do this is:

public aOpts(100)
public nOpts

sub getOpts( myLine )
nOpts = 0
while( len(myLine) > 0 )
p = instr( " ", myLine )
s = left( myLine, p-1 )
myLine = mid( myLine, p+1, len(myLine) )
nOpts = nOpts + 1
aOpts(nOpts) = s
end sub

(The above is off the top of my head.) What the above does is to split up the line based upon spaces. So if you say "/m this is a test" (where "/m" is the program's name) then aOpts is populated with "this", "is", "a", and "test". It is a simple parser but powerful because you are not having to guess what is where. If something isn't in the proper array location, then you just generate an error and post that. Also, you always know that - baring someone trying to break the parser - aOpts(1) will always contain the main command. So if you wanted to list out all of the players you would use something like "/m lp" to "L)ist P)layers". Your subroutine to do the actual listing would contain ALL of the commands to do so as well as it would generate any/all output. All your main program would do is:

if( aOpts(1) = "lp" )then
call listPlayers()
end if

*Note the "return". This ensures that your program only does the one thing and then returns to SM. You could also put everything into a SWITCH statement where each option is checked, executed, and then the program just returns.

11. Last, but not least, remember that you are generating HTML. Not ASCII output. So carriage returns and line feeds will be ignored. VBScript gives you three variables (CR, LF, and CRLF) to insert carriage returns and line feeds but neither of them work with SM. Instead, you have to use <BR> and <P> to do single and double line breaks. (I got very frustrated with the above until I realized what my problems were.)

I hope this helps. :-)


  • Here is a code snippet on my thing about the PUBLIC command:

    public aPlayers(100)
    public nPlayers
    public aOpts(100)
    public nOpts

    Here I am making two arrays (aPlayers and aOpts). Then I have two variables which will contain the count of how many entries there are (ie: nPlayers and nOpts). These are placed BEFORE your first SUB command, like so:

    public aPlayers(100)
    public nPlayers
    public aOpts(100)
    public nOpts

    sub m()
    on error resume next

    . . .
    end sub

    This makes these variables accessible from anywhere within your set of subroutines.
  • All ScreenMonkey (SM) programs have to be edited in a plain text editor. Some people use Notepad, some Notepad+, others PSPad, and I prefer VIM. VIM is a throwback to the pre-graphical interface era. It is simple to use (I=Insert, A=Append,O=Open a line for input, YY=Yank, P=Paste, etc...), fast, and can even page files in and out of memory. Which ever editor you use though, you will probably need to get a program from Microsoft called "Command Here". Command Here allows you to open up a command line window in a folder of your choice (rather than having to do the Start->Run->cmd.exe command).

    SnapFiles (formerly known as Web Attack) at (or has another command line program from someone that is even better than what Microsoft has done. This version of the "Command Here" program will let you open a command line window (dos prompt, command prompt, or whatever you want to call it) anywhere (well - not inside of another program - but just about anywhere else).

    So a great thing to do is to move to the folder where the scripts are located, right-click, open a command line window within that folder, and then begin editing your scripts. In this way, you can have SM up and running, pop over to the command line window, make changes, go back to SM, F9 them (ie: load them in), and try them again. This makes it really fast to do development work. Of course, if you use Notepad or one of those "other" editors instead of vim - you could just have that up at the same time too. The big difference between vim and those other editors is the it only takes three letters to jump from one file to the other (":n #"). Also, you can try executing your script from within vim via vbscript. So you can check for syntax errors in that way and then try them in SM afterwards. (Or not - either way is ok.)

    To me, the big drawback of other editors versus vim is that vim is almost totally keyboard based. Thus, you don't have to take your hands away from the keyboard in order to use it. Have fun! The only big thing to remember here is - VBScript is plain, ASCII text. So using something like Microsoft Word will mess up your files very quickly. Stick to the simple stuff!

Leave a Comment