マルチゲームサーバの構築を,自宅でする(4/4 ゲームサーバの構築)

技術
この記事は約44分で読めます。

この記事は 2024 年 04 月 20 日に Qiita に投稿された記事を元に作成しています.
Qiita 側の更新は停止しています.

  1. Debian サーバのセットアップ
  2. ターミナルと外部接続の設定
  3. ファイアウォールの設定
  4. ゲームサーバの構築 (← この記事の内容)

前 3 記事分の作業で,やっとのことでサーバマシンのセットアップが完了しました.
この記事でようやく,本題のゲームサーバの構築に取り掛かります.

が,その前にゲームサーバを構築するための共通設定を行います.

初期インストール

(任意)Visual Studio Code

今後シェルスクリプトを作成するために,Visual Studio Code を使用します.
apt のリポジトリを追加してインストールします.

ハードウェアに関係する制約があるので注意してください.
amd64 以外の環境では,arm64 などの適切なリポジトリを追加してください.

VisualStudioCode - Debian Wiki
$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
$ sudo install -o root -g root -m 644 microsoft.gpg /usr/share/keyrings/microsoft-archive-keyring.gpg
$ sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
$ rm -rf microsoft.gpg
$ sudo apt update
$ sudo apt install -y code

VS Code を起動して,各種設定,個人設定の同期を行います.

root 実行用の設定

sudocode を実行するために,エイリアスを設定します.

$ vim ~/bin/code-root.sh
#!/bin/bash

sudo code "$@" --user-data-dir=/root/.config/Code/ --no-sandbox
exit 0

作成した code-root.sh に実行権限を付与します.

$ chmod 744 ~/bin/code-root.sh

.bash_aliasescode-root のエイリアスを追加します.

$ sudo vim ~/.bash_aliases
# Visual Studio Code
alias code-root='/home/{{ユーザ名}}/bin/code-root.sh'

.bash_aliases を反映します.

$ source ~/.bash_aliases

code-root を実行して,VS Code が起動することを確認します.

$ code-root

ユーザ権限で実行した際の設定は読み込まれないため,最低限の VS Code の設定を行います.

tmux

ゲームサーバ実行時に,tmux を使用してセッションを分割します.

GitHub - tmux/tmux: tmux source code
tmux source code. Contribute to tmux/tmux development by creating an account on GitHub.

brewtmux をインストールします.

$ brew install tmux

aptxclip をインストールして,tmux のクリップボード機能を有効にします.

$ sudo apt install -y xclip

~/.tmux.conf を作成し,設定を記述します.

$ sudo vim ~/.tmux.conf

好みで設定可能な部分ですが,筆者は下記の設定を使用しています.

設定時の注意
Prefix の設定は,デフォルトから変更しておくことを推奨します.
今後 tmux セッション内で別の tmux セッションを立ち上げる際に,キーバインドが競合するためです.

例では,Ctrl + b から Ctrl + f に変更しています.

# Prefix
unbind C-b
set -g prefix C-f
bind C-f send-prefix

この状態で,入れ子で立ち上げる tmux のセッションではデフォルトの設定を使うことで,競合を回避しています.
もちろん,競合が回避できればこの限りではありません.

