# Home

<figure><img src="/files/IUU7epE9IKfKGBjHFVoa" alt=""><figcaption></figcaption></figure>

The command-line tool for quick, simple deployment and management of Linux dedicated game servers.

* User docs: [docs.linuxgsm.com](https://docs.linuxgsm.com)
* Dev Docs: [dev-docs.linuxgsm.com](https://dev-docs.linuxgsm.com)

## Introduction

Welcome to the LinuxGSM developer documentation that covers how to get started, tooling, workflow, best practices, and code standards.

If you want to contribute to LinuxGSM and need assistance feel free to pop on the LinuxGSM [Discord ](https://linuxgsm.com/discord)and have a chat with some of the contributors.

## Work in Progress

This documentation is a work in progress. If you have suggestions for topics or improvements you want to make. Please contribute to the [dev-docs github](https://github.com/GameServerManagers/LinuxGSM-Dev-Docs) page.

## Scope

The scope of this document is to provide developers with a starting point and reference to allow devs to contribute to the LinuxGSM project. This will include getting started, tooling, workflow, best practices, and code standards.


# Getting Started

<figure><img src="/files/IUU7epE9IKfKGBjHFVoa" alt=""><figcaption></figcaption></figure>

## Intro

This guide will give a brief overview of how to get started developing LinuxGSM by running through some of the basics of using GitHub and the tools you need. This is not a comprehensive guide to GitHub but should help with getting started. There are plenty of resources available online such as the [GitHub help documentation](https://help.github.com/en/github) and [guides](https://guides.github.com/) that will help you learn more.

## Choosing an Issue to Develop

Whenever someone raises a new feature request or bug is done on the [GitHub Issues](https://github.com/GameServerManagers/LinuxGSM/issues) page. There is a raft of issues with different levels of complexity. Choosing an issue to work on is down to you as an individual, however, it is important you enjoy working on it.&#x20;

When reviewing an issue it is a good idea to look at factors such as complexity, scope, and time to develop.&#x20;

It is recommended that a simple issue is picked first as they are more likley to be merged quickly.

Popular issues to attempt are [type:Server Requests](https://github.com/GameServerManagers/LinuxGSM/issues?q=is%3Aissue+is%3Aopen+label%3A%22type%3A+server+request%22) as often developers want to have a game server added to the project. Be warned however some game servers can be more difficult than others to develop.

To help filter issues GitHub uses [labels](https://help.github.com/en/github/managing-your-work-on-github/about-labels) to help identify the types of issues. Common labels include `type:bug`, `type:feature`, `command:monitor`, `game: 7 Days to Die`. Labels are split into label types such as type, command, game, and info to aid in prioritising and managing them.

## Starting Development

To begin working on LinuxGSM you need to [fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) the LinuxGSM repository once forked you will need to [clone](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository-from-github) your new repository to your local machine using your chosen git client. Once cloned it is possible to edit the code on your local machine using your text editor of choice.

It is recommended you create a [branch](https://github.com/GameServerManagers/LinuxGSM-Dev-Docs/blob/master/@linuxgsm/s/linuxgsm-dev/branching/README.md) to develop your code. The branch should use the Gitflow methodology and should be named `feature/[featurename]`.

Once a change has been made and saved the change will need to be committed to your local repo. When using commit it is important to leave a useful message to describe the change, this is covered in [Conventional Commits](https://github.com/GameServerManagers/LinuxGSM-Dev-Docs/blob/master/@linuxgsm/s/linuxgsm-dev/conventional-commits/README.md). When you are ready to send your commits to your remote fork you will need to [push ](https://help.github.com/en/github/using-git/pushing-commits-to-a-remote-repository)the updates.

##

##


# Programming Language

![](/files/-Lu30cfv1TvSQKa_KTId)

LinuxGSM is written in [Bourne-Again Shell](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) (BASH) Script sometimes just known as Shell Script.

## What is BASH?

*BASH* is a "Unix shell": a command-line interface for interacting with the operating system. It is widely available, being the default shell on many GNU/Linux distributions and Mac OSX, with ports existing for many other systems.

{% embed url="<https://www.youtube.com/watch?v=I4EWvMFj37g>" %}

## What is BASH Script?

"In addition to the interactive mode, where the user types one command at a time, with immediate execution and feedback, Bash (like many other shells) also has the ability to run an entire script of commands, known as a "Bash shell script" (or "Bash script" or "shell script" or just "script"). A script might contain just a very simple list of commands — or even just a single command — or it might contain functions, loops, conditional constructs, and all the other hallmarks of imperative programming. In effect, a Bash shell script is a computer program written in the Bash programming language." -[ Bash Shell Scripting](https://en.wikibooks.org/wiki/Bash_Shell_Scripting#What_is_Bash?)

## Why Does LinuxGSM use BASH?

BASH script is often used by Linux System Administrators to automate repetitive tasks on Linux servers and is often used in the same way Windows Admins use [BATCH](https://en.wikipedia.org/wiki/Batch_file) Script or [Powershell](https://learn.microsoft.com/en-us/powershell/scripting/overview?view=powershell-7.3) on Windows. BASH is available on all Linux systems, it is very stable and reliable and most people who interact with Linux will have had some exposure to it.

LinuxGSM started as a simple BASH script to easily control and manage a game server (Killing Floor). As Daniel Gibbs (lead developer) was a Linux Systems Administrator at the time and other examples of managing game servers often used BASH it simply made sense to use it.

LinuxGSM has evolved and grown drastically over time to add more commands and features from the early days, however, it essentially still does the same thing just on a larger scale. BASH is a relatively simple language to use and learn, does not require compiling, and can be written in any basic text editor.

## BASH Resources

There are loads of resources to help you learn BASH and below are a few. If you get stuck it is already recommended that you Google as there is probably a [Stackoverflow](https://stackoverflow.com/) question raised.

{% embed url="<https://www.shellscript.sh/>" %}

{% embed url="<https://linuxconfig.org/bash-scripting-tutorial-for-beginners>" %}

{% embed url="<https://www.tldp.org/guides.html>" %}

{% embed url="<https://en.wikibooks.org/wiki/Bash:Shell:Scripting#Introduction>" %}


# Development Software

Before you get started a few tools are required for developing LinuxGSM. The tools used are down to the developer's preferences. However, there are some recommendations if you are new.

## GitHub Account

LinuxGSM uses [GitHub](https://github.com) to host the code, manage issues, and run CI/CD tools. Because of this a GitHub account is required.

{% embed url="<https://github.com>" %}

{% embed url="<https://www.youtube.com/watch?v=pBy1zgt0XPc>" %}

## Text editor

LinuxGSM is written in BASH and can be developed simply by using a text editor. The recommended text editor is [VSCode](https://code.visualstudio.com/) as it is free and integrates with GitHub and WSL. However, if you are more comfortable with another editor that is fine. For specific requirements for text editors see [Text Editor Settings](https:///@linuxgsm/s/linuxgsm-dev/text-editor-settings).

* [VSCode](https://code.visualstudio.com/) (recommended)
* [Sublime Text](https://www.sublimetext.com/)
* [Notepad++](https://notepad-plus-plus.org/)
* [Neovim](https://neovim.io/)

{% embed url="<https://www.youtube.com/watch?v=KMxo3T_MTvY>" %}

## Git

The LinuxGSM project uses Git as version control software. It is important you have a basic understanding of Git, however, don't be worried if you don't understand it all.

{% embed url="<https://www.youtube.com/watch?v=hwP7WQkmECE>" %}

To work on the project, edit code, and create branches a Git client is required. GitKracken as it is feature-rich and easy to understand the branch relationships. GitHub Desktop is a great client for beginners as well as VSCode's built-in Git Client.

* [GitKracken](https://www.gitkraken.com/)
* [VSCode](https://code.visualstudio.com/docs/sourcecontrol/overview)
* [Github Desktop](https://desktop.github.com/)
* [Git](https://git-scm.com/downloads)

## SSH Client

To connect to Linux servers an SSH client is needed. There are various clients available to choose from. For Windows, MobaXterm is a great option for the classic PuTTY. For Linux and Mac Remmina works well for saving SSH sessions.

* [Termius](https://termius.com/) (Cross-platform)
* [MobaXterm](https://mobaxterm.mobatek.net/) (Windows)
* [Putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) (Windows)
* [Remmina](https://remmina.org/) (Linux & Mac)

## Discord

The LinuxGSM project uses [Discord](https://discordapp.com) as the main method of communication.

## SteamDB

[SteamDB](https://steamdb.info/) is a great resource for finding data related to Steam. This can be used to look up appid's for game servers as well as checking if a game server supports Linux. For example, The Rust dedicated server is found here <https://steamdb.info/app/258550/info/>

##


# Test Environment

LinuxGSM is designed to run on Linux, and therefore, a Linux test environment is essential for testing game servers and code changes. Whether you're already using a Linux desktop or primarily work on Windows, there are multiple ways to create a suitable Linux test environment. Additionally, if you are using Windows, you can leverage Windows Subsystem for Linux (WSL) to streamline your development process.

## Distro

LinuxGSM is primarily developed on Debian-based distros but is also tested to work on RedHat-based distros. Keep in mind that different distributions and versions may have varying versions of BASH and other dependencies. Ensure that your chosen distribution is still officially supported by the vendor and that it's compatible with the game server you intend to work with.

## Selecting a Test Environment

### **Using a Linux Desktop**

If you're already using a Linux desktop, you can run LinuxGSM directly on your desktop environment. This approach simplifies the setup process since LinuxGSM is natively compatible with Linux distributions.

### **Windows with WSL**

For developers using Windows, Windows Subsystem for Linux (WSL) provides an efficient way to create a Linux test environment without dual-booting or using virtual machines. You can install a Linux distribution of your choice via WSL and then proceed to set up LinuxGSM within that distribution.

### Virtual Machine

Creating a virtual machine on your desktop or laptop is a versatile way to create a development environment. You can use tools like VirtualBox to download an Ubuntu Server ISO and quickly set up a test environment. Note that for testing internet functionality, you may need to configure port forwarding on your home router.

* [Virtual Box](https://www.virtualbox.org/)
* [VMware Player](https://www.vmware.com/uk/products/workstation-player.html)
* [ESXI Server](https://www.vmware.com/uk/products/esxi-and-esx.html)
* [Xen](https://xenproject.org/)
* [Proxmox](https://www.proxmox.com/)

### Internet Server

Renting a virtual private server (VPS) or dedicated server can be an excellent choice for testing LinuxGSM in an online environment, which closely resembles how it's commonly used. Several providers offer cost-effective server options, making it accessible for testing purposes.

Notable providers include:

* [Linode](https://linode.com/)
* [Digital Ocean](https://www.digitalocean.com/)
* [OVHCloud](https://ovhcloud.com)
* [Oneprovider](https://oneprovider.com/)
* [Kimsufi](https://www.kimsufi.com/)

## **Testing Your Code**

At some point, you will need to test the code you have worked on. This can be done by downloading LinuxGSM and updating the repo and branch details to match your fork.

#### Setup Testing Environment

Login to your development environment and begin installing LinuxGSM.

1. Create a user and log in.

```
adduser linuxgsm
```

```
passwd linuxgsm
```

```
su - linuxgsm
```

> replace `[gameserver]` with the game server you are developing.

```bash
mkdir [gameserver] 
```

2. Download linuxgsm.sh.

```bash
wget -O linuxgsm.sh https://linuxgsm.sh && chmod +x linuxgsm.sh
```

3. Rename the GitHub username, repo and branch to match you one you are developing on.

```bash
## GitHub Branch Select
# Allows for the use of different function files
# from a different repo and/or branch.
githubuser="GameServerManagers"
githubrepo="LinuxGSM"
githubbranch="master"
```

4. Install the game server

```bash
./linuxgsm install
```

#### Updating the Test Environment

Every time you push to remote it is possible to pull the changes to the test environment. This is done by using the development command `clear-functions`.

To use clear-modules activate development mode.

```bash
./gameserver development
```

Run the command.

```bash
./gameserver clear-modules
```


# Developer Commands

LinuxGSM provides commands to help developers gather information about the game server they are developing.

| Command Name            | Command                       | Short              |
| ----------------------- | ----------------------------- | ------------------ |
| [Developer](#developer) | `./gameserver developer`      | `./gameserver dev` |
| Detect Details          | `./gameserver detect-details` | `./gameserver ddt` |
| Detect Dependencies     | `./gameserver detect-deps`    | `./gameserver dd`  |
| Detect Glibc            | `./gameserver detect-glibc`   | `./gameserver dg`  |
| Detect ldd              | `./gameserver detect-ldd`     | `./gameserver dl`  |
| Query Raw               | `./gameserver query-raw`      | `./gameserver qr`  |
| Clear Functions         | `./gameserver clear-modules`  | `./gameserver cm`  |

### Developer

The `developer` command enables development mode allowing access to all hidden developer commands.&#x20;

This command also enables dev debug that outputs everything LinuxGSM is doing to `dev-debug.log`when a command is run.

```bash
./gameserver developer
./gameserver dev
```

### Detect Details

Detects variables that are set up to be displayed in details.

```
./gameserver detect-details
./gameserver ddt
```

### Detect Dependencies

Detects dependencies the server requires by checking the contents of `serverfiles`. The output suggests the install command required.

```bash
./gameserver detect-deps
./gameserver dd
```

### Detect Glibc

Automatically detects which version of GLIBC a game server requires

```bash
./gameserver detect-glibc
./gameserver dg
```

### Detect ldd

Automatically detects required dependencies using the ldd command.

```bash
./gameserver detect-ldd
./gameserver dl
```

### Query Raw

Queries the game server using,`gamedig` , `query_gsquery.py`, `tcp` and `udp`, giving a raw output. This can diagnose if the game server query is working and configured correctly.

```bash
./gameserver query-raw
./gameserver qr
```

### Clear Modules

Use this command when pushing commits to a specific branch. It deletes all functions from `lgsm/functions` and removes default LinxuGSM configs. Allowing a commit to be applied to the testing environment without `gameserver.sh` being overwritten and resetting the GitHub branch settings.

```bash
./gameserver clear-modules
./gameserver cm
```


# Adding a new Game Server

Adding a new game server is one of the most common things developers do. This guide will help you add a new game server to LinuxGSM.

{% hint style="info" %}
replace gameserver with the name of the new server e.g rustserver
{% endhint %}

### Create new \_default.cfg config file

Firstly create a new `_default.cfg` file in `lgsm/config-default/config-lgsm/gameserver` . An existing \_default.cfg file can be used as a template.

Update all the variables in the new `_default.cfg` file to fit the new server.

Some common variables that will need updating:

* Add `## SteamCMD Login` section only if required.
* `startparameters` are any parameters the executable requires to run the game server.
* `appid`  used to download a game server from Steam. Remove if not using steam.
* `steammaster` used if the game servers are listed on the Steam master servers.
* `stopmode` defines how a server can safely exit.
* `querymode` defines the type of query monitor that can be used to check the server is responding.
* console type highlights to users if the console outputs and is interactive.
* Game Server Details `gamename` , `engine`, `glibc`.
* Various directory and config variables.

## Add the new server to serverlist.csv

Add the new server details to `serverlist.csv` as well as add any dependency requirements to all the distro csv files found in `lgsm/data` directory.

## Add any fixes to a fix file

Some game servers require alterations before they can start common examples include:

* copying library files to serverfiles
* symlinking files
* creating directories
* adding a directory to `LD_LIBRARY_PATH`

If this is required a fix module will need to be created.

1. Create a new module called `fix_[shortname].sh` (use an existing example as guidance)
2. Add the required fixes to the module
3. Add the module to `fix.sh`
4. Add the fix to `core_modules.sh` list

## Server Querying

Game servers can often be queried to check the server is running and return useful info. LinuxGSM uses gsquery.py to complete simple pings and [gamedig](https://github.com/gamedig/node-gamedig) to get detailed info returned in json format.&#x20;

Most game servers use the valve protocol for allowing queries, however, others are available. Look for any developer documentation to try and find out if querying is supported.&#x20;

Use the `query-raw` command to assist in testing the querying of the new game server.&#x20;

## Stop Mode

Game servers will be able to gracefully exit using various methods. Figure out the method the new game server uses. See [stop mode](https://docs.linuxgsm.com/features/stop-mode).

## Glibc Version

Most game servers require a minimum glibc version. Use the `detect-glibc` command to find out the minimum glibc version required.

## Details

Various game server info will need to be parsed from game server configs or variables. Use the info\_\*.sh modules to add this info.&#x20;

## Custom Updater

Not all game servers use SteamCMD. If this is the case a custom update module will need to be created. There are a number of examples in the code that can be used as a baseline.

## Custom Commands

Some game servers may require bespoke commands to complete tasks. Examples of this include Teamspeak 3 and Unreal Tournament 2004. Take a look at the `core_getopts.sh` module for examples of how to add commands.


# Semantic Versioning

LinuxGSM has now moved from a rolling release to [Semantic Versioning](https://semver.org/). This is due to the size of the project and the requirement to better manage features and bug fixes.


# Workflow

## LinuxGSM Feature Flowchart

The below flow chart highlights the basic method for getting a feature released.

![](/files/-Lh5bdwktO8RO3ghb-uT)


# Agile

\[WIP]


# Pull Requests

## Pull Requests

Once the code you have worked on is ready to be submitted to the LinuxGSM project a [pull request](/workflow/branching) will need to be raised. Pull requests have a list of things that need to be completed to get it merged into the project. Follow these steps as much as possible to ensure that your code can be merged quicker. When the pull request is raised various unit tests will be done on the code to ensure it follows the correct standards. When naming a pull request ensure that it is following [Conventional Commits](https://www.conventionalcommits.org/) standards; as this is what is used for generating the [changelog](https://github.com/GameServerManagers/LinuxGSM/releases) for the next release.

A best practice for writing a commit message is to say in your head the following, followed by the change you are making.

> If I commit this change it will.......*add slack support to alerts*

```bash
feat(alerts): add slack support to alerts
```

```bash
fix(csgoserver): remove SteamCMD auth requirement 32-bit workaround 
```

Once the Pull Request is created it is now time to wait.

The Pull Request will need to be reviewed by LinuxGSM developers who regularly work on the project. They will accept, reject or recommend changes to the Pull Request. This can take time or your pull request will be held until a time that is appropriate to merge into the project so please be patient. One of the developers may leave a review to make changes or make changes themselves to make the commit ready. Once this review process is completed congratulations your commit will be merged ready for the next release.

Once merged in to the develop branch where it will be tested with other new features and code. When the code is at a point to release it will be merged in to the master branch which will make it live.

Pull Requests (PR) let others review changes a developer has been making in a branch. Once a PR is opened, a branch can be reviewed with other developers giving feedback and also add follow-up commits (LinuxGSM core devs only) before changes are merged into the base branch.

LinuxGSM uses Pull Requests to allow developers to submit code that is ready or nearly ready to be merged into the `develop` branch. To make the process easier a checklist template has been created to guide the submission.

Various unit tests are carried out to check that the PR does not break LinuxGSM and follows standards. Feedback is given by the tests once they are completed.

If the PR is not quite ready for merge but is ready for review and feedback ensure the subject of the PR conains `[WIP]`(Work in Progress).


# Gitflow

## GitFlow

LinuxGSM uses the GitFlow method (mostly) for releases. Relying on `master`, `develop`, `feature` and `hotfix` branches.

![GitFlow branching model](/files/-Lh5LloHqmt3SxoQXbPM)

For further reading on the GitFlow model read the following article.

{% embed url="<http://nvie.com/posts/a-successful-git-branching-model/>" %}

{% embed url="<https://www.youtube.com/watch?v=hG_P6IRAjNQ>" %}

## Branches

The `master` branch will be the stable release branch. The `develop` branch is for developing stable code. All code is to be developed in a `feature` branch or `hotfix` for urgent fixes.

### Master

The `master` branch is where the stable, production release is kept. Only code that has gone via the `develop` can be merged here and goes through a release process. It is very important that the code there has been tested and is stable as it is used in production.

### Develop

The `develop` branch brings together all the `feature` branches ready to be tested to become the next stable release. Developers should use `develop` as the base when creating a branch.

### Feature

A feature branch is a development branch that is used while code is being actively worked on by developers. A feature branch should normally relate to an existing issue in GitHub. The feature branch should refer to the issue number and a word or two describing the issue, allowing other developers to know what issue branch is related to and helps with housekeeping.

```
feature\1234-glibc-migrate
```

Once a feature is ready to be merged into `develop` a pull request is to be raised to allow the feature to be reviewed.

{% hint style="info" %}
The branch naming convention is less of an issue for developers who have forked the project and submitted a pull request. However, it is recommended that the standard is used.
{% endhint %}

### Hotfix

The `hotfix` branch is identical to the `feature` branch but instead is used for urgent fixes that need to be applied to master.

```
hotfix\1234-glibc-migrate
```

### Release

When code from the `develop` branch is ready for release it is split off into a `release` branch.

The `release` branch will not have any more features added to it. It is then tested and any bugs fixed it will be released into `master` and tagged as a version number. The release will also be merged back into the `develop` branch.


# Conventional Commits


# Unit Tests


# Main Executable

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 the initial 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.

The main executable file `linuxgsm.sh` or `gameserver` is what the user interacts with to run commands.

`linuxgsm.sh` is designed to be used for the installation of a specific game server. You can run `./linuxgsm.sh install` to get a menu of the available servers or `./linuxgsm.sh gameserver` to install the specific game server.

To install a specific server `linuxgsm.sh` 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 `linuxgsm.sh` 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.


# Commands

## Commands

Within LinuxGSM there are many commands that a user will run to complete tasks such as start, stop, monitor, and details. Command scripts are stored will all other modules and are always named something like `command_install.sh`. See the [commands](broken://pages/DO59mPJammrHrXqDseLp) page for more info.

Within LinuxGSM there are many commands that a user will run to complete tasks such as start, stop, monitor, and details. Command scripts are stored with all other modules and are always named something like `command_install.sh`.

Some game servers may require bespoke commands to complete tasks. Examples of this include Teamspeak 3 and Unreal Tournament 2004. Take a look at the `core_getopts.sh` module for examples of how to add commands.


# Exit Codes

Below is a list of exit codes and explanations for each code. An exit code hightights the state of the code once it has completed its task. This is used to highlight if the proccess completed, failed or somwhere inbetween.

to see the exit code you can activate developer mode.

```
./gameserver developer
```

### Pass

* **Code:** 0
* **Description:** This code is returned when all is well.
* **On Screen Automated:** \[ OK ]
* **On Screen Interactive:** Complete!
* **Logfile:** PASS

### Fatal

* **Code:** 1
* **Description:** Fatal errors occur when LinuxGSM is prevented from completing its task. e.g it was unable to start a server.
* **On Screen Automated:** \[ FAIL ]
* **On Screen Interactive:** Failure!
* **Logfile:** FATAL

### Error

* **Code:** 2
* **Description:** An error occurs when LinuxGSM can complete its task however something went wrong. In many cases LinuxGSM will attempt to resolve errors itself.
* **On Screen Automated:** \[ ERROR ]
* **On Screen Interactive:** Error!
* **Logfile:** ERROR

### Warning

* **Code:** 3
* **Description:** Warnings happen when there is something mis-configured or not setup correctly. LinuxGSM may still work but not do as expected.
* **On Screen:** \[ WARN ]
* **On Screen Automated:** \[ WARN ]
* **On Screen Interactive:** Warning!
* **Logfile:** WARN

### Info

* **Code:** N/A
* **Description:** Useful information about what LinuxGSM is currently doing.
* **On Screen:**
* **On Screen Automated:** \[ INFO ]
* **On Screen Interactive:** Information!
* **Logfile:** INFO

### How to used exit codes in code

An exit code is generated when you specify a logfile message e.g \_\_`fn_script_log_fatal`. When you want the script to exit you must use `core_exit.sh` rather than just the exit command. `core_exit.sh` will then handle the exit and specify the last know exit code. So if the more recent command was `fn_script_log_fatal`then the exit code will be 1

#### Examples

```
fn_script_log_fatal "RCON password is not set"
core_exit.sh
```

This will exit with code 1

```
fn_script_log_error "RCON password is not set"
core_exit.sh
```

This will exit with code 2

```
fn_script_log_error "SteamCMD is missing"
LinuxGSM installs SteamCMD
fn_script_log_pass "SteamCMD has been installed"
core_exit.sh
```

This will exit with code 0


# Functions

Functions are groupings of code that complete a task (function). These functions can be called upon anywhere within the code. Creating a function prevents having to replicate the same code over and over.

## LinuxGSM Functions

All functions within LinuxGSM begin with the prefix `fn_` and should be descriptive of what the function is doing. Words are separated by an underscore `_`.

For LinuxGSM development, it is important that developers understand what a function does which is why all function names must describe the purpose of the function. A longer function name that describes the function is preferred over a short one that does not.

### Examples

```
fn_stop_graceful_cmd
```

```
fn_update_ts3_dl
```

### Syntax

All functions should be formatted with the following syntax.

```
fn_function_name(){
    code
}
```


# Modules

Modules are individual bash scripts containing code and functions that complete specific tasks.

> Modules may sometimes be referred to as function files or just functions are located in the functions directory and not be confused with bash functions. Modules have been named as such to avoid confusion.

A command will call upon modules to complete various command tasks. Modules are normally created if a task needs to be called upon by multiple commands, or as a logical way to split large commands and modules into smaller sub-modules.

Modules are located in the `modules` directory,

```
lgsm/modules
```

### Module Groups

Modules are split into logical groups depending on the type of task being carried out.

* alert – Sending alert notifications
* check – completes checks before a command runs.
* command – the command module that runs specific command tasks.
* core – core modules that are required to run LinuxGSM.
* fix – apply game server-specific fixes to allow the game server to run correctly.
* info – gathers info from sources such as the OS and game server.
* install - modules related to installation
* mods – handles game server mods
* query – game server query modules
* update – handles updating of game servers and LinuxGSM

### Module Pointer

Some modules such as `fix.sh` and `check.sh` are made up of smaller tasks that are split up into sub-modules. Because of this, these modules become pointers for their sub-modules that will upon the sub-modules as required.

An example of this is when check.sh will be called within command\_start.sh, it will automatically select which sub-module tasks are required and run them.

### Core Modules

Core modules handle vital are required by LinuxGSM. These include download, getopt, messages, exit, trap

### Module Order

Modules will launch in sequence as they are required by commands. The following modules will normally run in the following order when a command is executed:

```
core
command
check
fix
```

It is possible to see the order that modules run by enabling `./gameserver dev`. Once enabled the module order will be saved in `dev-debug-function-order.log`

Example output of `./gameserver stop`

```
+ core_functions.sh
++ core_legacy.sh
++ core_messages.sh
++ core_dl.sh
++ core_trap.sh
+ core_getopt.sh
+++ command_stop.sh
++++ check.sh
+++++ check_root.sh
+++++ check_tmuxception.sh
+++++ check_permissions.sh
+++++ check_system_dir.sh
+++++ check_logs.sh
+++++ check_deps.sh
++++++ info_distro.sh
+++++ check_config.sh
+++++ check_ip.sh
++++++ info_config.sh
++++++ info_parms.sh
+++++ check_status.sh
++++ info_config.sh
++++ check_status.sh
++++ check_status.sh
++++ check_status.sh
++++ check_status.sh
++++ core_exit.sh
```

## How Modules are Called

In bash to call another bash script, the `source` command is used. However, in LinuxGSM this is handled by the `core_modules.sh` module. This allows LinuxGSM to automatically download a module the first time it is used and then call the script.

To call a module simply add the name of the module file e.g `info_config.sh` and the module will be called. If a new module is being added it must be added to the list of modules in `core_functions.sh` like so.

```
info_config.sh(){
functionfile="${FUNCNAME}"
fn_fetch_function
}
```


# Fixes

##

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


# Core

### **core\_dl.sh**

This is the first script to be run when `gameserver`is executed. This script allows for fetching LinuxGSM core files, but also for downloading big files within kind of an API.

### **core\_modules.sh**

This is the second script to be run when `gameserver`is executed. This script declares all functions and fetches them when they are required.

### **core\_getopt.sh**

This is the third and last script to be run when `gameserver`is executed. This script allows for setting and printing available commands to the user.

### **core\_messages.sh**

This script allows for easy message output and logging. More details about it in the next part.


# Game Server Querying

\[WIP]


# 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

**Logging**

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


# Checks

Any script file must run `check.sh` at some point. Within `check.sh`, you will then choose what tests to run for a given function. The syntax of check.sh 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:

* check\_config.sh checks for a missing config file or a wrong parameter.
* check\_deps.sh checks for missing dependencies and contains requirements
* check\_glibs.sh checks if the server has the correct Glibc version or a fix available.
* check\_ip.sh automatically identifies the server interface IP.
* check\_logs.sh checks if log files exist.
* check\_permissions.sh checks ownership & permissions of scripts, files and directories
* check\_root.sh checks if the user tried to run the script as root
* check\_status.sh checks the process status of the server. Either online or offline
* check\_steamcmd.sh checks if SteamCMD is installed correctly
* check\_system\_dir.sh checks if systemdir is accessible
* check\_system\_requirements.sh checks RAM requirements (maybe more into the future)
* check\_tmuxception.sh checks and prevents server start from tmux or screen


# Exit

**core\_exit.sh**

This script allows for the use of exit codes which will print different outputs to LinuxGSM logs. Running `core_exit.sh` defaults exitcode variable to 0 which stands for a proper exit

* Normal exit: exitcode=0
* FATAL exitcode=1
* ERROR: exitcode=2
* WARN: exitcode=3


# Install

#### Server installation

Installing a new server is mainly done through two scripts:

* install\_server\_files.sh
* install\_config.sh

Sometimes, another script is required, such as for TeamSpeak 3: `update_ts3.sh`


# Debuggins

## 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. Display your main "gameserver" file on GitHub, and select "Raw".
2. Make a test user, login to it
3. wget your Raw link and chmod +x the script.
4. Edit your "gameserver" file by changing GitHub information to your username and repo and branch.

   ```bash
   ## Github Branch Select
   # Allows for the use of different function files
   # from a different repo and/or branch.
   githubuser="YourUsername"
   githubrepo="YourRepository"
   githubbranch="YourBranchName"
   ```

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. It's caused by your own code parts and you know how to fix it: Just go on and fix it.
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. 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.


# Style Guide

In order to make LinuxGSM as coherent as possible, we adopted some code conventions to follow.\
Here are some of them.

## Variables

#### Naming variables

Variables should be made of lowercase letters only and should be descriptive enough to understand its purpose (even if the variable is longer that preferred).

### Defining variables

Any variable should be defined through double quotes

```bash
var="value"
```

### Calling variables

Variable should always be called between brackets and double quotes to prevent globbing and word splitting.

```bash
echo "${var}"
```

### Directories

Directories are called using LinuxGSM directories variables, or relative to those. Common directory variables can be found in `linuxgsm.sh` and `_default.cfg` .

Examples:

```bash
mkdir -pv "${servercfgdir}"
mkdir -pv "${lgsmdir}/config-default/config-game"
du -sh "${rootdir}" 2> /dev/null
find "${executabledir}/bin"
```

## `if` Statements

If statements should look like the following

```
if [ "${shortname}" == "csgo" ];then
   # content
fi
```

if statements with multiple options like so

```
if [ "${shortname}" == "csgo" ]||[ "${shortname}" == "css" ]; then
   # content
fi
```

## Conditional checks

### Syntax

* The `if [ statement ]; then` should be a one-liner operation.
* Signs comparators like `==`, `lt`, `lt` etc. are preferred to `-eq`, `-le`, `-lt`.
* Anything within an if statement must be tabulated one step deeper.

Example:

```bash
if [ "${test}" == "${var}" ]; then
    mycheck="true"
fi
```

### Expression Standards

Common if expressions LinuxGSM uses. More expressions [here](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html).

| Expression | Description                          |
| ---------- | ------------------------------------ |
| `-d`       | if directory exists                  |
| `! -d`     | if directory does not exist          |
| `-f`       | if file exists                       |
| `! -f`     | if file does not exist               |
| `-z`       | true if length of string is zero     |
| `-n`       | true if length of string is non-zero |
| `-v`       | true if the variable exists          |

{% hint style="danger" %}
Do not use `! -z` or `! -n`
{% endhint %}

There is a distinct difference between -n and -v.

-n is used to check is a variable is set and not if it exists\
-v is used to check if a variable exists and not it is set

```bash
var="set"
if [ -n "${var}" ]; then
 # Variable is set
fi
```

```bash
var=""
if [ -z "${var}" ]; then
 # Variable is not set
fi
```

```
var=""
# OR
var="set"
if [ -v var ]; then
 # Variable exista
fi
```

```
# var is missing
if [ ! -v var ]; then
 # Variable does not exist
fi
```

## Loops

* Loops should be a one liner statement.
* Anything within a loop must be tabulated one step deeper.

```bash
while [ "${var}" < "${cap}" ]; do
    echo "This is tabulated"
    let var=var+1
done
```

## Comments

As English is not always the native language of a developer, comments should use a formal writing style and be straight to the point. If unsure this short formal writing [guide](http://www2.ivcc.edu/rambo/tip_formal_writing_voice.htm) will help.

```bash
# Using comments help developers understand complex code, but should be used sparingly.
```

## Functions

* Function should be named starting with `fn_` and using lowercase letters only.
* Any recurrent task should be put into a function.
* Anything within a function must be tabulated one step deeper.

Example:

```bash
fn_myfunction(){
    echo "This is tabulated"
}
```

## Messages

* Messages should be given using core\_messages.sh forms
* Additional information messages are given in the form of `echo -e " * Message here"`

## Automated Messages

Automated messages are used with any commands that are non-interactive. Examples of this include Start, Stop and Monitor. There are various different alert messages available see [Exit-Codes](broken://pages/-Lgn9gyZzujsevVI68ug) for details.

Each automated message starts with `fn_print_dots` to show a process is happening but with no known outcome.

`fn_print_dots`

```
[ .... ] Starting fctrserver:
```

Once an outcome of a process is known the message uses an outcome message like `fn_print_ok` or `fn_print_fail`

fn\_print\_ok

```
[  OK  ] Starting fctrserver: Factorio Server
```

The option of a newline is also available by appending `_nl` for example `fn_print_ok_nl`. This will add a carriage return to the message preventing it being overwritten by the next message.

```
[  OK  ] Stopping fctrserver: Graceful: CTRL+c: 2: OK
[ .... ] Starting fctrserver: Factorio Server
```

#### Characteristics

Interactive messages contain extra detail at the begining of the message that is pre-populated. Full stops must `not` be used with this type of message.

### Interactive Messages

Interactive messages are used with any commands that have interactive elements. Examples of this include Install, console and debug. There are various different alert messages available see \[\[Exit-Codes]] for details.

```
Warning! If fctrserver is already running it will be stopped.
```

standard echo commands are normally used to supplement an alert or if an alert is not required. Bullet points can also be used

```
Information! Press "CTRL+b" then "d" to exit console.
Warning! Do NOT press CTRL+c to exit.
* https://docs.linuxgsm.com/commands/console
```

#### Characteristics

Treat interactive messages as a standard sentence. All messages must begin with a capital and end with a full stop


# Shellcheck Linter

\[WIP]


# Text Editor Settings

\[WIP] discuss using LF and white space remover etc.

Below is information on requirements needed when using a text editor to work on LinuxGSM code. All the recommended text editors can be set up to take into account the requirements.

## Indentation

LinuxGSM uses `tabs` instead of spaces, it is possible to specify tabs and convert spaces to tabs if required.

## Line Ending

All files must be saved using `LF` (Line Feed) line endings which is the line ending used by UNIX based systems. Please ensure that your text editor is saving in `LF` format as failure to do so will cause BASH scripts to stop functioning.

For more info about line endings check out the article "[The Great Newline Schism](https://blog.codinghorror.com/the-great-newline-schism/)".

## Trailing White Spaces

When developing code sometimes it can be easy to end up with trailing white spaces. as shown below.

```
fn_example_func(){
    # The line below has two spaces after its final character
    code••
}
```

All code must have whitespaces removed to keep code tidy. Many text editors have a feature that will automaticly remove trailing whitespaces when a file is saved. It is highly reccomended this feature is turned on.


