steamゲームのmodから学ぶ設計

この記事は [ウェブクルー Advent Calendar 2019](https://qiita.com/advent-calendar/2019/webcrew)の9日目の記事です。
昨日は@end-wcさんの「[Re:ゼロから始めるCSS設計](https://qiita.com/end-wc/items/9d1926cecf236d8f1027)」でした。
9日目は @wchikarusato が担当いたします。宜しくお願いします。

----
## はじめに
ドーモ、オンプレのサイトを開発してる者です。
最近の休日はmodに対応したsteamのPCゲームでmod作成して遊ぶのが熱いです。
ゲーム開発に関しては全くの素人ですが、何度か触ってく中で見えてきたこのゲームの作りが、楽できそうなコード設計にかなり使えそうに思えました。
そこで本日はゲームのコードから更に楽できそうなコーディングのヒントみたいなのを書きたいと思います。

ちなみにmodというのはmod対応したゲームであれば改修パッチみたいなのをユーザー自らが作れます。文字のフォント調整、気になるバグfix、自作アイテム・キャラ追加、世界そのものを再構築、色々ありますmodの種類。
遊び尽くした人には更に無限に遊べる神要素となりますが、興味ない人でもfix系やUI改善系はむしろ本家で対応しなさいよレベルの物が意外と多いので気になったらワークショップをフルに使いましょう。
ちなみに、steamで公開してるmodを導入する場合は、そのゲームのワークショップから検索してサブスクライブというボタンを押すだけで完了します。

## 上書きするという仕組み
私が最近触ってる某ゲームを例に
分かりやすく人間、エルフ、ドワーフみたいなのが登場するゲームとして例えます。
ゲーム上のキャラクター達は物凄く簡略化するとこんな感じのデータになる様です。

```
種族=人間, 筋力exp=1.0, 運動能力exp=1.0, テクスチャー=data/char/人間.mesh, ・・・
種族=ドワーフ, 筋力exp=1.5, 運動能力exp=0.75, テクスチャー=data/char/ドワーフ.mesh, ・・・
種族=エルフ, 筋力exp=0.75, 運動能力exp=1.5, テクスチャー=data/char/エルフ.mesh, ・・・
```
・expはスキル制あるあるのレベルの上がり易さを表していて、他にも武器レベルや職人スキルなど能力毎に設定されています
・とりあえずドワーフは筋力が伸びやすく、エルフは運動能力が伸びやすく、人間は平均的みたいな種族特性で例えました
・テクスチャーはcgファイルで、パスのかかれたファイルをゲームクライアントがロードする事で画面上でそのキャラが見える様になる様です。パスを変えればエルフだけど見た目ドワーフなエルフちゃんとか出来ます。
・実際はxmlみたいな書き方だったり、公式がMOD作成ツールをexeファイルと一緒に配布しててdbツールみたいに直感で見え易くなってたりと様々です


### 3倍界王拳
ここで分かりやすい例として筋力と運動能力の成長速度3倍になるmodを作る事を考えます。
バランス崩壊も良い所ですが、設定値を少し変えるだけのチート系が実は一番練習に向いています。
詳しいやり方は各steamゲームの攻略wikiを参照頂きたいのですが、ありがたい事に公式が環境を提供してくれてるゲームではmodの新規作成、modデータの保存、steamワークショップへのデプロイなど大抵の事を自動でやってくれます。
ツールによっては新規作成と一緒に本体データをロードする事で、修正したい箇所の検索、修正分の差分確認、編集分の戻し、mod同士のマージまでボタン一つで出来る様になっていたりします。
手動でのmod導入方法ですが、modに対応してるゲームは本体が置かれてるフォルダの中にmodというフォルダが大体あるので、作ったmodファイルと同じ名前のフォルダを切って所定の場所に置けばこれだけで完成します。

ゲームを起動すると、
ゲーム本体のデータがロードされ、更にmodファイルが読み込まれ

```
種族=人間, 筋力exp=3.0, 運動能力exp=3.0, ・・・
種族=ドワーフ, 筋力exp=4.5, 運動能力exp=2.25, ・・・
種族=エルフ, 筋力exp=2.25, 運動能力exp=4.5, ・・・
```

この様なデータでプレイする事が出来る様になります
オリジナルのデータをいきなり上書きする訳ではなく、メモリ上で上書きされるというのがポイントです。
ダメなMODだと思った場合はmodフォルダから作ったmodファイルを削除するだけで綺麗に元通り。
逆に伸びを0.5倍にしてジックリ遊べる様にしたくなった場合は、オリジナルと本modの差分を見ればどこに手を加えれば良いのかが一目瞭然。同じ様なmodを参考にする事で、次にバランス調整に挑戦したい人は楽ができるという工夫が見えます。
ちなみに、あらゆるキャラが成長するスキル制な某ゲームでこれをやると、一見チートそうで敵味方関係なく全部の種族が3倍になるので<b>唯でさえステータス高いボス格が戦ってく中で更に3倍速で成長</b>して楽をする筈が逆に返り討ちにされます。

もっと語りたい所ですが、これ以上書くとエンジニア向けというよりゲーム攻略のノウハウになってしまうので省略します。
興味持たれたら、各steamゲームのwikiを参照してチャレンジください

### 順番が命
上書きでデータをロードする都合上、複数のmodを使う場合は順番が肝となります。以下が注意点です。
・ライブラリの様な前提modは先に読み込ませ、逆に日本語翻訳とか絶対適用したいmodは最後に読み込ませる必要があります。
・稀に他のmodと競合したり、間違って開発者自身が入れてるmodと一緒に配布してしまって前提modが無い言われたりします。最も、自分が競合してるという事は他の人も競合してるのでmodのコメントや攻略サイトを見れば大抵解決します。
・公式のアップデートでデータの持ち方自体が変わると整合性が取れなくなるので頻繁にアップデートが入るゲームではmod側にも調整が必要です。親切なゲームはアップデート時に最初からmod外してくれてたりします。
流石に楽と言っても100個以上のmodを導入したら読み込み順をパズルみたいに組み立てないといけないとか別の問題が出てきます。

## 開発に応用したい
ここまででロジックという単語が出てこなかった通り、そもそもがビジネスロジックを触る必要がない様に出来ていて、思いつく大抵の事がデータ修正で完結します。
普段のコーディングだと条件分岐でネストしそうな所も上手くデータでまとまっているので、修正するも追加するも、他の人が作ったのを導入するも外すも楽ができる様な仕組みになっている様です。
上手く言葉では書けないですが、フレームワークと似ている様で全く異なり、コミュニティで開発する形の一つの答えに思えました。

実際の開発で一から真似ようとすると、テストの為のテストの為のテストみたいな事をやる必要が出てくるので中々難しい所ではありますが、本稿が皆様の楽できる何かしらのヒントとなれば幸いです。

----
明日は、@kalzit さんです。よろしくお願いします。

### 参考リンク
modとは https://store.steampowered.com/about/communitymods/?l=japanese
rubyで始めるプログラミング https://magazine.rubyist.net/articles/0004/0004-FirstProgramming.html