下記例では,ステータスバーの背景色を Xterm 256 カラーの 88(暗赤)に設定しています(#[bg=colour88] の部分).
対応表は下記リンクの画像を参照してください.

xterm - Wikipedia
# Prefix
unbind C-b
set -g prefix C-f
bind C-f send-prefix

# Environment
set -sg escape-time 100
#set-option -g xterm-keys on
set -g history-limit 10000

# Mouse
bind-key m set-option -g mouse on \; display 'Mouse ON'
bind-key M set-option -g mouse off \; display 'Mouse OFF'

set -g mouse on
bind -T root WheelUpPane   if-shell -F -t = '#{alternate_on}' 'send-keys -M' 'select-pane -t =; copy-mode -e; send-keys -M'
bind -T root WheelDownPane if-shell -F -t = '#{alternate_on}' 'send-keys -M' 'select-pane -t =;               send-keys -M'

bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel 'xclip -selection clipboard -i'

set-window-option -g mode-keys vi
setw -g mode-keys vi
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'y' send -X copy-pipe-and-cancel 'xclip -selection clipboard -i'
unbind -T copy-mode-vi 'Enter'
bind-key -T copy-mode-vi 'Enter' send -X copy-pipe-and-cancel 'xclip -selection clipboard -i'

# Command
bind r source-file ~/.tmux.conf \; display '.tmux.conf Reloaded'
bind | split-window -h
bind - split-window -v

# Window
set -g window-style 'fg=colour239'
set -g window-active-style 'fg=terminal'
set-window-option -g window-status-current-style bright
set-window-option -g window-status-style dim

set-option -g status-interval 1

set-option -g status-justify 'left'
set-option -g status-bg 'colour238'
set-option -g status-fg 'colour255'

set-option -g status-left-length 50
set-option -g status-right-length 100

set-option -g status-left '#[bg=colour88][#H] #S #[default]'
set-option -g status-right '#[bg=colour88][%Y-%m-%d(%a) #(TZ="Asia/Tokyo" date +%%H:%%M:%%S)]#[default]'

set-window-option -g window-status-current-format '#[bg=colour196,bold] #I: #W #[default]'
set-window-option -g window-status-format ' #I: #W '

# Color
set -g default-terminal 'screen-256color'
set -g terminal-overrides ',xterm:colors=256'

作成した ~/.tmux.conf を今後のテンプレートとして使い回すため,/etc/tmux/ にコピーします.

$ sudo mkdir -p /etc/tmux
$ sudo cp ~/.tmux.conf /etc/tmux/.tmux.conf
$ sudo chmod 744 /etc/tmux/.tmux.conf

テンプレート .tmux.confPrefix をコメントアウトしてデフォルトに戻します.

$ sudo vim /etc/tmux/.tmux.conf
# Prefix
#unbind C-b
#set -g prefix C-f
#bind C-f send-prefix
# ︙

tmuxinator

tmuxinator をインストールして,tmux のセッションを管理します.

GitHub - tmuxinator/tmuxinator: Manage complex tmux sessions easily
Manage complex tmux sessions easily. Contribute to tmuxinator/tmuxinator development by creating an account on GitHub.

brewtmux をインストールします.

$ brew install tmuxinator

.profile に tmuxinator が使うエディタを環境変数 EDITOR で指定します.

$ vim ~/.profile
# set PATH so it includes Homebrew
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

# set EDITOR for tmuxinator
export EDITOR='vim'

.profile を反映します.

$ source ~/.profile

ゲームサーバ監視用のレイアウト servers を作成します.
例として,Terraria サーバ運用開始後の状態を想定しています.

$ tmuxinator new servers
name: servers
#root: ~/
# ︙
startup_window: main
#︙
startup_pane: 0
#︙
windows:
  - main:
      layout: main-horizontal
      # Synchronize all panes of this window, can be enabled before or after the pane commands run.
      # 'before' represents legacy functionality and will be deprecated in a future release, in favour of 'after'
      # synchronize: after
      panes:
        - Main:
        - Sub:
  - terraria:
      layout: 8c65,205x39,0,0{102x39,0,0,0,102x39,103,0[102x19,103,0,1,102x19,103,20,2]}
      panes:
        - Terraria:
          #  - sudo -iu terraria
          #  - tmux a -t terraria
        - Console:
          #  - sudo -iu terraria
          #  - /opt/terraria/terraria_server.sh start
        - PortMonitor:
          #  - sudo iftop -i enp7s0 -PnNf 'port 7777'

コメントアウト部分について
まだ terraria ユーザが作成されていないため,tmux 起動時に自動実行されるコマンドはコメントアウトしています.
ので,この時点で tmuxinatorservers を起動することは想定していません.

注意
tmuxinatorsudo 用のパスワードは事前に入力できないため,ユーザ切替後に実行されるコマンドは設定できません.
「どのコマンドを実行する想定か」をコメントアウトしておくことを推奨します.

sudoers をいい具合に調整すれば,tmuxinatorsudo が使えるかもしれませんが,それ以外のセキュリティ上のリスクが高すぎるため,推奨しません.

tmuxinatorservers を起動するエイリアスを設定します.

$ vim ~/.bash_aliases
# tmuxinator
alias servers='tmuxinator start servers'

.bash_aliases を反映します.

$ source ~/.bash_aliases

iftop

iftop をインストールして,ポート監視を行います.

$ sudo apt install -y iftop

以降,ようやくゲームサーバの構築に取り掛かります.

共通設定

権限グループ作成

ゲームサーバ起動用ユーザを登録するグループを作成します.

$ sudo groupadd -g 10000 gameserver

ユーザごとにインストールが必要なパッケージについて,sudo の実行許可を設定します.
ここでは,apt での tmux インストール許可を付与します.

$ sudo visudo
# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# Allow members of group gameserver to execute limited commands
%gameserver   ALL=(ALL:ALL) ALL NOPASSWD: /usr/bin/apt install -y tmux, /usr/bin/apt purge -y tmux

汎用パッケージインストール

SteamCMD

steamcmd をインストールします.

$ sudo mkdir -p /usr/bin/steamcmd
$ cd /usr/bin/steamcmd
$ sudo wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
$ sudo tar -xvzf steamcmd_linux.tar.gz
$ sudo rm -rf steamcmd_linux.tar.gz
$ cd ~

x86 パッケージを有効化して,steamcmd を実行可能にします.

$ sudo dpkg --add-architecture i386
$ sudo apt update

steamcmd が必要とする GCC サポートライブラリをインストールします.

$ sudo apt install -y lib32gcc-s1

gameserver グループに所属するユーザであれば,steamcmd を実行できるように設定します.

$ sudo visudo
# Allow members of group gameserver to execute limited commands
%gameserver   ALL=(ALL:ALL) ALL NOPASSWD: ..., /usr/bin/steamcmd/steamcmd.sh

(任意)Visual Studio Code

gameserver グループのユーザでも code-root を実行できるように設定します.

$ sudo visudo
# Allow members of group gameserver to execute limited commands
%gameserver   ALL=(ALL:ALL) ALL NOPASSWD: ..., /home/{{ユーザ名}}/bin/code-root.sh

Terraria ゲームサーバの構築

ファイアウォール設定

ルール設定

gufw を使用して,ファイアウォールの設定を行います.

  • Terraria
    • ポリシー : Allow
    • 方向 : In
    • インターフェース : All Interfaces
    • ログ : すべてログ出力する
    • プロトコル : 両方
    • From
    • IP : 空欄
    • ポート : 空欄
    • To
    • IP : 空欄
    • ポート : 7777

ルータ設定

ルータの設定画面から,ポート変換を設定します.

  • 詳細設定
    • セキュリティー
    • ポート変換
      • グループ : Terraria
      • (TCP)
        • Internet 側 IP アドレス : エアステーションの Internet 側 IP アドレス
        • プロトコル : 任意の TCP ポート,{{外部 Terraria ポート}}
        • LAN 側 IP アドレス : {{サーバマシンの IP アドレス}}
        • LAN 側ポート : 7777
      • (UDP)
        • Internet 側 IP アドレス : エアステーションの Internet 側 IP アドレス
        • プロトコル : 任意の UDP ポート,{{外部 Terraria ポート}}
        • LAN 側 IP アドレス : {{サーバマシンの IP アドレス}}
        • LAN 側ポート : 7777

外部ポートについて
{{外部 Terraria ポート}} は,LAN 外部から接続する際のポート番号です.
ポート変換をしない場合は,このセクションは飛ばしてください.

実行ユーザ作成

gameserver グループに所属する terraria ユーザを作成します.

$ sudo useradd -u 10000 -g gameserver -m -s /bin/bash terraria
$ sudo passwd terraria

PS1 設定

作成した terraria ユーザのプロンプト文字色を変更します.

$ sudo -iu terraria
terraria$ vim ~/.bashrc

下記例では,文字色を Xterm 256 カラーの 34(緑)に設定しています(\033[38;5;34m の部分).
対応表は下記リンクの画像を参照してください.

xterm - Wikipedia
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[38;5;34m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

.bashrc を反映します.

terraria$ source ~/.bashrc

tmux 設定

tmux の設定ファイルを汎用ファイルからコピーして,色設定を変更します.

terraria$ cp /etc/tmux/.tmux.conf ~
terraria$ vim ~/.tmux.conf

下記例では,ステータスバーの背景色を Xterm 256 カラーの 28(暗緑)に設定しています(#[bg=colour28] の部分).
対応表は下記リンクの画像を参照してください.

xterm - Wikipedia
︙
# Window
︙
set-option -g status-left '#[bg=colour28][#H] #S #[default]'
set-option -g status-right '#[bg=colour28][%Y-%m-%d(%a) #(TZ="Asia/Tokyo" date +%%H:%%M:%%S)]#[default]'

set-window-option -g window-status-current-format '#[bg=colour34,bold] #I: #W #[default]'
︙

Terraria サーバインストール

Terraria サーバのインストール手順については,下記記事を参考に一部変更しています.

【Ubuntu】Terrariaサーバーのインストール
Ubuntu Server 20.04にTerrariaサーバをインストールする方法です。 VPS上にTerrariaサーバ構築することで、24時間好きな時にマルチプレイで遊ぶことができるようになります。 作業工程 Terrariaサーバを

外部からの接続確認について
今後発生するゲームサーバへの接続確認時に,LAN 外部からも接続する必要があります.
協力者や自分で操作可能な LAN 外のクライアントがあれば,その端末から接続確認を行ってください.

筆者にはその環境がなかったため,ネットワーク内のクライアントに VPN を導入して接続確認を行いました.

  1. インストールディレクトリ作成

    terraria$ exit
    $ sudo mkdir -p /opt/terraria/{bin,downloads}
  2. 権限設定

    $ sudo chown -R terraria:gameserver /opt/terraria
  3. ダウンロード

    下記からダウンロード用 URL をコピー

    ダウンロード用 URL
    https://terraria.org/api/download/pc-dedicated-server/terraria-server-****.zip の形式です.

    $ sudo -iu terraria
    terraria$ cd /opt/terraria/downloads
    terraria$ wget {{ダウンロード用 URL}}
  4. 展開

    terraria$ unzip {{ダウンロードファイル}} -d /opt/terraria/bin
  5. 設定ファイル作成

    terraria$ cp -p /opt/terraria/bin/****/Windows/serverconfig.txt ..
    terraria$ vim /opt/terraria/serverconfig.txt
    # serverconfig.txt
    world=/opt/terraria/bin/worlds/{{ワールド名}}.wld
    worldname={{ワールド名}}
    password={{パスワード}}
    worldpath=/opt/terraria/worlds

    その他の項目は,適宜入力またはデフォルト値で問題ありません.

  6. サーバ起動確認

    terraria$ cd /opt/terraria/bin/****/Linux
    terraria$ chmod 744 TerrariaServer.bin.x86_64
    terraria$ ./TerrariaServer.bin.x86_64 -config /opt/terraria/serverconfig.txt
    Terraria Server v*.*.*.*
    
    Listening on port 7777
    Type 'help' for a list of commands.
    
    : Server started

    接続確認
    : Server started が表示されたら,クライアントから接続確認を行います.
    Multiplayer > Join via IP を開き,LAN 内の場合は {{プライベート IP アドレス}}:7777,LAN 外の場合は {{グローバル IP アドレス}}:{{外部 Terraria ポート}} でゲームサーバに接続できることを確認します.

  7. サーバ停止

    Ctrl + C でサーバを停止します.

サーバ起動/停止スクリプト作成

tmux でサーバを起動/停止/再起動するスクリプトを作成します.

terraria$ exit
$ code-root /opt/terraria/terraria_server.sh
#!/bin/bash

function start() {
    if pgrep -u "${USER_NAME}" -f "${SERVER_EXEC}" >/dev/null; then
        echo -e "\e[31mサーバ[${SERVER_EXEC}]は既に起動しています\e[m"
        return 1
    else
        echo "サーバ[${SERVER_EXEC}]を起動します"
        tmux new-session -d -s "${SESSION_NAME}"
        tmux send-keys -t "${SESSION_NAME}":0 "${SERVER_DIR}/${SERVER_EXEC} -config ${SERVER_CONFIG} 2>&1 | tee -a ${LOG_FILE}" C-m
        RETURN_CODE=$?
        if [ ${RETURN_CODE} -eq 0 ]; then
            echo -e "\e[32mサーバ[${SESSION_NAME}]を起動しました\e[m"
        else
            echo -e "\e[31mサーバ[${SESSION_NAME}]の起動に失敗しました\e[m"
        fi
        return ${RETURN_CODE}
    fi
}

function stop() {
    if pgrep -u "${USER_NAME}" -f "${SERVER_EXEC}" >/dev/null; then
        echo "サーバ[${SERVER_EXEC}]を停止します"
        tmux send-keys -t "${SESSION_NAME}":0 "say SERVER SHUTTING DOWN IN 30 SECONDS!!" C-m
        sleep 10
        tmux send-keys -t "${SESSION_NAME}":0 "say SERVER SHUTTING DOWN IN 20 SECONDS!!" C-m
        sleep 10
        tmux send-keys -t "${SESSION_NAME}":0 "say SERVER SHUTTING DOWN IN 10 SECONDS!!" C-m
        sleep 5
        tmux send-keys -t "${SESSION_NAME}":0 "say SERVER SHUTTING DOWN IN 5 SECONDS!!" C-m
        sleep 4
        tmux send-keys -t "${SESSION_NAME}":0 "say SERVER SHUTTING DOWN STARTING NOW!!" C-m
        tmux send-keys -t "${SESSION_NAME}":0 "exit" C-m
    else
        echo -e "\e[31mサーバ[${SERVER_EXEC}]は停止しています\e[m"
        return 1
    fi

    while :
    do
        if pgrep -u "${USER_NAME}" -f "${SERVER_EXEC}" >/dev/null; then
            echo -e "\e[33mサーバ[${SERVER_EXEC}]停止待機中\e[m"
            sleep 10
        else
            tmux kill-session -t "${SESSION_NAME}":0
            RETURN_CODE=$?
            if [ ${RETURN_CODE} -eq 0 ]; then
                echo -e "\e[32mサーバ[${SESSION_NAME}]を停止しました\e[m"
            else
                echo -e "\e[31mサーバ[${SESSION_NAME}]の停止に失敗しました\e[m"
            fi
            return ${RETURN_CODE}
        fi
    done
}

# 絶対パス
SHELL_HOME="$(cd $(dirname $0) && pwd)"

# ユーザ名
USER_NAME="terraria"
# tmux セッション名
SESSION_NAME="terraria"
# サーバのバージョン
SERVER_VERSION="{{サーバのバージョン}}"
# サーバのディレクトリ
SERVER_DIR="${SHELL_HOME}/bin/${SERVER_VERSION}/Linux"
# サーバの実行ファイル
SERVER_EXEC="TerrariaServer.bin.x86_64"
# サーバの設定ファイル
SERVER_CONFIG="${SHELL_HOME}/serverconfig.txt"
# ログファイル
LOG_FILE="${SHELL_HOME}/terraria_server.log"

# ユーザ取得
USER_ID=($(whoami))
if [ -z "${USER_ID}" -o "${USER_ID}" != "${USER_NAME}" ]; then
    echo -e "\e[33mユーザ ${USER_NAME} で実行してください\e[m"
    exit 1
fi

# ログファイル初期化
: >"${LOG_FILE}"

# オプション
case "${1}" in
    start)
        start
        RETURN_MAIN=$?
        ;;
    stop)
        stop
        RETURN_MAIN=$?
        ;;
    restart)
        stop
        RETURN_MAIN=$?
        if [ ${RETURN_MAIN} -eq 0 ]; then
            start
            RETURN_MAIN=$?
        fi
        ;;
    *)
        echo -e "\e[33mオプションは [start / stop / restart] のいずれかを指定してください\e[m"
        exit 1
        ;;
