Server Customization


First off, throw out the installation instructions in the README. Trying to make them mesh with the ones that included the watchdog, wd, just caused me to end up with a confusing mess. I had log folders everywhere. I had a DB when I booted without wd but got a new one when I booted with it. It was a disaster. So don't even run anything just yet.

A quick note about wd. wd is a watchdog utility that will usually restart netmare if it crashes. It's really handy to have, as your players don't have to sit around waiting for an admin to show up and fire the game back up if something goes horribly awry. Not that it happens very often, but it can happen. It's well worth using.

  1. Compile netmare. I assume you've done this already. If not, see my CompilerNotes.
  2. Compile and install wd, the watchdog.
    • cd src/utils
    • Edit wd and change #define MUD_PROGRAM "../bin/netmare" to #define MUD_PROGRAM "netmare", we'll make sure that netmare is in the current path so that the relative path isn't required. There's a reason for this change and it's related to symlinks and mentioned in slightly more detail later on
    • make wd
    • cp wd ../../bin/ - put the compiled wd in the bin/ directory with netmare
  3. Set up the bootmare script to launch wd and thus netmare
    • cp src/bootmare ~/ - Assuming you want to launch TinyMARE from ~/, this is what I do. (Adjust source path or cd to somewhere you can find the src/ directory)
    • Edit your new ~/bootmare script, I prefer vim, you probably prefer emacs. I'm not sure I like you any more
    • This is what my bootmare script looks like, there's quite a bit changed from the original. There are reasons for all the changes. I'll go over them after you take a look at the script
# MARE Startup File  - updated May 18 2003  Gandalf
#                    - expanded Feb 21 2017 QBFreak

echo "NetMARE Starting up..."
cd ~/mare/mare1.0.10339 || exit 1
cd bin || exit 1

cd ../run || exit 1
rm -rf logs.bak
if [ -e logs ]; then
  mv -f logs logs.bak
mkdir logs

wd $* && echo "Started."
/bin/ps -e | /bin/grep "netmare" > /dev/null && echo "Online!"

  • The first thing we do is make sure the current mare directory exists. I've reported a few bugs and had them fixed, so I've had a few different versions of TinyMARE. I deal with this by putting them all in a single mare directory, along with my run/ and then symlinking run/ into each version so I can switch back and forth quickly should I need test (for my test server) or should there be a problem on my live server. All I have to do is tweak the version number in bootmare and everything is switched over.
  • Next we cd into bin/ and make sure it exists as well, the reason for that will become clear in a moment
  • Saving the current path from pwd into MAREPATH allows us to get an absolute path to bin/ instead of a relative one. This is necessary if symlinks are used. Trying to use a relative path to bin/ (../bin) out of the symlink'd run/ directory resulted in an error, because bin/ didn't actually exist in the real location of run/. The easiest way around this is to just grab the absolute path, and pwd lets us do that
  • Next we make sure that run/ exists. This ultimately needs to be our current working directory when we launch netmare, hence the reason we went and collected a path to bin/ earlier
  • If backup logs exist delete them, move the existing logs to the backup logs
  • Set the PATH to MAREPATH so that we can find wd and netmare without specifying any paths
  • Launch wd, which will in turn launch and manage netmare, passing along any command line parameters. If it succeeds, notify the user that it started
  • Check and see if netmare remained running, if there was a db problem or it couldn't open the port it will immediately exit, but the above command will still show success

That's it! Now you can launch the bootmare script and regardless of what folder you are in at the time, it should always find the correct run/, so it never loses the db and other files or creates new logs/.

Customizing TinyMARE

There are a couple of external services you can turn on for TinyMARE. The port definitions to turn them on or off are located in the file run/etc/portmap. From there you can also change the main port the game uses. The portmap file is pretty explanatory. Here's an except:

# This file holds a list of ports that are automatically turned on when the
# program finds and loads the database. Currently supported are the following:
#   game - Default login screen where anyone can connect to the game.
#  admin - Separate port allowing only administration to connect through.
#   http - Supports HTML 1.0 requests.
#   mesg - Prints a message at login and disconnects user.

game            4986
admin           4981
http            7350
# mesg          6666    msgs/noentry.txt

I encountered two gotchas. The first is that when I enabled http alone, it caused the game to revert to the default port. I ended up specifying the game port as well instead of leaving it commented out. The second is that the port number portmap uses for admin is 23, which is the default telnet port, and since I wasn't root I couldn't open a port that low. The portmap actually details the ranges of ports that you can open without root, and which ones require root.

I turned all of the services on for my test server. The admin interface provides a login without the standard greeting, just a simple username/password prompt and straight into the game. It does not allow for player creation or guest users. I have not tried, but I assume it also has a restriction by class on who can use it.

The HTTP interface just provides a listing of who is online. It looks just like the who command in-game, however if there is any code in any of the displayed attributes (@poll, @doing) it will not be parsed.

