Python」カテゴリーアーカイブ

factorioをconohaで動かしてみた

conoha(www.conoha.jp)というVPSサービスが安くて良さそうなので使ってみた。

これまで、AWSでEC2のt2.microを利用してfactorio headlessを立ち上げていたが、突然ゲーム内のスピードが落ちてカクカクになったのに、topコマンドの結果を見るとCPU使用率は低いまま。原因を調べた結果、tシリーズはCPU creditというものが設定されていて、それを使い切ってしまうと、CPUの能力を十全に活用できずキャップがかかる仕様と判明。そもそも、本来、t2.microはCPUをあまり利用しないサービスが前提となっているものの、起動など一時的にCPUを使用するシーンのみ、お情けとして規定された性能分だけCPU性能をオマケしてもらっている、という仕様らしい。CPUをガンガン常用するようなゲームサーバには適していないことが判明。

じゃあ、適したAWSのインスタンスタイプがどれかなと調べているとき、factorioがプリインストールされているVPSを格安で貸し出してくれる本サービスを発見し利用に至る。注意点は、サーバ停止時も利用料がかかってしまうこと。どうせ停止中でもお金がかかるなら起動しっぱなし(factorio headlessは誰もプレイしていないときはゲーム内時間がSTOPする仕様)とするか、毎回、セーブデータをローカルなどにバックアップしてサーバ自体を削除/新規するかの2択となる。

ちなみに、FAQには詐欺(?)のような書き方で「停止していても料金はかかる」と書いてある。

停止時の料金はありますか?(ConoHa VPS・ConoHa for Windows Server・ConoHa for GAME)
ConoHa VPS・ConoHa for Windows Server・ConoHa for GAMEについて、停止(シャットダウン)いただいた場合でも料金が変動することはございません。サーバーの稼動、停止の状態にかかわらず、ご契約数で料金が発生いたします。

https://support.conoha.jp/common/faq/payment-q/

セキュリティグループはプリセットから下記を適用する。Webコンソールは使いにくいし、セーブデータのアップロードやダウンロードができないので、SSH portを開放してやり、Teratermなど手に馴染んだクライアントソフトから接続するのが吉。

  1. IPv4v6-SSH
  2. IPv4v6-Factorio

セーブデータは下記に格納されている。コマンドからマップのカスタマイズをするのは面倒なので、ローカルのfactorioで作成したセーブデータを同名でアップロードしてやるのが吉。

  • アップロード先:/opt/factorio/savedata/factorio_save.zip
  • アップロード元(Windows Steam版):%appdata%\Factorio\saves

conohaのすごいところは、factorioがプリインストールされているだけではなく、serviceまで作り込まれているところ。enableになっているので、サーバを起動した時点でfactorioが起動している。おなじみのsystemctlからサービスを起動/停止しよう。なお、ポートはデフォルト(34197)となっている。先程設定したセキュリティグループ(IPv4v6-Factorio)も34197が許可されている。

  1. systemctl status factorio.service
  2. systemctl stop factorio.service
  3. systemctl start factorio.service

statusを確認してみた。

# systemctl status factorio.service
● factorio.service - Factorio Server
     Loaded: loaded (/etc/systemd/system/factorio.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-10-10 09:30:36 JST; 2h 8min ago
   Main PID: 138266 (sh)
      Tasks: 12 (limit: 1065)
     Memory: 651.7M
     CGroup: /system.slice/factorio.service
             tq138266 /bin/sh -c /usr/bin/screen -DmS factorio /opt/factorio/factorio/bin/x64/factorio --start-server /opt/factorio/save>
             tq138267 /usr/bin/SCREEN -DmS factorio /opt/factorio/factorio/bin/x64/factorio --start-server /opt/factorio/savedata/factor>
             mq138276 /opt/factorio/factorio/bin/x64/factorio --start-server /opt/factorio/savedata/factorio_save --console-log /opt/fac>

Oct 10 09:30:36 vm-1c3075e2-0b systemd[1]: Started Factorio Server.

config.iniはデフォルトなので、必要に応じて修正する。デフォルトだと、10分間隔にオートセーブでフリーズがかかってうざいので、autosave-intervalは長めにしておくことを推奨。この方法だと、何故か設定が適用されない不具合が発生。解消方法は後述。

# pwd
/opt/factorio/factorio/config

# diff config.ini.default config.ini
21c21
< ; autosave-interval=5
---
> autosave-interval=20
23c23
< ; autosave-slots=3
---
> autosave-slots=5

上記の方法だと何故か設定が反映されない。別の方法を模索した結果、下記のjsonで設定してやるとうまくいくことが判明。exampleをコピーして設定ファイルを新規作成。仲間内でのゲームなので、public/lanをいずれもfalseにして、autosave_intervalを60分に変更。その後、この設定ファイルを読み込むよう、起動オプションに追加してやる。

  • /opt/factorio/factorio/data/server-settings.example.json
  • /opt/factorio/factorio/data/server-settings.json
# diff server-settings.example.json server-settings.json
13,14c13,14
<     "public": true,
<     "lan": true
---
>     "public": false,
>     "lan": false
48c48
<   "autosave_interval": 10,
---
>   "autosave_interval": 60,

serviceファイルの起動オプションに「–server-settings /opt/factorio/factorio/data/server-settings.json’」を付与する。systemctl daemon-reloadでserviceの再読み込みを忘れずに。

# cat /etc/systemd/system/factorio.service
[Unit]
Description=Factorio Server
After=network.target nss-lookup.target

[Service]
Type=simple
User=factorio
Group=factorio
WorkingDirectory=/opt/factorio
ExecStart=/bin/sh -c '/usr/bin/screen -DmS factorio /opt/factorio/factorio/bin/x64/factorio --start-server /opt/factorio/savedata/factorio_save --server-settings /opt/factorio/factorio/data/server-settings.json'
ExecStop=/usr/bin/screen -p 0 -S factorio -X eval 'stuff "/server-save\015"'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S factorio -X eval 'stuff ^C'
ExecStop=/bin/sleep 5
Restart=always

[Install]
WantedBy=multi-user.target

# systemctl daemon-reload