esac

exit ${RETURN_MAIN}

編集が必要な部分について
{{サーバのバージョン}} には,/opt/terraria/bin/****/Linux に展開した Terraria サーバのバージョンを指定してください.
公式サイトからダウンロードしたバージョンに依存するため,適宜変更してください.

作成した terraria_server.sh に実行権限を付与します.

$ sudo -iu terraria
terraria$ chmod 744 /opt/terraria/terraria_server.sh

ログファイルを初期作成し,実行権限を付与します.

terraria$ touch /opt/terraria/terraria_server.log
terraria$ chmod 744 /opt/terraria/terraria_server.log

サーバの起動に必要な tmuxterraria ユーザにもインストールします.

terraria$ sudo apt install -y tmux

起動スクリプトを実行

start オプションを指定して,サーバを起動します.

terraria$ /opt/terraria/terraria_server.sh start

tmux セッションに接続し,サーバが起動していることを確認します.

terraria$ tmux a -t terraria
Terraria Server v*.*.*.*

Listening on port 7777
Type 'help' for a list of commands.

: Server started

接続確認
: Server started が表示されたら,クライアントから接続確認を行います.

停止スクリプトを実行

stop オプションを指定して,サーバを停止します.

terraria$ /opt/terraria/terraria_server.sh stop

