![]() |
Under The HoodThe Stuff That Doesn't ShowWelcome to the second part of our biased and opinionated tour of Cyborg scripts. Let's talk for a moment about structure.
|
I've seen three major schemes for organizing the overall code in users' Cyborg.ipt files:
(Okay, this isn't a complete quotation from the Cyborg.ipt file. Here's why.)
ON SIGNON { TICKS itk = botHold GLOBAL timeBase GLOBAL debugOn GLOBAL burning GLOBAL burnInt GLOBAL burnCt GLOBAL facM GLOBAL altM GLOBAL twinPW GLOBAL iptPW GLOBAL iptOn GLOBAL autoPos GLOBAL autoX GLOBAL autoY GLOBAL "\x3bwirf" iptPW = ; "\x3b" = semicolon "\x3bzoik" twinPW = 0 FALSE = FALSE NOT TRUE = FALSE debugOn = DATETIME timeBase = 200 burnInt = FALSE burning = 0 burnCt = FALSE autoPos = 0 autoX = 0 autoY = 9 facM = 8 altM = TRUE iptOn = ; end of global variable initializations |
That block of GLOBAL declarations is then copied to the INCHAT and OUTCHAT handlers, as well as any Macros etc that might use any of these variables.
The itk variable is NOT global, but something I use to keep track of operations inside of the ON SIGNON block, as we'll see below.After the variables come the shared global subroutines/functions:
; **************************************** ; *** Global Subroutines ***************** ; **************************************** ; return # of seconds since signon time GLOBAL { timeBase GLOBAL DATETIME timeBase - } time DEF ; number of Guests in current room count_guests GLOBAL { NBRROOMUSERS r = 0 result = 0 i = { { result ++ } i ROOMUSER WHONAME "^Guest " GREPSTR IF i ++ } { i r < } WHILE result } count_guests DEF ; return true if named user is in current room ; <name> find_name EXEC ; find_name GLOBAL { seekName = NBRROOMUSERS r = { 0 i = { { 1 RETURN } i ROOMUSER WHONAME seekName == IF i ++ } { i r < } WHILE } seekName "" == NOT IF 0 } find_name DEF ; return position of named user is in current room, or own pos if ; not found ; <name> find_pos EXEC ; find_pos GLOBAL { seekName = NBRROOMUSERS r = { 0 i = { { i ROOMUSER WHOPOS RETURN } i ROOMUSER WHONAME seekName == IF i ++ } { i r < } WHILE } seekName "" == NOT IF POSX POSY } find_pos DEF ; ; ...etc. ; There are quite a few functions here, then a wrapup: ; TICKS itk - ITOA " Ticks for SIGNON exec" & LOGMSG } |
which ends the SIGNON block. The itk timer
variable lets me know how long the entire SIGNON block took
to load, in 1/60th of a second "ticks."
Each OUTCHAT etc handler
then needs to have those global functions declared, too, e.g.,
time GLOBAL time_log GLOBAL find_name GLOBAL count_guests GLOBAL bot_say GLOBAL auto_pos GLOBAL leap_to GLOBAL glide_to GLOBAL burn_it GLOBAL aps GLOBAL n_prop GLOBAL costume_set GLOBAL |
My own habit for naming variables and
the like is to use multiple words with different separators to name
variablesWithCaps and functions_with_underscores.
Iptscrae ignores case, so don't make the mistake of thinking that,
say, "msX" and "MSX" are different variable names.
(Variables and functions used by the
BotBot are automatically scoped correctly)