ゲームとデータのお話

こんにちは
株式会社OGIX サーバーエンジニア時々クライアントエンジニアのH.O.です。

みなさん、ゲームはお好きですかね？
私は子供のころ、こんなキャラクターがいてこんなアイテムがあって
パラメーターはこんな感じで…
といった具合に妄想をデータとして紙だったりエクセルに書いてるが好きでした。
そんなデータですが実際の現場ではどんな感じに使われているか気になりません？
今回はゲームの設定に関するデータをどんな感じで管理しているか、
どんな形式で持っているかをちょこっと紹介できればと思っています。

:::note warn
あくまでも一例なので現場ごとに差異があります　あしからず！
:::

# まずはじめに
ゲームで扱うデータはいろいろありますが
ゲームの設定に関するデータのことを**マスターデータ**や**マスタ**と呼んでいます。
例えば

<dl>
  <dt>キャラクターのステータス</dt>
  <dd>最大HP</dd>
  <dd>攻撃力</dd>
  <dd>防御力  etc...</dd>
  <dt>アイテムの設定</dt>
  <dd>アイテム名</dd>
  <dd>種別</dd>
  <dd>効果量  etc...</dd>
  <dd>フレーバーテキスト  etc...</dd>
</dl>

といったものがマスターデータとして扱われます。
これらのデータはコードとは分離して管理されます。

# マスタの作成方法
マスタですが基本はプランナーさん厳密にはレベルデザイナーさんが作成するものになります。
そのためエンジニアの知識がなくても入力が可能な方法として
Excelやスプレッドシートを利用して作成することが多いです。

作成の流れとしてはまず仕様に沿って雛形を作成し、
それに沿ってデータを入力していく形になります。

一例として
![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3565804/c747f3f8-e5f4-ba9d-bc90-e3a571f6bce5.png)
こんなイメージがあった場合、まずゲームの設定となりうるものを洗い出していきます。
今回の場合は

<dl>
  <dd>名前</dd>
  <dd>最大HP</dd>
  <dd>攻撃力</dd>
  <dd>防御力</dd>
</dl>

を設定できるものとします。
（あとキャラクター画像もマスタの範囲内ですが今回はスルーで…！）
その場合は
![sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3565804/f83b34e8-1697-135d-7727-cdabcb0822bd.png)
こんな感じにエクセルで記載しています。

# マスタのデータフォーマット
つくったExcelデータはバイナリデータのためゲーム上ではそのまま扱うことはなく、
一度プログラムで読みやすい形にするためテキストファイルに変換してあげる必要があります。
主に用いられるデータ形式を先ほどのExcelデータを変換したイメージとともに3種類ほど紹介します。

### CSV/TSV

``` csv:csv例
id,name,maxhp,atk,def
1,キャラ１,100,20,10
2,キャラ２,80,25,5
```
カンマ( , )もしくはタブ文字(\t)でデータ区切りをする形式です。
CSVはエクセルの保存形式として、
スプレッドシートからテキストエディタに張り付けた場合、
TSVとして貼り付けが行われるので
非エンジニアでもエンジニアの助けなしに簡単に出力できる形式です。
項目の増減の時にずれることでデータが崩壊するという点に注意が必要なことと、
量が増えると見ずらくなる傾向があるので長期運用を想定した場合はお勧めしません。

### JSON
``` json:json例
[
  {
    "id": 1,
    "name": "キャラ１",
    "maxhp": 100,
    "atk": 20,
    "def": 10
  },
  {
    "id": 2,
    "name": "キャラ２",
    "maxhp": 80
    "atk": 25,
    "def": 5
  }
]
```
項目と値がセットになっているのが特徴です。
やろうと思えば連想配列などを利用して入れ子型にすることもできます。
（がExcelで表現することが難しいのでやることはないかと）
一つ一つの要素が厳密に書かれているため、項目の増減に対して耐性があります。
UnityではJSONUtilityが用意されているため、Unityとの相性がよく利便性が高いです。
見やすさにおいては人力できれいに整えてあげる必要があります。

### YAML
```yaml:YAML例
- id: 1
  name: キャラ１
  maxhp: 100
  atk: 20
  def: 10
- id: 2
  name: キャラ２
  maxhp: 80
  atk: 25
  def: 5
```
こちらも項目と値がセットになっているのが特徴です。
書式から人が見やすくなるように保証されています。
インデントによって階層の表現がされて少し不思議な感じがありますが
個人的には扱いやすいものだと思っています。

:::note info
ポイント
言語によって扱いやすいものが変わるので言語に合わせて選びましょう
:::

# 作ったマスタを扱う

さて、形式に変換したものを実際に使うときは
ファイル読み込みを行い、管理用のクラスに記録させます。

一例としてJSON形式のものをUnityで利用を想定した場合

まず各要素の部分の記録するクラスを用意し
```cs: CharaData.cs
[Serializable]
public class CharaData
{
    public string name;
    public int maxHp;
    public int atk;
    public int def;
}
```

マスタのリストを保管するクラスを用意、
```cs: CharaDataList.cs
public class CharaDataList
{
    static public CharaDataList DataList;
    public List<CharaData> Data;
}

```
そのうえでデータを読み込む形にするとよいです。
```cs: 読み込み例
StreamReader stream = new StreamReader(path);
string data = stream.ReadToEnd();
stream.Close();
CharaDataList.SetData(JsonUtility.FromJson<CharaDataList>(data));
```

実際に扱うときはこのように一度値のコピーを行いゲームを使っていく形になります。
```cs: 利用例
class Chara{
    int hp;
    int maxHp;
    int atk;
    int def;
    public Chara(int id){
        CharaData data = CharaDataList.DataList.Data[id];
        hp = maxhp = data.maxHp;
        atk = data.maxHp;
        def = data.maxHp;
    }
}
```

:::note warn
注意
マスタを直接操作すると、元々のデータを失い初期化ができなくなるため
マスタを直接操作せず定数として扱うようにしましょう
:::

# まとめ
・ゲームにはマスターデータというルールや設定を司るデータがあるよ
・マスターデータはExcelやスプレッドシートで作成/管理されるよ
・プログラムではCSV/TSV,JSON,YAMLなどに変換して読み込むよ

# 一緒に働く仲間を募集しています！

株式会社OGIXでは一緒に働いてくれる仲間を募集しています！
エンタメ制作集団としてゲームのみならず、未来を見据えたエンタメコンテンツの開発を行っています。

事業拡大に伴い、エンジニアさんを大募集しています。
興味のある方は下記リンクから弊社のことをぜひ知っていただき応募してもらえると嬉しいです。
▼会社について
https://www.wantedly.com/companies/company_6473754/about
▼代表インタビュー
https://www.wantedly.com/companies/company_6473754/post_articles/443064
▼東京オフィスの応募はこちら
https://www.wantedly.com/projects/1468324
▼新潟オフィスの応募はこちら
https://www.wantedly.com/projects/1468155