tmux セッションが停止していることを確認します.

terraria$ tmux ls
no server running on /tmp/tmux-1001/default

tmuxinator 設定

tmuxinatorservers を編集し,コメントアウトしていた terraria セッションを有効化します.

terraria$ exit
$ tmuxinator edit servers
#︙
windows:
  # ︙
  - terraria:
      layout: 8c65,205x39,0,0{102x39,0,0,0,102x39,103,0[102x19,103,0,1,102x19,103,20,2]}
      panes:
        - Terraria:
            - sudo -iu terraria
          #  - tmux a -t terraria
        - Console:
            - sudo -iu terraria
          #  - /opt/terraria/terraria_server.sh start
        - PortMonitor:
            - sudo iftop -i enp7s0 -PnNf 'port 7777'

tmuxinatorservers を起動します.

$ servers

次のようなレイアウトが表示されれば,terraria セッションが正常に起動しています.

terrariaServer

実行時ログについて

tmux セッション内で実行されるコマンドのログは,/opt/terraria/terraria_server.log に出力されます.
基本的には,tmux セッション内での履歴を別ファイルでミラーリングするために使用しています.
上記のスクリプトそのままだと,ログは 1 世代分しか保存されません.

複数世代のログを保存するには,サーバ停止時にタイムスタンプでログファイルをリネームして退避させるなどログローテーションを行う必要があります.