The one interface I have not tried is mesg, but it seems straight forward. You could set up a couple of different portmap files, with the ports swapped around, so that when your MARE is closed for maintenance users connecting to the standard port get a message about it, but admins can still connect through the admin port.

Add on software for TinyMARE

So you've got your server up and running, everything is great, but there's all those annoying _log channels. You don't want to totally ignore them, you can send them off to another terminal window or a totally separate world in your client without getting into complex triggers and all sorts of craziness (which I've tried on TinyFugue, and while really cool, is also really brittle and messy, plus I really want them in a separate window). All of TinyMARE's _log channels end up in individual log files in run/logs. We can combine this with the tcpserver utility from the ucspi-tcp suite to create a telnet server that serves up each log file, live to one or more clients concurrently. Combine this with Gnu screen and you can use telnet or PuTTY to switch between all of the logs in one window. Here's what I've got set up:

First you need ucspi-tcp. You can either download it, or if you have root access use your package manager to install it. I was able to use apt to install it on my Ubuntu PC, although for kicks I downloaded and compiled it from source on my Raspberry Pi 3 (Yes, TinyMARE runs just fine on a Raspberry Pi). I did run in to some issues compiling it, apparently most (all?) of the *.c+ files needed me to add =#include . If you get errors when you go to make it about errorno, this is what is wrong. Download the attached source from the bottom of the page and use my corrected version instead if you want to save yourself some editing.

Now that ucspi-tcp is installed, it's time to edit the bootmare script to fire up an instance of tcpserver for each log file from TinyMARE that you're interested in monitoring. Edit bootmare and append the following lines to the end: (alternatively, download the attached file from the bottom of the page)

cd logs || exit 1

tcpserver -q -RHl0 7324 tail -f main &> /dev/null
tcpserver -q -RHl0 7325 tail -f io &> /dev/nul
tcpserver -q -RHl0 7326 tail -f error &> /dev/nul
tcpserver -q -RHl0 7327 tail -f commands &> /dev/nul

  • The first thing we do change to the logs/ directory so we can find all the log files. This also gives the script a chance to exit if it can't find them for some reason
  • Launch a tcpserver for each log file that you want to monitor. tcpserver is designed to serve up a program, so I'm using tail -f to feed it the log file. the & ensures that each instance runs as a background job and > /dev/null keeps bash from cluttering the screen with the job info
  • The log files main, io, and error correspond to _log_main, _log_io and _log_err, respectively. The last one, commands, logs all of the commands run by TinyMARE, be it something typed by a user, or a triggered attribute. This is a really handy debugging tool IMO, plus it gives you a nice clue that the game is running properly based on the frequency of the output. I suggest you leave it in and give it a shot, but it's up to you.

Now that the servers are all set up we need to set up an rc file for screen to consolidate our clients. Fire up vim your favorite text editor (there you go with emacs again, darn you) and create this file: (or just download it from the attachments at the bottom of the page)

hardstatus string '%{= Kd} %{= Kd}%-Lw%{= Kr}[%{= KW}%n %t%{= Kr}]%{= Kd}%+Lw %-= %{KG} %H%{KW}|%{KY}%101`%{KW}|%D %M %d %Y%{= Kc} %C%A%{-}'
hardstatus alwayslastline
defmonitor on
bindkey "^[" select 0
bindkey "^[[11~" select 1
bindkey "^[[12~" select 2
bindkey "^[[13~" select 3
bindkey "^[[14~" select 4
bindkey "^[[15~" select 5
bindkey "^[[17~" select 6
bindkey "^[[18~" select 7
bindkey "^[[19~" select 8
bindkey "^[[20~" select 9
bindkey "^[[21~" select 10
bindkey "^[[23~" select 11
bindkey "^[[24~" select 12
screen -t "_log_main" telnet 7324
screen -t "_log_io" telnet 7325
screen -t "_log_err" telnet 7326
screen -t "cmdhist" telnet 7327

  • hardstatus provides a nice status line at the bottom of the screen. I did not come up with this hardstatus string on my own, I swiped it off of a Stack Overflow answer that I've since lost, otherwise I'd attribute it.
  • defmonitor on defaults monitor on for all new screens. This is needed for the activity notification for background screens
  • All of these bindkeys bind the ESC and Function keys to screen 0 through screen 12. You may find that your Function keys produce different output than mine did, in which case you'll want to modify these bindings
  • The screen statements create our screens and launch telnet sessions to the various log files. Note the IP and port numbers at the end. You'll want to change these to match your set up. The -t "title" option for screen lets you name each screen, this will show up at the bottom on our hardstatus line
  • Name your rc file something useful, like .screenrc. You'll need to remember it in a moment

Almost done! One more file. We're going to create the script that launches screen and either connects to a disconnected instance of what we create above, or creates a new one if it doesn't exist.

Start your editor and create viewlogs. It's going to look like this: (you can download viewlogs below)

