Tintin++: Difference between revisions
(One intermediate revision by the same user not shown) | |||
Line 47: | Line 47: | ||
If a variable must be followed by a dot, escape it with a backslash (<code>\.</code>): |
If a variable must be followed by a dot, escape it with a backslash (<code>\.</code>): |
||
<source lang="text"> |
<source lang="text"> |
||
#showme {Added new name: $name.}; |
#showme {Added new name: $name.}; #nop FAIL!; |
||
#showme {Added new name: ${name}.}; #nop FAIL too!; |
|||
#showme {Added new name: $name\.}; #nop Ok; |
#showme {Added new name: $name\.}; #nop Ok; |
||
</source> |
</source> |
||
Line 75: | Line 76: | ||
<source lang="text"> |
<source lang="text"> |
||
#if {1} { #nop;}; |
#if {1} { #nop;}; |
||
</source> |
|||
==== Surround dotted-variable with braces or use bracket ==== |
|||
Like this: |
|||
<source> |
|||
#showme {${schedule.profile} set}; #nop CORRECT; |
|||
#showme {$schedule[profile] set}; #nop CORRECT; |
|||
#showme {$schedule.profile set}; #nop WRONG; |
|||
</source> |
</source> |
||
Latest revision as of 15:25, 8 July 2018
Tintin++ is a terminal-based MUD client, with support for scripting, timers (tickers).
Documentation
- Links
- tintin++ manual
- tintin++ unofficial documentation (more complete than embedded help).
- In particular Data Types.
- 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
andRECEIVED 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