サーバの自動起動設定

筆者は,サーバの自動起動設定を行っておらず,都度手動で起動しています.
サーバの自動起動設定については,systemd を使用して設定することが一般的です.

詳しくは,先ほども参照した下記記事に記載されています.

【Ubuntu】Terrariaサーバーのインストール
Ubuntu Server 20.04にTerrariaサーバをインストールする方法です。 VPS上にTerrariaサーバ構築することで、24時間好きな時にマルチプレイで遊ぶことができるようになります。 作業工程 Terrariaサーバを

Valheim ゲームサーバの構築

Valheim サーバの構築について
基本的には Terraria サーバの構築手順と同じです.
が,変換するポートやユーザ名などが微妙に異なるので,全て記載しています.

ファイアウォール設定

ルール設定

gufw を使用して,ファイアウォールの設定を行います.

  • Valheim
    • ポリシー : Allow
    • 方向 : In
    • インターフェース : All Interfaces
    • ログ : すべてログ出力する
    • プロトコル : UDP
    • From
    • IP : 空欄
    • ポート : 空欄
    • To
    • IP : 空欄
    • ポート : 2456:2458

ルータ設定

ルータの設定画面から,ポート変換を設定します.

  • 詳細設定
    • セキュリティー
    • ポート変換
      • グループ : Valheim
      • (TCP)
        • Internet 側 IP アドレス : エアステーションの Internet 側 IP アドレス
        • プロトコル : 任意の TCP ポート,{{外部 Valheim ポート}}
        • LAN 側 IP アドレス : {{サーバマシンの IP アドレス}}
        • LAN 側ポート : 2456
      • (UDP)
        • Internet 側 IP アドレス : エアステーションの Internet 側 IP アドレス
        • プロトコル : 任意の UDP ポート,{{外部 Valheim ポート}}
        • LAN 側 IP アドレス : {{サーバマシンの IP アドレス}}
        • LAN 側ポート : 2456

