[UE4] DedicatedServer を Windows と Linux で構築する

Linux で DedicatedServer 建てたいよォ！
ということで、いろいろ試したことをメモしておきます

# この記事は
+ UE4.25 で確認します
+ AWS EC2 を利用します
+ C++ビルド環境が必要です

# Windows環境で動作を確認する
まずはエディタ上で動作することを確認しましょう
![3aa51d51363dc4d28f0666adec0ef373.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/e817382f-bcd2-4d83-ba2e-5834b963f51f.png)
[選択ビューポート] x [スタンドアローンゲーム] x [Play Offline] x [Play As Client] x [プレイヤー数]
これらの組み合わせをそれぞれ動作確認するので、結構タイヘン。。

## エディタ外部からの起動
PIEで起動すれば全てのサーバー、クライアントのプロセスをトレースできます
これはこれで便利ですが、CLI1, CLI2, SERV と複数回コールされる関数（BeginPlay等）を追っていくと頭が非常に疲れるので（！）
プロセスを個別に起動する方法について記述します

### Server起動バッチ
```RunServer.bat
:: [UE4DIR], [ProjectName] は自身の環境で置き換えてください
set EDITOR=[UE4DIR]\Engine\Binaries\Win64\UE4Editor.exe
set GAME_UPROJECT=%~dp0%\[ProjectName].uproject

:: 起動マップをオプションで指定する
:: デフォルトはプロジェクト設定の [Server Default Map] が使われる
set MAP_NAME=

:: エディタからサーバーを起動
start %EDITOR% %GAME_UPROJECT% %MAP_NAME% -server -log
exit
```
### Client起動バッチ
```RunClient.bat
set EDITOR=[UE4DIR]\Engine\Binaries\Win64\UE4Editor.exe
set GAME_UPROJECT=%~dp0%\[ProjectName].uproject

start %EDITOR% %GAME_UPROJECT% -game -log -windowed -ResX=1024 -ResY=576
exit
```

# ビルド&クックの実行
次はバイナリ作成について記述します

## サーバーのビルドターゲットを追加
テンプレートにはターゲットファイルが存在しないので追加します

```[ProjectDir]/Source/[ProjectName]Server.Target.cs
using UnrealBuildTool;
using System.Collections.Generic;

public class [ProjectName]ServerTarget : TargetRules
{
	public [ProjectName]ServerTarget(TargetInfo Target) : base(Target)
	{
		Type = TargetType.Server;
		DefaultBuildSettings = BuildSettingsVersion.V2;
		ExtraModuleNames.Add("[ProjectModuleName]");
	}
}
```
同じディレクトリにある [ProjectName].Target.cs を参考に追加してください
![f68f1206877201067ff5f8a5447ff97d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/7bd5692c-2385-8ef0-9bd6-0413e1a00d54.png)
ファイル追加後、uprojectメニューからVSファイルを更新します
![fe585b7fa7855b8e8fd1051443f87961.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/0e4267e6-55ae-f047-dc6c-0b4c15b052bf.png)
ターゲットが増えていることを確認してください（画像はVSCode）

## コマンドラインからクック
ググると ProjectLauncher でのチュートリアルが多いですが、
エディタを起動せずに済むのでバッチファイルから実行することをおススメします

```BuildServer.bat
set ENGINE_ROOT=[UE4DIR]\Engine
set GAME_UPROJECT=%~dp0%\[ProjectName].uproject

:: 1行が長くなる場合は^で改行する
:: startを入れると終了時にウィンドウが残る
start %ENGINE_ROOT%\Build\BatchFiles\RunUAT ^
	BuildCookRun -project=%GAME_UPROJECT% ^
	-nop4 -build -cook -compressed -stage ^
	-noclient -server -serverplatform=Win64 -serverconfig=Development ^
	-pak -utf8output
```
![81ebb694a18fef878a21e358c28aa9b5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/bac6f082-a153-e991-3b0b-382ad7391834.png)
BUILD SUCCESSFUL と表示されたら完了です
[ProjectDir]\Saved\StagedBuilds\WindowsServer 以下にパッケージが生成されます
![8809a9e877f3aba2b910de72065c3448.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/c672c854-8487-6932-95f6-a5701a44af4e.png)
フォルダをエクスプローラーで開き、cmdと入力するとその場でコマンドプロンプトが開きます（知らなかった）
![23068bc0dedb39a92461bce3bbeafccb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/c7b8d459-a41b-252d-33de-4faccb13c1d1.png)
-log 引数をつけて exe を実行し、サーバーを起動してください
![3c40660160da2ba816bbf74857911da6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/a559b69d-23e3-2d55-41eb-f348b1b8dfaf.png)
PIE を起動してから @キー を押し、[open 127.0.0.1] とコマンドを入力するとサーバーに接続できます

