Skip to content

TinTin Samples

Kurt edited this page Jul 12, 2026 · 3 revisions

TinTin++ Setup

Audience: Player Status: ✅ Ready

Recipes for TinTin++ (tt++) — a fast, scriptable, terminal-based client that a lot of MUD players prefer. Unlike Mudlet, tt++ has no GUI: it drives everything from # commands in a terminal, and it ships a genuinely good built-in mapper. Everything below is illustrative — reach for the TinTin++ manual for exact syntax, since command details vary a little across tt++ versions.

How TinTin++ delivers GMCP

TinTin++ negotiates GMCP automatically when the server offers it (option 201). A received GMCP message raises a telnet-subnegotiation event, and you hook it with #event:

  • #event {IAC SB GMCP} {…} fires for any GMCP message — %0 is the module (package) name, %1 is its data.
  • #event {IAC SB GMCP <Module>} {…} fires for one package — %1 is its data.
#event {IAC SB GMCP Char.Vitals}
{
    #json gmcp_vitals {%1}
    #showme {HP %1 of what?  hp=${gmcp_vitals[hp]}/${gmcp_vitals[maxhp]}}
}

%1 is the package's raw JSON; parse it into a table with #json (then index it like ${gmcp_vitals[hp]}). See the GMCP Reference for every package and its fields.

Content-defined keys: the demo world's vitals are hp/mana (so hp/maxhp/mana/maxmana); a different content pack uses its own resource refs.

Auto-open the login link

When you connect, the gate prints your one-click OAuth link and waits for you to sign in (Player Reference → Connecting). An #action (tt++'s trigger) can spot it and hand the URL to your OS's browser opener:

#action {open this link in your browser} {#variable {telos_login} {1}}
#action {http%1}
{
    #if {"$telos_login" == "1"}
    {
        #script {_} {xdg-open "http%1" > /dev/null 2>&1 &};
        #variable {telos_login} {0}
    }
}

The first action arms a flag on the prompt line; the second catches the following URL line and opens it. Swap xdg-open for your platform's opener (open on macOS, start on Windows). The OAuth page closes itself after a few seconds and hands you back to the MUD.

Matching note: this keys off the gate's login screen text, which is engine code, not content — so a world changing its content (rooms, mobs, even its message of the day) leaves the trigger working; only a fork that edits the auth code's wording would need the pattern updated.

The built-in mapper

This is where tt++ shines: #map is a full automapper, no plugin required.

#map create 1000        // start a new map
#map goto <vnum> dig    // move to a room, digging (creating) it if new
#map map 12 40          // draw a 12×40 map to the screen
#map write mymap.tin    // save it

Rooms are created automatically as you walk, and #map flag nofollow explicitly supports GMCP-driven automapping. Drive it from the server's Room.Info package — its num is a stable per-room id and it carries coord and exits:

#event {IAC SB GMCP Room.Info}
{
    #json gmcp_room {%1}
    #map goto ${gmcp_room[num]} dig
    #map roomname ${gmcp_room[name]}
}

Vitals status line

tt++ has no floating gauges, but you can reserve a fixed status region with #split and render a vitals line into it, refreshed from the Char.Vitals event above (use #format to build a bar out of repeated characters, and #draw / a prompt row to place it). See #split and #format in the manual. A simple, no-split option is to just #showme the numbers whenever Char.Vitals changes.

Channels

The engine sends channel chatter both as text and, to GMCP clients, as Comm.Channel.Text ({channel, talker, text}) with the usable channel list in Comm.Channel.List — see GMCP Reference. You can hook it and, for example, colour or tag each channel:

#event {IAC SB GMCP Comm.Channel.Text}
{
    #json ch {%1}
    #showme {<138>[${ch[channel]}]<099> ${ch[talker]}: ${ch[text]}}
}

Placeholder — separate channel windows. tt++ is a single terminal; it has no dockable per-channel sub-windows like Mudlet's miniconsoles. Practical options today: split the screen into regions with #split, gag a channel from the main flow and mirror it into a #buffer or a log, or run tt++ inside a terminal multiplexer (tmux/screen) and pane it out. A first-class "one window per channel" recipe is not something the client provides.

Tab-completion

tt++ already tab-completes words it has seen in recent output, so item and mob names you can currently see are completable out of the box.

Placeholder — programmatic suggestions. tt++ has no equivalent of Mudlet's addCmdLineSuggestion, so there's no clean way to feed it a live keyword list from Char.Items GMCP for completion of items you haven't seen printed. If tt++ adds a suggestion API, this section will get a real recipe.


See the GMCP Reference for the full data surface, Player Reference for the non-scripted basics, and Mudlet Samples if you also use Mudlet.

Clone this wiki locally