変換するポートについて
Valheim サーバは,2456:2458 の 3 つのポートを使用するとマニュアルに記載されています.
が,とりあえずポート変換は 2456 だけで問題なさそうです.
ポート変換をしない場合は,このセクションは飛ばしてください.

実行ユーザ作成

gameserver グループに所属する valheim ユーザを作成します.

$ sudo useradd -u 10001 -g gameserver -m -s /bin/bash valheim
$ sudo passwd valheim

PS1 設定

作成した valheim ユーザのプロンプト文字色を変更します.

$ sudo -iu valheim
valheim$ vim ~/.bashrc

下記例では,文字色を Xterm 256 カラーの 27(青)に設定しています(\033[38;5;27m の部分).
対応表は下記リンクの画像を参照してください.

xterm - Wikipedia
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[38;5;27m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

.bashrc を反映します.

valheim$ source ~/.bashrc

tmux 設定

tmux の設定ファイルを汎用ファイルからコピーして,色設定を変更します.

valheim$ cp /etc/tmux/.tmux.conf ~
valheim$ vim ~/.tmux.conf

下記例では,ステータスバーの背景色を Xterm 256 カラーの 17(暗青)に設定しています(#[bg=colour17] の部分).
対応表は下記リンクの画像を参照してください.

xterm - Wikipedia
︙
# Window
︙
set-option -g status-left '#[bg=colour17][#H] #S #[default]'
set-option -g status-right '#[bg=colour17][%Y-%m-%d(%a) #(TZ="Asia/Tokyo" date +%%H:%%M:%%S)]#[default]'

set-window-option -g window-status-current-format '#[bg=colour27,bold] #I: #W #[default]'
︙

Valheim サーバインストール

  1. libpulse-dev インストール

    Valheim サーバが必要とするライブラリをインストールします.

    valheim$ exit
    $ sudo apt install -y libpulse-dev
  2. インストールディレクトリ作成

    $ sudo mkdir -p /opt/valheim/bin
  3. 権限設定

    $ sudo chown -R valheim:gameserver /opt/valheim
  4. ダウンロード

    steamcmd を使用して,Valheim 用の Dedicated Server をインストールします.

    $ sudo -iu valheim
    valheim$ sudo /usr/bin/steamcmd/steamcmd.sh
    > force_install_dir /opt/valheim/bin
    > login anonymous
    > app_update 896660 validate
    > quit
  5. 設定ファイル作成

    valheim$ cp -p /opt/valheim/bin/start_server.sh /opt/valheim/valheim_server.sh
    valheim$ vim /opt/valheim/valheim_server.sh
    #!/bin/bash
    
    export templdpath=$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=/opt/valheim/bin/linux64:$LD_LIBRARY_PATH
    export SteamAppId=892970
    ︙
    /opt/valheim/bin/valheim_server.x86_64 -name "{{サーバ名}}" -port 2456 -world "{{ワールド名}}" -password "{{パスワード}}" -savedir "/opt/valheim/" -public 0 -nographics -batchmode
    
    export LD_LIBRARY_PATH=$templdpath

    その他の項目は,適宜入力またはデフォルト値で問題ありません.

    各オプションについて
    valheim_server.x86_64 のオプションの設定項目や制限については,/opt/valheim/bin/ にダウンロードされる Valheim Dedicated Server Manual.pdf に記載されています.

  6. サーバ起動確認

    valheim$ /opt/valheim/valheim_server.sh
    ︙
    Game server connected

    接続確認
    Game server connected が表示されたら,クライアントから接続確認を行います.

  7. サーバ停止

    Ctrl + C でサーバを停止します.

サーバ起動/停止スクリプト作成

tmux でサーバを起動/停止/再起動するスクリプトを作成します.

valheim$ exit
$ code-root /opt/valheim/valheim_server.sh
#!/bin/bash

function start() {
    if pgrep -u "${USER_NAME}" -f "${SERVER_EXEC}" >/dev/null; then
        echo -e "\e[31mサーバ[${SERVER_EXEC}]は既に起動しています\e[m"
        return 1
    else
        echo "サーバ[${SERVER_EXEC}]を起動します"
        tmux new-session -d -s "${SESSION_NAME}"
        tmux send-keys -t "${SESSION_NAME}":0 "${SERVER_DIR}/${SERVER_EXEC} ${SERVER_ARGS} 2>&1 | tee -a ${LOG_FILE}" C-m
        RETURN_CODE=$?
        if [ ${RETURN_CODE} -eq 0 ]; then
            echo -e "\e[32mサーバ[${SESSION_NAME}]を起動しました\e[m"
        else
            echo -e "\e[31mサーバ[${SESSION_NAME}]の起動に失敗しました\e[m"
        fi
        return ${RETURN_CODE}
    fi
}

function stop() {
    if pgrep -u "${USER_NAME}" -f "${SERVER_EXEC}" >/dev/null; then
        echo "サーバ[${SERVER_EXEC}]を停止します"
        tmux send-keys -t "${SESSION_NAME}":0 "Say SERVER SHUTTING DOWN IN 30 SECONDS!!" C-m
        sleep 10
        tmux send-keys -t "${SESSION_NAME}":0 "Say SERVER SHUTTING DOWN IN 20 SECONDS!!" C-m
        sleep 10
        tmux send-keys -t "${SESSION_NAME}":0 "Say SERVER SHUTTING DOWN IN 10 SECONDS!!" C-m
        sleep 5
        tmux send-keys -t "${SESSION_NAME}":0 "Say SERVER SHUTTING DOWN IN 5 SECONDS!!" C-m
        sleep 4
        tmux send-keys -t "${SESSION_NAME}":0 "Say SERVER SHUTTING DOWN STARTING NOW!!" C-m
        tmux send-keys -t "${SESSION_NAME}":0 C-c
        tmux send-keys -t "${SESSION_NAME}":0 "exit" C-m
    else
        echo -e "\e[31mサーバ[${SERVER_EXEC}]は停止しています\e[m"
        return 1
    fi

    while :
    do
        if pgrep -u "${USER_NAME}" -f "${SERVER_EXEC}" >/dev/null; then
            echo -e "\e[33mサーバ[${SERVER_EXEC}]停止待機中\e[m"
            sleep 10
        else
            if ! tmux has-session -t "${SESSION_NAME}" 2>/dev/null; then
                echo -e "\e[32mサーバ[${SESSION_NAME}]を停止しました\e[m"
                return 0
            else
                echo -e "\e[31mサーバ[${SESSION_NAME}]の停止に失敗しました\e[m"
                return 1
            fi
        fi
    done
}

# 絶対パス
SHELL_HOME="$(cd $(dirname $0) && pwd)"

# ユーザ名
USER_NAME="valheim"
# tmux セッション名
SESSION_NAME="valheim"
# サーバのディレクトリ
SERVER_DIR="${SHELL_HOME}/bin"
# サーバの実行ファイル
SERVER_EXEC="valheim_server.x86_64"
# サーバの引数
SERVER_ARGS="-name \"{{サーバ名}}\" -port 2456 -world \"{{ワールド名}}\" -password \"{{パスワード}}\" -savedir \"${SHELL_HOME}\" -public 0 -saveinterval 7200 -backupshort 7200 -backuplong 21600 -nographics -batchmode"
# ログファイル
LOG_FILE="${SHELL_HOME}/valheim_server.log"

# 元のスクリプト引数
export templdpath=$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="${SERVER_DIR}"/linux64:$LD_LIBRARY_PATH
export SteamAppId=892970

# ユーザ取得
USER_ID=($(whoami))
if [ -z "${USER_ID}" -o "${USER_ID}" != "${USER_NAME}" ]; then
    echo -e "\e[33mユーザ ${USER_NAME} で実行してください\e[m"
    exit 1
fi

# ログファイル初期化
: >"${LOG_FILE}"

# オプション
case "${1}" in
    start)
        start
        RETURN_MAIN=$?
        ;;
    stop)
        stop
        RETURN_MAIN=$?
        ;;
    restart)
        stop
        RETURN_MAIN=$?
        if [ ${RETURN_MAIN} -eq 0 ]; then
            start
            RETURN_MAIN=$?
        fi
        ;;
    *)
        echo -e "\e[33mオプションは [start / stop / restart] のいずれかを指定してください\e[m"
        exit 1
        ;;