# Linux 環境を構築する
[Linux のクロスコンパイル](https://docs.unrealengine.com/ja/Platforms/Linux/GettingStarted/index.html) をまず読みましょう
読みましたね？どうすればいいんだ・・・
そもそも Linux 環境でビルドすればよくないですか？そう思ったあなた！！！
![679e03840b5a525aee093506fb20d543.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/57cb87a1-8b46-496d-9696-dd4cb97c6c99.png)
P4環境を作ろうとして、UE4DIRをサブミット&更新かけたらこんな感じになったので怖くてやめました
Setup叩くと120GBくらいあるので・・・そもそもボリューム足りないが・・・
[Building Unreal Engine Game Client and Dedicated Server on Linux](https://gist.github.com/zhiguangwang/42b0584ae689f0f8711790e4c05d76f1)
やってる人とかいるけどね、どういう運用してるんだろうね

というわけで Windows でビルド -> 実行ファイルだけ転送 のフローにします

## ツールチェインのインストール
![aacfa4ee36e3060455da770db2f9b489.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/9c494fc3-1eab-658c-7650-3163aa2eb72b.png)
[リンク](https://docs.unrealengine.com/ja/Platforms/Linux/GettingStarted/index.html)をクリックしてもインストールが始まりません、が
右クリック -> 新しいウィンドウを開く でインストールできました
再び [Generate Visual Studio project files] を実行すると、Linux がターゲットに追加されるはずです
（この辺は詳細の自信がない・・・）

## Linuxサーバーのクック
先ほどの BuildServer.bat 内の -serverplatform を Linux に変更してビルド&クックします
\Saved\StagedBuilds\LinuxServer にパッケージされれば成功です

## AWS サーバーを構築する
あまり本題ではないので要点だけ

+ t3.microを起動します（t2より安くて次世代機、しかし無料枠ではない）
+ t3.nanoでは<font color="orange">メモリが足りないのでサーバーが起動できません</font>（後述）

+ デフォルトのボリューム8GiBだと足りなかったので16GiBに増量（減量についてはめんどくさすぎるので慎重に！）
参考：[EC2のボリューム(EBS)容量拡張方法検証 (AmazonLinux)](https://qiita.com/hoshino/items/98aa8efd35cd6e8969bc)
+ 使うときだけ起動したいので、ElasticIPで固定しとくと楽です
+ UE4の通信はUDP:7777を使うので、開けておきましょう
![f541c125770cbe186f4dd3c228904e81.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/f7b22620-fcd3-3ef5-348e-7945e5bb9121.png)

+ [WinSCP](https://winscp.net/eng/docs/lang:jp) で転送しました
\Saved\StagedBuilds\LinuxServer\\[ProjectName]\Binaries\Linux\\[ProjectName]Server.debug は容量が大きいので、用途に合わせて転送するか決めてください
gdb でスタックトレースとかを追うので開発の場合は必要かも

## サーバーの起動
```
$ ./[ProjectName]Server.sh -log
```
ひとまずコマンドを実行してみる、が

```
./[ProjectName]Server.sh: line 5:  2950 Segmentation fault
"$UE4_PROJECT_ROOT/[ProjectName]/Binaries/Linux/[ProjectName]Server" [ProjectName] "$@"
```
ｗ

### gdb デバッガ起動
```
$ gdb [ProjectName]Server
GNU gdb (GDB) Red Hat Enterprise Linux 8.0.1-30.amzn2.0.3
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from [ProjectName]Server...Reading symbols from /var/www/[ProjectName]/Binaries/Linux/[ProjectName]Server.debug...done.
done.
(gdb) run -log
Starting program: /var/www/[ProjectName]/Binaries/Linux/[ProjectName]Server -log
fork: Cannot allocate memory.
(gdb)
```
Cannnnnnnnnot allocate memory!!!
ということで、t3nano から t3micro に変更して無事起動できました
[open ###.###.###.###（GlobalIP）] で接続できることを確認

### nohup でバックグランド起動
```
// nohup で起動するため実行権限を付与
$ chmod +x SlothServer.sh
// 標準/エラー出力は適宜変更する
// MapName はオプションです（指定しなかった場合は[Server Default Map]）
$ nohup ./SlothServer.sh [MapName] > nohup.out 2> nohup.err &
```

### nohup 起動プロセスをキル
```
$ pkill SlothServer
```

## 参考リンク
[How To Set Up Dedicated Servers for Windows and Linux For Your UE4 Game (using Windows)](https://allarsblog.com/2015/11/06/support-dedicated-servers/)
[Legacy/Dedicated Server Guide (Windows & Linux)](https://www.ue4community.wiki/legacy/dedicated-server-guide-%28windows-and-linux%29-yoapx62d)