Simutrans (a transport sim game similar to Transport Tycoon etc.) recently gained support for online multiplayer games. This is based around a persistent-world client/server model (e.g. the server runs the game 24/7 and clients can connect to play for a while, with their transport companies continuing to exist when they quit).
I have set up a number of public game servers to allow people to play the game online and through doing so learnt quite a bit about the process of setting up and maintaining not just Simutrans but Unix server processes in general. I hope that this guide helps those that might follow me.
Simutrans can be compiled using GCC 3 or 4 (or other means, not covered in this guide). For the server version it’s highly recommended to use the posix backend which completely disables the graphics engine, reducing the amount of processing that needs to be done by the server.
Currently there aren’t binaries compiled for the posix backend by default so generally you need to compile it yourself on the server it is going to be run on. This is fairly easy to do. I am going to assume for the purposes of this guide that you’re running Debian Linux, though it should be much the same for any Unix platform.
1. Check out the correct version of the Simutrans source code. You’ll need Subversion installed to do this. E.g. to check out version 110.0 (the first stable version with network support:
svn co --username anon -r 4303 svn://tron.homeunix.org/simutrans/trunk
When prompted for a password just hit enter (blank password).
2. Once Subversion finishes working copy the file config.template to config.default:
cp config.template config.default
Then use your favorite text editor to edit the new file. Uncomment the lines:
BACKEND = posix
COLOUR_DEPTH = 0
OSTYPE = linux
DEBUG = 3
OPTIMISE = 1
WITH_REVISION = 1
These should be the only non-commented lines in your default.config.
3. Save the file and then run these commands. You’ll need GCC installed as well as any other packages your OS requires to be able to compile C and C++ code.
When this completes, run:
This will strip symbols from the binary and reduce its size dramatically.
4. You’re done, the binary “sim” will be used together with a set of game files to set up your server. You can use the same source tree to compile newer versions of the game later. To do this you’ll need to issue an svn update command with the revision of the version you wish to update to, e.g.:
svn up -r 4304
Again to rebuild the newer version.
To avoid running the Simutrans server processes as root (poor security) and to avoid running them as a real system user (also poor security) I set up a new user account called “simutrans”. This account doesn’t have a home directory or login shell since it is only going to be used to run the server. I would recommend (and will write here in this guide) that you use the username “simd” instead since “simutrans” is more than 8 characters so the name won’t appear in the output of the ps command.
The exact way you create a user is likely to be very OS specific so I will leave it to you.
Simutrans can run in one of two modes, “single user” and “multi-user”. This has no effect on network multiplayer and refers only to the scheme used to store the game’s configuration files. In multi-user mode the game will store its config per-user under your home directory. In single-user mode it’ll store everything under the installation’s config directory. I recommend using single-user mode for simplicity.
This setting is specified in the “/config/simuconf.tab” file under the simutrans directory for the revision you’re running, e.g.:
The setting in question is:
singleuser_install = 1
See the Configuration File section for more details.
I created the following file structure for my server:
/var/simutrans/bin (For control scripts, see below)
/var/simutrans/etc/ (For server instance configuration files)
/var/simutrans// (For simutrans game files)
Additionally I create a folder under /var/log:
Which is where we’ll redirect the individual servers’ log output to using syslog.
“/var/simutrans” should be owned by root, group simd.
“/var/simutrans/bin” and “/var/simutrans/etc” should be owned by root, group root
“/var/simutrans//” and everything below it should be owned by simd, group simd
“/var/log/simutrans” should be owned by simd, group root (or adm on Debian)
By default Simutrans logs to a file in the directory where the executable is located. The logging level is determined by the “-debug” command line switch. A value of 2 is reasonable, 3 will provide a lot more information. Unfortunately it isn’t possible to tell Simutrans where to log. It is also not possible to send it a signal to make it re-open its log file (so log rotation isn’t easily possible).
The solution to this is to use syslog. On Debian (and likely other platforms) there is a utility called logger which allows you to redirect the stdout/stderr of a process to syslog (and from there to log files). This is the best way to handle logging on Unix systems as it takes care of log rotation etc. for you.
Using logger is simply, you just pipe the output of your Simutrans instance to it. This will be covered in more detail later when I explain the use of the simctrl script but roughly you would execute a command like:
sim -server 13353 -server_id 123456789 -server_name testserver -debug 2 -lang en -objects pak/ 2>&1 | logger -i -t testtag &
This runs “sim” (the binary we compiled earlier) with various options. The “2>&1” tells the shell to redirect standard error to standard output (e.g. all messages go to the same place). Finally we pipe this output (the | is a pipe character) to the logger utility which we tell to tag each line with an arbitrary tag (in this case “testtag”) and the process id. The tag can be used later to filter the syslog messages into a distinct log file.
You will need to modify your syslog configuration. On Debian this is found at:
Under the RULES section and before any other rules add the following:
# Simutrans log files
:syslogtag, contains, "simserver1" /var/log/simutrans/simserver1.log
:syslogtag, contains, "simserver2" /var/log/simutrans/simserver2.log
This assumes we have two instances of Simutrans set up, one known as “simserver1” and the other as “simserver2”. Any messages which syslog sees which are tagged with this string will go into the log file specified. The line with “& ~” just tells syslog that we can discard these messages at this point since we only want them to be logged to this place. If you don’t do this then the messages can end up in other log files as well.
The “tag” is a concept used extensively with the simctrl script and acts as an identity for the server instance in question. More on this later.
Save games + restarting server
Simutrans loads savegames from the “simutrans/save/” folder (when in single-user mode). You can place new games here and then load them on the command line. If you don’t specify the “-load xxxx.sve” command line switch then the game will automatically search for a file called “serverXXXXX-network.sve” (where XXXXX is the port number of the server instance, e.g. “server13353-network.sve”). If it finds this file it will load the game automatically. In most cases the last time this will have been saved is when a client enters the game, or if autosave is turned on. I believe the game also saves if the server is shut down cleanly.
To run a new game then specify “-load mygame.sve” on the command line. To resume a game after the server has been shut down or crashes you don’t need to specify this flag at all. IMPORTANT: The automatic savegame will be overwritten if you start another server instance on the same port using the “-load xxxx.sve” option. Remember that the savegame specified with the “-load” flag is found relative to the game’s savegame directory. In a single-user installation this will be “/save/”, e.g. if your binary is located here:
Then it will look for savegames here:
Simutrans Configuration File
Simutrans stores its configuration in many places. In single-user mode (I recommend using this!) the main locations are “/config/simuconf.tab” and the simuconf.tab files located under individual pakset folders. The only place you should need to make changes are the main simuconf.tab.
Settings important for network servers:
Set this to 1.
If you wish you can enable this, though for an active server it shouldn’t be needed as people will join/leave so often.
This setting determines the number of frames the server runs ahead of the client. Setting this to a higher value increases stability but also increases latency (e.g. takes longer to build things but less likely to get desyncs).
This isn’t a server setting and is set per-client, but I will mention it here as it can help people who have laggy connections to stay connected to your server. It does roughly the same thing as server_frames_ahead but on a per-client basis.
This setting determines the number of frames between manually syncing clients (if nothing else requiring a sync has happened in the intervening period). Again, lower values increase stability but also increase bandwidth usage slightly.
The “server_announce”, “server_announce_interval”, “server_name” and “sever_comment” fields can all be set on the command line and for multiple servers running from the same source files this is a necessity so I will cover them in the simctrl config section.
Simctrl Utility Script
I created a shell script to automate the process of starting and stopping the Simutrans instances I have running on my server. This script relies on the concept of each instance having a “tag”, e.g. sim64 or sim128 which is unique to that instance. This tag is used to idenfity which instance we wish to control and to look up configuration parameters.
The script expects your Simutrans instances to be located at:
You can change this by modifying the script if you need to. I recommend the directory structure explained earlier however as it seems fairly sensible (and lends itself to the possibility of using chroot).
The script must be run as root and it uses su to run the server as the user simd. The format of the command is:
Replacing with the tag name of your simutrans instance and selecting one of the 4 following commands.
status – Basically runs “ps uww” filtered by the pid recorded in the pidfile created when simctrl is used to start a simutrans instance
start – Starts the specified simutrans instance. Configuration is read from the .config file located in the etc/ folder relative to the simutrans location defined in simctrl (by default /var/simutrans/etc/). See below for the config file format. The start command will load the savegame file defined in the configuration.
restart – Performs a stop followed by a start. The restart command does not specify a savegame path so use this for restarting the server if it has crashed as it will then pick up the last running game from the automatically saved file.
stop – Stops the specified simutrans instance.
The configuration file format is:
Hopefully this is fairly self-explanatory. Simctrl will complain if any of the fields are missing. This should be saved as .config in the /var/simutrans/etc/ directory. The tag should be a short string that uniquely identifies an instance of the game.
Note: The port number must be unique for each instance. You can obtain a server_id from the Server List website (see here: http://simutrans-germany.com/serverlist/). Use the “Add a new simutrans server” link and then fill out the details. This unique ID allows the game to automatically update its status for clients. Your server won’t show up in the client’s game listing until you do this.
The other fields:
revision – This should match whatever the subfolder under /var/simutrans/ is which contains your game, e.g. “r4303” would indicate: /var/simutrans/r4303
objects – The pakset to load, this is relative to the location simutrans is starting up from. E.g. “pak/” for pak64, “pak128.Britain.r376/” for pakBritain etc.
save – The savegame file to load when using the Start command, this is relative to the game’s save directory
debug – Debug level for logging, 2 is fairly useful, 3 is pretty verbose
server_name – IP address or DNS name, this is how clients know where to find your server to connect to you
server_comment – Currently doesn’t do much (this should update the comment field on the Server List website but this doesn’t seem to work)
You can download the simctrl script from here:
This guide presents the basics for setting up a Simutrans server so I hope it proves a good starting point. There are some other concepts to cover (most important of these being monitoring since Simutrans can occasionally crash) but I will look at these in a future post. There is also a complementary utility to simctrl (known as simquery) which lets you talk to a running server and ask it questions. This script isn’t quite ready for release yet though.
I hope you found this guide useful. If you have any questions please ask!