Tintin++

From miki
Jump to navigation Jump to search

Tintin++ is a terminal-based MUD client, with support for scripting, timers (tickers).

Documentation

Links
Help
  • Manpages refer to a basic manual in /usr/share/doc/tintin++, but it is incomplete. Use #help to get help (#help tickers for instance).
Built-in
  • #help, #help some_command

Scripting

Math

#math myvar {1 + $somevar};

#nop Use 1d... to get random numbers:
#math mydice {1d6};

Define @math function (see below), for easier use:

#var {max} {100};
#showme {Welcome @math{1+1d$max} times.};

Frequent PITFALLS

See troubleshooting section for more.

Do not add brace after !

Don't add braces after ! operator.

#nop These expressions DO NOT WORK!;
!($someflag)
!($flag1 || $flag2)

Don't forget trailing semicolons after #nop

Always add trailing semi-colon ; to all commands, and in particular #nop, #if.

Don't add a dot after dereferencing a variable

The . has a special effect on variable name. It can be used to build nested variables. If a variable must be followed by a dot, escape it with a backslash (\.):

#showme {Added new name: $name.};          #nop FAIL!;
#showme {Added new name: ${name}.};        #nop FAIL too!;
#showme {Added new name: $name\.};         #nop Ok;

Lists are one-indexed

First element of list starts at one, not 0:

#math idx 1;
#while {$idx <= @len{schedule.hm}}
{
    #nop ...;
    #math idx {$idx + 1};
};

Remove empty space commands

These commands generate messages like #NO SESSION ACTIVE. USE: #session {name} {host} {port} TO START ONE.

An empty space command is trailing spaces after a final semi-colon. For instance

#nop This will trigger message '#NO SESSION ACTIVE. USE: #session {name} {host} {port} TO START ONE.'
#if {1} { #nop; };

To remove the message, remove the trailing space:

#if {1} { #nop;};

Surround dotted-variable with braces or use bracket

Like this:

#showme {${schedule.profile} set};    #nop CORRECT;
#showme {$schedule[profile] set};     #nop CORRECT;
#showme {$schedule.profile set};      #nop WRONG;

Miscellaneous

  • Embed variable in curly brace with & operator.
  • Make sure a variable exists before using it in an expression, or enclose it in quotes "..."
#if {!&{doesnotexist} || "${doesnotexist}" != "0"} {#showme {good};} {#showme {BAD};}
good
#if {!&{doesnotexist} || $doesnotexist} {#showme {good};} {#showme {BAD};}
good
#if {!&{doesnotexist} || ${doesnotexist}} {#showme {good};} {#showme {BAD};}
BAD

Boolean

  • Use &{var} to test if var exists, and !&{var} to test if var does not exist.
#if {&{iszero}} {...} {...};
#if {!&{doesnotexist}} {...} {...};
  • Undefined variables$doesnotexist evaluates to 0 if _doesnotexist_ is not defined.

Tips

Auto login

We add name and password to #session for auto-connect, and y if asked to restart a new session if forget to quit previous session on server.

#session discworld discworld.starturtle.net 23;MyName;MyPassword;y
#config {BUFFER SIZE} {300000}
#split
#log append discworld.log
#ticker idlechase {idlechase} {105}

Leave

Use #zap to zap all session and leave if last, or #end to leave all sessions.

quit
#end

RECEIVED OUTPUT vs RECEIVED LINE

  • Difference between events RECEIVED OUTPUT and RECEIVED LINE. _RECEIVED OUTPUT_ is triggered whenever the client receives some text from the server, _RECEIVED_LINE_ is triggered whenever the client prints a single line. The text contained in %0 in event RECEIVED OUTPUT may be truncated (waiting for more text from the server, see option PACKET PATCH), and may contain several lines (separated by newline characters).

Echo without terminating newline

  • To prevent printing terminating newline character with #line, just finish with a trailing \ (#line log {$logFile} {[$timestamp] \}).

Advanced Alias

To have an alias that matches all user input, use `%*` as the name.