esac

# 元のスクリプト引数
export LD_LIBRARY_PATH=$templdpath

exit ${RETURN_MAIN}

編集が必要な部分について
{{サーバ名}}{{ワールド名}}{{パスワード}} は,それぞれ Valheim サーバの設定値を指定してください.

シャットダウン前の通知について
stop() 内に Say SERVER SHUTTING DOWN IN ** SECONDS!! を送信するコマンドを記載していますが,現時点で Valheim Dedicated Server にはゲームサーバからゲーム内にメッセージを送信する機能はありません.
参加しているユーザからは突然サーバから切断される形になります.

Valheim はキャラクターデータをクライアント側に保管しているので,特別問題にはならないはずです.

作成した valheim_server.sh に実行権限を付与します.

$ sudo -iu valheim
valheim$ chmod 744 /opt/valheim/valheim_server.sh
valheim$ chmod 744 /opt/valheim/*.txt

ログファイルを初期作成し,実行権限を付与します.

valheim$ touch /opt/valheim/valheim_server.log
valheim$ chmod 744 /opt/valheim/valheim_server.log

サーバの起動に必要な tmuxvalheim ユーザにもインストールします.

valheim$ sudo apt install -y tmux

起動スクリプトを実行

start オプションを指定して,サーバを起動します.

valheim$ /opt/valheim/valheim_server.sh start

tmux セッションに接続し,サーバが起動していることを確認します.

valheim$ tmux a -t valheim
︙
Game server connected

接続確認
Game server connected が表示されたら,クライアントから接続確認を行います.

停止スクリプトを実行

stop オプションを指定して,サーバを停止します.

valheim$ /opt/valheim/valheim_server.sh stop

tmux セッションが停止していることを確認します.

valheim$ tmux ls
no server running on /tmp/tmux-1001/default

tmuxinator 設定

tmuxinatorservers を編集し,valheim セッションを追加します.

valheim$ exit
$ tmuxinator edit servers
#︙
windows:
  # ︙
  - valheim:
      layout: 8c65,205x39,0,0{102x39,0,0,0,102x39,103,0[102x19,103,0,1,102x19,103,20,2]}
      panes:
        - Valheim:
            - sudo -iu valheim
          #  - tmux a -t valheim
        - Console:
            - sudo -iu valheim
          #  - /opt/valheim/valheim_server.sh start
        - PortMonitor:
            - sudo iftop -i enp7s0 -PnNf 'port 2456'

tmuxinatorservers を起動します.

$ servers

valheim セッションが追加されていることを確認します.


おわりに

以上で,サーバマシンの構築,ゲームサーバの構築と公開が完了しました.
他のゲームサーバの構築も基本的には同様の手順で行うことができるはずです.

Java が必要なゲームや専用の管理コンソールがあるゲームなど,都度適宜対応が必要ですが,基本的な流れは同じです.

繰り返しになりますが,筆者自身サーバ構築やセキュリティに関しては素人なので,誤りや不適切な記述があるかもしれません.
その際はご指摘いただけると幸いです.

以上,ありがとうございました!

コメント