Developing LinuxGSM

This page has been designed to help you learn how LinuxGSM code works.
As a user, it will allow you for a better understanding of how LinuxGSM works. As a developer, it will help you with adding new servers, fixing bugs and adding new features.


The LinuxGSM executable ./gameserver is the main entry point for users, their main interactions will be with this script. However, from a development perspective, this is only the gateway as it simply does initial the bootstrap and points to the commands and modules that are stored elsewhere. LinuxGSM is made up of many smaller (mainly bash) scripts (modules) that interact with each other to complete a set of tasks. A command will complete its set of tasks using the LinuxGSM modules.

Main Executable

The main executable file or is what the user interacts with to run commands.
linuxgsm.shis designed to be used for the installation of a specific game server. You can run ./ install to get a menu of the available servers or ./ gameserver to install the specific game server.
To install a specific server first downloads a complete list of all available servers from serverlist.csv. This file contains variables required to identify the server; ${gamename}, ${shortname} and ${servername}. When installing a game server copies itself using the${servername} variable as the script name and inserting the other variables into the copied file. The added variables allow LinuxGSM to know which server the user selected.
A user can also run the install again if they want multiple [[instances]] of the same server. This will give an output of gameserver-2,gameserver-3 etc as the file name.

Server Specific Information
Here are the things you need to look after when deploying a new server:
  • ## SteamCMD Login section needs to be present only if the game server requires a steam connection.
  • Paths variables, especially config paths
  • appid="" (steamcmd games only)
  • servicename="" (must be unique)
  • gamename="" (must be unique)
  • engine=""
  • githubuser/repo/branch="" (if you dev on your own github or a branch can help a lot)
Server Settings and start command
This part contains any setting that can be set as a start command for the given server. You will then use fn_parms and its parms="" variable to call those start parameters.

Functions, commands and script files

Script files are located in ${functionsdir}, which is ${rootdir}/lgsm/functions
  • Every single script file must be declared in
  • Commands are declared in, depending on the game or engine
Note: You need to update those files with update-functions command after adding a new one.


Here are the command functions you might need to alter when adding a new server:
  • - Server installation must work properly
  • - if the given game supports updates (might required to add a file for that matter, for now, we use to add a single file for install and update, like for TeamSpeak 3).
  • - Server details need to be displayed properly
  • &, & - You'll need to read carefully and understand this code before altering it.
  • - You will define available commands in this one, displayed when the user runs ./gameserver without an argument. Either use an existing opt or make a new one if needed.
  • & - Of course, your server needs to be able to start and stop properly.
  • & - Those commands usually work out of the box, but might require some more work. If not using tmux, then console should be disabled for this server in
  • - You might need to read variables out of configuration files such as Rcon information in the case of Squad.

Fixes runs at the end of server installation. If the given server requires a fix, then add and run it from

Core functions
This is the first script to be run when gameserveris executed. This script allows for fetching LinuxGSM core files, but also for downloading big files within kind of an API.
This is the second script to be run when gameserveris executed. This script declares all functions and fetches them when they are required.
This is the third and last script to be run when gameserveris executed. This script allows for setting and printing available commands to the user.
This script allows for easy message output and logging. More details about it in the next part.

Messages & Logs

LGSM has a message/logging framework to avoid painful syntax into scripts.
Framework syntax is: fn_print_whatever "This is your message" If you want to replace the line afterwards, then reuse fn_print_whatever. If you want a new output on a new line, then use fn_print_whatever_nl. "nl" stands for "new line".
On-Screen - Automated functions
  • [ .... ] | fn_print_dots | fn_print_dots_nl
  • [ OK ] | fn_print_ok | fn_print_ok_nl
  • [ FAIL ] | fn_print_fail | fn_print_fail_nl
  • [ ERROR ] | fn_print_error | fn_print_error_nl
  • [ WARN ] | fn_print_warn | fn_print_warn_nl
  • [ INFO ] | fn_print_info | fn_print_info_nl
On-Screen - Interactive messages
  • Print $gamename $commandaction and jump some lines | fn_print_header (used at the beginning of a command)
  • Complete! |fn_print_complete | fn_print_complete_nl
  • Failure! | fn_print_failure | fn_print_failure_nl
  • Error! | fn_print_error2 | fn_print_error2_nl
  • Warning! | fn_print_warning | fn_print_warning_nl
  • Information! | fn_print_information | fn_print_information_nl