#alias {%*} {#showme You wrote: %0}
Evaluation order
  • Aliases are ordered alphabetically and only one alias can trigger at a time.
  • To change the order you can assign a priority, which defaults to 5, with a lower number indicating a higher priority. The priority can be a floating point number.

Useful Functions

@math for inserting math in any context
#function math {#math result {%0};};

Now we can do

#showme {Here a random dice @math{1d6}, or 2 dies @math{2d6}.};
@len for taking length of a list variable in any context
#function {len}
{
    #list {%1} {size} {result};
};
@to_hm (eg. @to_hm{1;45}) and @timehm to process time
#nop Usage: @to_hm{1;45}
#function {to_hm}
{
    #math {result} {%1 * 60 + %2};
};

#function {timehm}
{
    #format {timeH} {%t} {%H};
    #format {timeM} {%t} {%M};
    #var {result} @to_hm{$timeH;$timeM};
    #unvar {timeH};
    #unvar {timeM};
};

Troubleshooting

  • Command not executed in script — Most probable cause is a missing semicolon, typically after #nop! All commands must be terminated with ;
#nop Call an alias                 <-- MISSING semi-colon
/myalias;                          <-- ... not executed

#action {^Some text} {
    #send {this}                   <-- MISSING semi-colon
    #send {that}
}

#action {^Some text} {
    #send {this};                  <-- Each command MUST be separated by semi-colons
    #send {that}
}
  • Output corrupted, bad escape sequences — Mainly due to packet being cut.
#CONFIG           {PACKET PATCH}  {1}

Troubleshooting boolean expressions

We use ! as NOT operator:

#if {0} {#showme {true};} {#showme {false};}
false
#if {1} {#showme {true};} {#showme {false};}
true#if {!1} {#showme {true};} {#showme {false};}
false
#if {!0} {#showme {true};} {#showme {false};}
true

However adding extra braces (...) after ! messes things up:

#if {!(1)} {#showme {true};} {#showme {false};}
false
#if {!(0)} {#showme {true};} {#showme {false};}
false

Using curly braces does not help either:

#if {!{1}} {#showme {true};} {#showme {false};}
false
#if {!{0}} {#showme {true};} {#showme {false};}
false

So conclusion:

  • Don't add braces after !.

Troubleshooting & operator

Let's combine ! with & operator:

#unvar {doesnotexist}
#var {iszero} {0}
#var {isone} {1}
#if {&doesnotexist} {#showme {true};} {#showme {false};}
false
#if {&iszero} {#showme {true};} {#showme {false};}
true
#if {!&doesnotexist} {#showme {true};} {#showme {false};}
false
#if {!&iszero} {#showme {true};} {#showme {false};}
false

So no dice. Let's add curly braces:

#if {&{doesnotexist}} {#showme {true};} {#showme {false};}
false
#if {&{iszero}} {#showme {true};} {#showme {false};}
true
#if {!&{doesnotexist}} {#showme {true};} {#showme {false};}
true
#if {!&{iszero}} {#showme {true};} {#showme {false};}
false

... much better!

So conclusion:

  • Always wrap & variable in curly braces.

Troubleshooting $ operator

Let's combine ! with $ operator:

#var {iszero} {0}
#var {isone} {1}

#if {!{$iszero}} {#showme {true};} {#showme {false};}
false
#if {!{$isone}} {#showme {true};} {#showme {false};}
false

The correct construction is either no braces or surround only variable name with curly braces:

#if {!$iszero} {#showme {true};} {#showme {false};}
false
#if {!$isone} {#showme {true};} {#showme {false};}
false
#if {${iszero}} {#showme {true};} {#showme {false};}
false
#if {${isone}} {#showme {true};} {#showme {false};}
true
#if {!${iszero}} {#showme {true};} {#showme {false};}
true
#if {!${isone}} {#showme {true};} {#showme {false};}
false

However using curly braces sometimes fail:

#if {!&{doesnotexist} || "${doesnotexist}" != "0"} {#showme {good};} {#showme {BAD};}
good
#if {!&{doesnotexist} || $doesnotexist} {#showme {good};} {#showme {BAD};}
good
#if {!&{doesnotexist} || ${doesnotexist}} {#showme {good};} {#showme {BAD};}
BAD