SCREENSESS=$(screen -list | grep "solar" | grep "(Detached)" | head -n 1)
if [ -n "$SCREENSESS" ]; then
        screen -R solar
        screen -c solarwinds.screenrc -R solar

  • You'll first note that I named my screen session solar, for SolarWinds. It's used in three places, grep and two lines for screen. I probably should have used a variable for it, but I didn't. You're welcome to change it to something more fitting to your MARE, just make sure you change all three locations
  • SCREENSESS contains the output of a single line of grep searching for a specifically named, disconnected screen session
    • You'll note that this only searches for disconnected screen sessions. That is intentional. You can have more than one person logging in and using this script and it will not steal an active session. However, if anyone disconnects and leaves a session running the script will attempt to reuse it instead of creating a new one
  • If SCREENSESS is not empty, we reconnect to the session
  • Otherwise we create a new session, using the .screenrc file created above (you'll want to change the name here to match above) and ensure that it gets named properly so we can find it later if this script runs again

The final required step is to make viewlogs executable:

  • chmod +x viewlogs

How to use it:

You have two choices:

  1. You can log in to your shell with a terminal (SSH, Telnet) and run ./viewlogs
  2. If you're using SSH and PuTTY, you can configure PuTTY to run /bin/bash ~/viewlogs on connect (if you run a command on connect, there is no interpreter such as bash, unless you run it yourself)
    • In the session configuration, on the Session -> Connection > SSH screen, set Remote command to /bin/bash ~/viewlogs
    • In the session configuration, on the Session -> Terminal screen, check Implicit CR in every LF
    • I suggest saving this to a profile so you can simply double click on it from the profiles list in the future (or if you're feeling adventurous, look up how to create a desktop/taskbar shortcut that launches that profile)

Here's what it ends up looking like:

  • Screenshot of PuTTY connected to session running viewlogs / screen for log files:

As you can see, across the bottom are the names of the various log files. These are the numbered screens you can switch to with the Function keys we bound earlier. I have ESC bound to screen 0, as there is no F0 key. F1-F12 are bound to screen 1 - screen 12, even though we currently only have four screens going. The reason _log_main is black, with an @ next to the screen number, is because it has unread activity that occurred in the background. screen 3, cmdhist is outlined in red brackets because it is the current screen. The computer name and the date are in the corner at the bottom. If you have a larger window than the one in my screen shot, the date will also expand to include the time of the remote computer. If you want to disconnect and leave screen and all of the telnet sessions running in the background, simply CTRL+a, CTRL+d, and PuTTY will close, leaving everything running and waiting for you to connect again. As stated earlier, viewlogs will attempt to reconnect to one of the disconnected screens that it created, before it will attempt to create a new one. So don't worry about ending up with a hundred disconnected screens. You can always CTRL+a, CTRL+c to create a new screen with BASH running and run screen -list (yes, one hyphen not two) to see what sessions are running. typing exit at the shell prompt will close the shell if you don't want it cluttering up the tab bar. screen is quite powerful, this is just the tip of the iceberg. If you want to do more crazy stuff with it do some googling. You can do split windows and all manner of craziness.

And that's it. That is how I've customized my TinyMARE installs. I've got a couple, one in production (SolarWinds) and I've always got at least one test MARE running on my Raspberry Pi where I can perform experiments or attempt to reproduce bugs. Gandalf likes having a nice clean test world where it's easy to reproduce a bug when you submit one to him smile

-- SluggyQBFreak - 21 Feb 2017
Topic attachments
I Attachment Action Size Date Who Comment
bootmareEXT bootmare manage 691 bytes 21 Feb 2017 - 23:03 UnknownUser TinyMARE launcher script - Symlink compatible. Makes use of wd (Watchdog) as well as tcpserver to monitor log files
solarwinds.screenrcscreenrc solarwinds.screenrc manage 705 bytes 21 Feb 2017 - 23:53 UnknownUser screenrc file to launch log file telnet sessions
ucspi-tcp-0.88-errno.h.tgztgz ucspi-tcp-0.88-errno.h.tgz manage 59 K 21 Feb 2017 - 23:15 UnknownUser ucspi-tcp v0.88 with errno.h #includes to solve compiler errors
viewlogsEXT viewlogs manage 181 bytes 21 Feb 2017 - 23:54 UnknownUser viewlogs script to launch new or reconnect to existing screen session for telnet logs
viewlogs.pngpng viewlogs.png manage 62 K 22 Feb 2017 - 00:07 UnknownUser Screenshot of PuTTY connected to session running viewlogs / screen for log files wd.c manage 3 K 21 Feb 2017 - 23:02 UnknownUser TinyMARE Watchdog SOURCE - modified by QBFreak to remove hardcoded path to netmare
Topic revision: r2 - 22 Feb 2017, SluggyQBFreak
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding WikiMARE? Send feedback