On-Screen End of Line
  • OK| fn_print_ok_eol | fn_print_ok_eol_nl
  • FAIL | fn_print_fail_eol | fn_print_fail_eol_nl
  • WARN | fn_print_warn_eol | fn_print_warn_eol_nl
  • FAIL | fn_print_info_eol | fn_print_info_eol_nl
  • QUERYING | fn_print_querying_eol | fn_print_querying_eol_nl
  • CHECKING | fn_print_checking_eol | fn_print_checking_eol_nl
  • CANCELED | fn_print_canceled_eol | fn_print_canceled_eol_nl
  • REMOVED | fn_print_removed_eol | fn_print_removed_eol_nl
  • UPDATE | fn_print_update_eol | fn_print_update_eol_nl
Syntax: fn_script_log "Message goes here." Output: ## Feb 28 14:56:58 ut99-server: Monitor: Message goes here.
  • Simple action log | fn_script_log
  • PASS (a successful test) | fn_script_log_pass
  • FATAL (an error has interrupted LGSM) | fn_script_log_fatal
  • ERROR | fn_script_log_error
  • WARN | fn_script_log_warn
  • INFO | fn_script_log_info


Any script file must run at some point. Within, you will then choose what tests to run for a given function. The syntax of is a bit counter-intuitive: local allowed_commands_array=( ) is the variable where you will enter the functions into which you need to run the following check.
There are several checks available:
  • checks for a missing config file or a wrong parameter.
  • checks for missing dependencies and contains requirements
  • checks if the server has the correct Glibc version or a fix available.
  • automatically identifies the server interface IP.
  • checks if log files exist.
  • checks ownership & permissions of scripts, files and directories
  • checks if the user tried to run the script as root
  • checks the process status of the server. Either online or offline
  • checks if SteamCMD is installed correctly
  • checks if systemdir is accessible
  • checks RAM requirements (maybe more into the future)
  • checks and prevents server start from tmux or screen
This script allows for the use of exit codes which will print different outputs to LinuxGSM logs. Running defaults exitcode variable to 0 which stands for a proper exit
  • Normal exit: exitcode=0
  • FATAL exitcode=1
  • ERROR: exitcode=2
  • WARN: exitcode=3

Server installation

Installing a new server is mainly done through two scripts:
Sometimes, another script is required, such as for TeamSpeak 3:


At the moment, only the main "gameserver" script has a version number. The syntax is pretty easy, it's all incremental, based on the date: version="YYMMDD"

Testing and debugging your code

Working from your own GitHub branch

You will usually be developing onto your own repo. Using your own repo instead of the original one is quite easy.
  1. 1.
    Display your main "gameserver" file on GitHub, and select "Raw".
  2. 2.
    Make a test user, login to it
  3. 3.
    wget your Raw link and chmod +x the script.
  4. 4.
    Edit your "gameserver" file by changing GitHub information to your username and repo and branch.
    ## Github Branch Select
    # Allows for the use of different function files
    # from a different repo and/or branch.
Now, any command you run will get your own GitHub files, and after any change you make on your repo, ./gameserver uf will grab new files. If you make a change and that ./gameserver uf don't get them, it means you were too quick, and that your curl still has old files in cache; in this case, you'll need to wait a few minutes to get your modifications.

How to test

You need to make sure that all needed commands displayed in opt work properly. So just run ./gameserver to show available commands, then try commands one by one. A common procedure is to first work on command_install, then start, then stop, then debug, then details, then monitor.

Oops, I found a bug!

If you found a bug, either you'll instantly know how to fix it, or you won't. And either it will be a bug caused by your own code or a bug into LinuxGSM itself. So let's address those cases.
  1. 1.
    It's caused by your own code parts and you know how to fix it: Just go on and fix it.
  2. 2.
    It's caused by your own code parts but you got no idea why: Use ./gameserver dev-debug that will add a very detailed log into your rootdir that might help you figure this out. To disable the dev-debug mode, just re-run the command. If you still can't find why it's not working, come get help on Discord's #gsm-development channel or Github issue that might have been created for this issue.
  3. 3.
    You found a bug into LinuxGSM itself. First, you need to be sure that it's really a bug that affects every game, by testing with another game onto the original repo, otherwise, if it only affects your game, you will usually just need to add a clever conditional check to fix the issue.