リズムゲームの設計思想【中級】

#はじめに
この記事は[リズムゲームの設計思想【初級】](https://qiita.com/GONBEEE_project/items/8e0ce446efa7bd076c22)の続編です。
リズムゲームの設計思想シリーズ第二弾、今回は譜面データに関するお話です。
前回記事で各ゲームの触り部分を紹介しました。
読んでいなくても理解はできますが、読んだほうがこの記事も分かりやすくなると思います。

前回記事の最後で**「少しでもリズムゲーム制作を簡単にするために」**、と予告しました。
簡単にしようにも、まずリズムゲームでロードされる譜面データの全体像を捉える必要があります。
今回は【初級】の内容を踏まえ、「制作を簡単にする」の前段階として
実際のゲームでどのような情報が譜面データに含まれているかを考えていきましょう。

#譜面とは
リズムゲームに慣れ親しんだ者にとっては「何言っとんじゃい」というような話です。

音楽用語では「楽譜」という意味ですが、
リズムゲームにおいて「譜面」というと、「ノーツが流れてくるタイミングやタイプ・レーン配置」のことを指します。
（初級で定義を説明するべきでした）
以降「譜面」という単語が出てきたら音楽用語の楽譜ではなく、ノーツ情報のことを指しているんだなと認識してください。
基本的にリズムゲームでは1曲1難易度に対して1つの譜面が存在します。（例外もある）
一般的なリズムゲームは大体1曲に対して3難易度+αなので、同じ曲で3回程譜面をデザインしなければなりません。
それを踏まえた上で読み進めてください。

###譜面はごはん
リズムゲームに慣れ親しんでいない人向けの例え話です。
リズムゲームは譜面がなければ成立しません。
前回記事で
>ゲーム本体、それに食わせる譜面データ、譜面を作る専用エディタの3方面に広げないとリズムゲームというのは成立しません。

と記しました。
これらを極めて噛み砕いた説明をすると、
**ゲーム本体＝食器
譜面データ＝ごはん
譜面を作る専用エディタ＝調理器具
（譜面を作る人＝料理人）**
と言い換えることが多分できます。書いてて思いつきました。
どんなに美しい食器でも、盛り付けるごはんが不味ければ不味い食事になりますし、
どんなに料理人の腕が良くて出来上がったごはんが美味しくても、食器が悪ければ見栄えが落ちます。
満足度の高い食事にするためには食器もごはんも大事です。~~お米は大事と、存じます~~
そのくらい譜面データは大事なものだということを理解していただければと思います。

#時間が大前提
譜面データを構築する上でどうあがいても外せないものが**時間**です。
以降**タイミング**と呼称します。
前回記事の冒頭で記した通り、人間の感覚では「音楽のリズムに合わせて反応する」というゲームです。
リズムを示す（＝ノーツを表示する）ためには、
**楽曲の再生時間に対していつをジャストタイミングとするか**のデータが必要不可欠です。
例外はありません。
極論を言ってしまうと**タイミングのデータさえあれば一応遊べるゲームは作れます。**
上記のごはんの例で言うと、食器がなくごはんだけがある状態です。
手と米があればおむすびを握って腹を満たせます。
満足度は低いでしょうが、ごはんを食べるという一点だけで言うと、
食器がなくても食べられるということですね。

では、満足度の高いリズムゲームとするにはどのようなデータが必要になるでしょうか？
前回記事で挙げたゲームからいくつか分かりやすい物をピックアップして、紹介していきます。

**（当然ですが個人の見解です。きっとこうなんだろうな、という想像なのでご了承ください。）**

##beatmania IIDX
現代リズムゲームの親、弐寺です。
![maxresdefault.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/494c00db-3ff6-134a-7399-fc6d5e9f1731.jpeg)
前回記事でも紹介しましたが、念の為もう一度。
これは落下式ゲームで、判定ラインは画面下部の赤いラインです。
入力方法は7ボタン+1皿で、
上からノーツが降ってきて赤いラインに触れた瞬間にボタンを押すか、皿を回します。
まずはこのゲームの譜面にどのような情報が含まれているかを考えてみましょう。


この画像内で見えている情報だけで
**8本のレーン
3色のノーツ**
が見えますね。
ですが、弐寺のノーツ色分けはレーンによって固定です。
赤いノーツは皿、青いノーツは黒鍵ボタン、白いノーツは白鍵ボタンに対応しています。
そのため色分けに関してはゲームシステム側で吸収することができます。
つまり譜面データには
**タイミング情報
どのレーンに流すかのレーン番号**
が含まれていると推測できます。

また、ちょうどいい画像が見当たらなかったので示せませんが、
弐寺には**ホールドノーツ**が存在します。
ボタンに流れてきたときはボタンを長押し、皿に流れてきたら皿を回し続けます。
ホールドノーツは全てが同じ長さホールドするわけではないため、
**ホールドする長さ**
の情報が追加で発生します。
これらの情報を表にまとめてみます。

| 弐寺  |タイミング| レーン番号 |ホールド長さ|
|:--|--:|--:|--:|
| 通常ノーツ      |○|○| |
| ホールドノーツ   |○|○|○|
こうなりました。
（他にも譜面の加速減速などもありますが、今回は割愛します。）
どちらのノーツも**タイミングとレーンは必要**ということがわかります。
これらの情報は【上級】の記事で譜面データを設計する際に必要となります。
今回はまとめるだけで特に進展はありません。
こういう情報が必要なんだなとぼんやり捉えてください。

##太鼓の達人
カジュアルリズムゲームの筆頭です。
![Inkedmaxresdefault (1)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/5b2bf9fb-4389-164d-6dc9-a0489805a5c6.jpeg)

こちらは弐寺とは違い、単一レーンで複数の種類が流れてきます。
太鼓の達人にあるノーツの種類は
**ドン・カッ
大ドン・大カッ
黄色連打
風船連打・くす玉連打**
あたりでしょうか。
最近のバージョンをプレイしていないので他にもあるかもしれません。
コメントか編集リクエストが来ればちゃんと調査してきます。

太鼓の達人はレーンが一本しか無いため、弐寺とは違いレーン番号情報は必要ありません。

| 太達  |タイミング| 色 |連打受付時間|連打数|
|:--|--:|--:|--:|--:|
|通常ノーツ  |○|○| ||
|大ノーツ   |○|○|||
| 黄色連打   |○|△|○||
| 風船・くす玉   |○||○|○|
△：黄色連打・黄色大連打区別あり
このような感じでしょうか？
この時点で**「ん？」と思ったあなたは譜面データ設計の才能があるかもしれません。**
あえて違和感の残る書き方をしています。パッと分からなかったあなたは当記事後半をお楽しみに。

##Jubeat
上2つが落下式なので、拡張式からも一つ紹介します。
![hqdefault.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/1e896454-5ca0-0de0-ff8d-d20f12156ac7.jpeg)ﾋﾟｷﾞｬｰ
こちらは流れるという概念が存在しません。拡張式なので当然ですが。
Jubeatにあるノーツの種類は太鼓の達人よりはシンプルで
**タッチ
ホールド**
の2種類です。
とはいえホールド実装の譜面は比較的少ないですが、、、

| 指  |タイミング| 枠番号 |ホールド長さ|
|:--|--:|--:|--:|
| タッチノーツ      |○|○| |
| ホールドノーツ   |○|○|○|

Jubeatは16パネルなので枠番号が大きくなりがちです。
それ以外は特に問題はなさそうですね。
またしても**「ん？」と思ったあなたは**~~十字押しの才能~~**譜面データ設計の才能がある気がします。**

#時間以外も大事
ここまでの表から、面白いリズムゲームとして成り立つためには時間以外の情報も大事であると分かっていただけたでしょうか。
この記事の山場に入る前にここまで出てきた譜面情報を整理しましょう。

###タイミング - 浮動小数点
前述の通りタイミングは大前提です。
どのゲームにおいてもタイミング情報は組み込まれていました。
タイミングさえあれば遊べるとは書きましたが、それだけでは面白いゲームにはなりにくいでしょう。
（リズム天国などシステム側が超頑張ってタイミングだけを使っているゲームもあるといえばあります。
が、リズ天に関しては1つ1つのゲームがもはや別ゲーなので同系列では語れません。）

タイミング情報は曲の再生時間に対する秒数なので、`float`や`decimal`などの浮動小数点データ型を使うのがいいと考えています。
`float`は微妙に計算誤差が発生するので、株ごんでリズムゲームを作る際は`decimal`を使っています。
この2つの違いはここでは説明しません。`decimal`のほうが計算精度が高いということだけ知っておいてください。

###レーン番号 - 整数
上に挙げた例ではbeatmania IIDXでのみ登場しました。
8レーンある中でどのレーンにノーツを流すかを特定するのに必要な情報です。
こちらは番号であるので、整数として扱うのがいいでしょう。`int`などの整数型が理想ですね。
当然ながら計算誤差は発生しません。
弐寺は8レーンなので、`0~7`を保持できれば問題ありません。`int`はもはや情報過多なので、整数型であればなんでもいいです。

###色 - 整数
**後述します。**

###連打受付時間 - 浮動小数点
これには2種類の意味を持たせることができます。
まずは太鼓の達人の黄色ノーツをどのくらいの長さを流し続けるかのデータです。
これは時間の長さとなるので、タイミング情報と同じく浮動小数点型を使うのが良いでしょう。
こちらも計算精度を重視したいので`decimal`を使いたいところですね。

もう一つは下記の連打数とセットで風船連打・くす玉連打の制限時間を設けるためのデータです。
黄色連打以外は次ノーツの詰まりを防ぐために
一定時間経過するとそのノーツが丸ごとミス扱いになるという仕様があります。
そのための制限時間を組み込むためのデータとして使います。

###連打数 - 整数
太鼓の達人の風船連打とくす玉連打で使う、何度叩けばクリアとするかの情報を保持します。
こちらは回数なのでレーン番号などと同じく整数型で扱います。
最近の太鼓の達人をプレイしていないのでなんとも言えませんが、
多分連打数は多くても100回くらいではないでしょうか。
レーン番号と同じく整数型であればなんでもいいと思います。

###枠番号 - 整数
Jubeatでどの枠にノーツを出すかを特定するのに必要な情報です。
性質としてはbeatmania IIDXのレーン番号に似ています。
ただこちらは16枠あるので`0~15`になります。整数型であればなんでもいいです。

###ホールド長さ - 浮動小数点
これは弐寺とJubeatのホールドノーツに使います。
どのくらいの時間長押しさせるかのデータです。
これは時間の長さとなるので、タイミング情報と同じく浮動小数点型を使うのが良いでしょう。
（全く同じ文章を少し前に見ましたね。）

#本題
各譜面情報をまとめ終わったところで【中級】の山場です。
**「少しでもリズムゲーム制作を簡単にするために」**の具体的なステップを踏みます。
ここまでの情報整理はいわば前座、仕込みでした。
この項目では**前述の譜面データを最適化して、実際に譜面データを設計する際の足がかりとします。**
ゲーム紹介のところでちらほら書いていた違和感をここで全て回収します。

##太鼓の達人の違和感
太鼓の達人紹介時の表をもう一度見てみましょう。

| 太達  |タイミング| 色 |連打受付時間|連打数|
|:--|--:|--:|--:|--:|
|通常ノーツ  |○|○| ||
|大ノーツ   |○|○|||
| 黄色連打   |○|△|○||
| 風船・くす玉   |○||○|○|
この表では**通常ノーツと大ノーツを別のノーツとして表記しています。**
色を保持させるデータとして挙げていますが、
**ドンノーツの大小・カッノーツの大小**と分けても表の形状がほとんど変わらないということに着目してください。

| 太達  |タイミング| サイズ |連打受付時間|連打数|
|:--|--:|--:|--:|--:|
|ドン  |○|○| ||
|カッ   |○|○|||
| 黄色連打   |○|△|○||
| 風船・くす玉   |○||○|○|
この表から**ドンカッ・サイズの区切りは曖昧である**ということが分かると思います。
そのため太鼓の達人で保持する通常ノーツ系の情報は**一つの整数型でサイズと色を同時に表現できます。**
先程のノーツ情報整理で色を後述とした理由はこれです。
ふわっと上級の内容が混ざってしまいますが、
例えば
0=ドン小
1=カッ小
2=ドン大
3=カッ大
とすれば一つの整数型で通常ノーツと大ノーツを**譜面データ上は一つのノーツとして扱えます。**

表をまとめ直す前にもう一つ叩いてしまいましょう。
黄色連打と風船・くす玉連打を少し強引ですが融合させてしまいます。
どの連打ノーツも連打受付時間を持っているというところを糸口として合体させます。
連打ノーツにもタイプという概念を持たせましょう。
0=黄色連打
1=黄色連打大
2=風船連打
3=くす玉連打
とすることで連打系ひとまとめに合体できます。

表にすると

| 太達  |タイミング| タイプ |連打受付時間|連打数|
|:--|--:|--:|--:|--:|
|通常系  |○|○| ||
|連打系   |○|○|○|○|
このように、**4つあったノーツタイプを譜面データ上は2つとして扱うことができました。**
「黄色連打には連打数のデータは必要ないだろ！」という声もあると思いますが、
**データとして含まれているだけで、使わなければなかったものと同じです。**
少し暴論気味ですが、譜面データ設計のコストを考えると
**専用ノーツを分離させて作る**よりも、
**含まれているだけで使わない**ほうがコストが低いのではないでしょうか。
ノーツの種類が増えるとその分だけ譜面データをロードする側の処理が増えます。
譜面デザイナーもノーツの種類が多いとややこしいと感じると思います。
そのため多少強引でも**それぞれに情報を多めに持たせて、ノーツの種類自体を削る**というのが
効率的な譜面設計かと思われます。
詳しくは【上級】で書きますが、
株ごんの譜面エディタRefrainCoreではこの思想に基づいてノーツを設計しています。

##弐寺と指の融合
項目名から既に面白い。

こちらは太鼓の達人より分かりやすく伏線を張りましたが、
![okizuki.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/322212d3-3c47-84fa-4c8f-02777e5cbd09.jpeg)

こちらは譜面情報の圧縮の話ではありません。
**譜面データ共通化の話です。**

弐寺に必要なノーツ情報は
タイミング：浮動小数
レーン：整数
ホールド長さ：浮動小数

指に必要なノーツ情報は
タイミング：浮動小数
枠番号：整数
ホールド長さ：浮動小数

でした。情報の型が完全に一致していますね。
これはそれぞれ再デザインは必要ですが、
**弐寺と指は同じ譜面データを流用できるため、ローダーとエディタは全て使い回せる**ということになります。
【初級】でも記しましたが、リズムゲームは**ゲーム本体、譜面データ、そのエディタ3方面**に広げないと成立しません。
譜面データとエディタを使い回せるというのは非常に強力なアドバンテージになるということが
想像に難くないと思います。
強引に融合させた譜面データを表にすると

| 弐寺・指  |タイミング| レーン・枠 |ホールド長さ|
|:--|--:|--:|--:|
| 通常ノーツ      |○|○| |
| ホールドノーツ   |○|○|○|
こうなりました。
もちろん全く同じ譜面を流用することはできません。
レーン数と枠数が違うので当然です。
しかし、譜面データの設計と専用エディタを作らなくていいというのは明らかなメリットです。
一度譜面データの規格を決めてしまえば、ゲーム本体に注力できます。
言い換えると、**ゲーム本体さえ作ればいいのでリズムゲーム量産が可能になります。**

これは**完全に推測**ですが、弐寺も指も大本はコナミなので、
コナミ社内で共通化されている譜面データと譜面エディタがあるんじゃないかなと思っています。

##休憩エリア
雑談ですが、Jubeatでの休憩エリアって次ノーツ来るタイミングが完全に覚えゲーで難しくなりますよね。
落下式なら比較的前から次ノーツが見えているので準備できますが、
拡張式は遠くから飛んでくるわけではないので、休憩譜面と相性が悪い気がします。

「次ノーツが見える」といえば、説明がややこしいので今回は説明しませんでしたが、
リズムゲームの高難易度譜面になると**ソフラン**という仕掛けがあります。
詳しくは[ニコニコ大百科 - ソフラン](https://dic.nicovideo.jp/a/%E3%82%BD%E3%83%95%E3%83%A9%E3%83%B3%28%E9%9F%B3%E6%A5%BD%E3%82%B2%E3%83%BC%E3%83%A0%29)を参照してください。
ソフランに対応するためには譜面データ側で譜面再生速度を変更するタイミングの情報を組み込まなければなりません。
しかしこのシリーズはリズムゲームの大筋紹介なので、ソフランは扱いません。
~~ソフラン入り譜面は大体クソ譜面~~

「どんな仕掛けか気になる！」という人は
Youtubeで[ 太鼓の達人 ドンカマ2000 ](https://youtu.be/_v0byXDgMXw)を見てみるといいと思います。~~何ッ！？~~
これは極端な例ですが、作曲の時点でソフラン譜面を意識している物すら[登場する始末](https://dic.nicovideo.jp/a/%E6%B7%B7%E4%B9%B1%E5%B0%91%E5%A5%B3%E2%99%A5%E3%81%9D%E3%81%B5%E3%82%89%E3%82%93%E3%81%A1%E3%82%83%E3%82%93%21%21)。
~~どんどん譜面難易度上がってるのに、それに対応できるプレイヤー側もヤバいと思う。~~

今後既存リズムゲームプレイヤーに楽しんでもらえるゲームにするためには
ソフランの存在は無視できないものとなるでしょう。
当然譜面デザインのコストは増えます。~~勘弁してくれ~~

##悪魔合体
休憩したところで最後の山場に突入します。
先程beatmania IIDXの譜面とJubeatの譜面を強引に合体させました。
弐寺・指は特に違和感なく融合できました。
共通化された譜面データとエディタがあると量産が楽になるので、
様々なリズムゲームに対応できる、**ジョーカー譜面**があると理想ですよね。
~~UNOで言うとワイルド譜面~~

さて、
項目名の**悪魔合体**から予想していらっしゃる方もいると思います。
ここで**太鼓の達人譜面と弐寺・指譜面を合体させます。**

もう一度それぞれの表を見比べてみましょう。

| 弐寺・指  |タイミング| レーン・枠 |ホールド長さ|
|:--|--:|--:|--:|
| 通常ノーツ      |○|○| |
| ホールドノーツ   |○|○|○|

| 太達  |タイミング| タイプ |連打受付時間|連打数|
|:--|--:|--:|--:|--:|
|通常系　　　　  |○|　　　○| ||
|連打系   |○|○|○|○|

よくよく見比べると「あれ？行けそう？」という感じがしてきますね。

タイミングはどちらも**曲の再生時間に対する秒数**で**浮動小数**でした。
レーン・枠とタイプは思想こそ違いますが**整数型で区別している**ことに変わりはありません。
ホールド長さ・連打受付時間も**浮動小数で保持する時間の長さである**ことに変わりはありません。

連打数だけは似たものが弐寺・指にはありませんが、
太鼓の達人のまとめ項にてこのように書きました。
>多少強引でもそれぞれに情報を多めに持たせて、ノーツの種類自体を削るというのが
効率的な譜面設計かと思われます。

実際に黄色連打に連打数は必要ありませんが、持っているだけで使わないという対応を取りました。
この考え方を流用して、
**弐寺・指のホールドノーツ系が連打数の情報を持っていても、使わなければ同じである**としましょう。

これらを踏まえて**弐寺・指・太鼓全対応のジョーカー譜面**を考えてみましょう。
タイミングはそのままタイミングと名付けます。
レーン・枠・タイプは名称がバラバラなので、強引ですが**座標**という名前で統一しましょう。
（【上級】で座標という名前で使うので強引に合わせました。）
ホールド長さ・連打受付時間は両方とも長さであるので、**ホールド長さ**を継承します。
連打数はカウントとしましょう。（同じく【上級】で使います。）

| ジョーカー譜面  |タイミング| 座標 |ホールド長さ|カウント|
|:--|--:|--:|--:|--:|
|通常系　 |○|　　○| ||
|長押し系   |○|○|○|○|

これで3つのゲームに対応できる譜面データが完成しました。

本来リズムゲームを作る場合、
それぞれゲーム本体、譜面データ、そのエディタの3つのコンポーネントが必要でした。
今回は3つのリズムゲームを挙げたので、
3*3で合計9つのコンポーネントがないと成立しないはずです。
しかし強引に譜面を合体させたことによって
**3つのゲーム本体、1つの譜面データ、1つのエディタ**で
**合計5つのコンポーネント**を揃えれば事足りることになります。
そのコストは約半分です。
**一度共通規格を作ってしまえば以降のリズムゲーム量産が低コストで出来るようになります。**
作れば作るほど元が取れるということですね。
もちろんその分譜面データとエディタを頑張って設計しないといけませんが、、、

##要するに
ここまでの話を整理すると
**譜面データは常に多めに情報を保持しておいて、
その情報の取捨選択は各リズムゲーム側で行う**という態勢を取ることで、
リズムゲームを量産する際のコストを大きく抑えることができます。

ただ、あまりに多い情報を使わずに切り捨てる場合は別のノーツタイプを作るほうがいいと思います。
バランスが難しいところです。
上記例での長押し系でカウントを切り捨てる程度であれば問題ないですが、
「通常系も長押し系に含まれる情報で表現できるやん！くっつけたろ！」というのはおすすめしません。
詳しくは【上級】で書きますが、これは**クラス継承**をうまく使うことで解決します。

譜面データとエディタをちょうどいいバランスで共通化できれば
様々なゲームに使い回すことができます。

これは経験談（宣伝）ですが、
弊社製品RefrainCoreは既に4ゲームに投入されており、
上記計算で行くと6コンポーネント分のコストを節約できたことになります。
（ほぼ毎回微カスタムをしているので怪しいですが、譜面エディタはほとんど変更なしです。）
毎回別々の譜面データと譜面エディタを使う場合はそれぞれのツールに慣れるまで時間がかかりますが、
それらを全て共通化できた場合**慣れたツールを使い回せる**という制作する人間側のメリットも存在します。
地味ですが実によく効きます。

#次回予告
最後の最後で自社製品の宣伝を挟んだところで今回の記事は終了です。
【初級】の内容を踏まえて「少しでもリズムゲーム制作を簡単にするために」をテーマに、

できたかは怪しいですが、リズムゲームに対するさらなる理解を深められたかと思います。
リズムゲームを単体で作るのは正直難しいです。
が、量産体制を整えられたら勝ちです。

次回は【上級】になります。
ここまでの設計思想や概要説明からは大きく離れて、
実際に譜面データをC#で設計してみます。
とはいえ読みやすく簡単に書くつもりではあるので、
エンジニアでもそうでない方も読んでいただければ幸いです。

次回「ぼくのかんがえたさいきょうのジョーカー譜面」
お楽しみに！

##あとがき
【初級】よりは踏み込んだ内容で、かつそこまで難しくなく
という正に【中級】レベルの記事を書けたかと思います。
弊社株ごんが作っているリズムゲームツールキットはこれらの思想に基づいています。
リズムゲーム制作でUnityエンジン案件があれば株ごんまで。（でも今期余裕ない・・・）

何か追記してほしい情報や質問があれば、
Qiitaのコメント欄か [@GONBEEE_project](https://twitter.com/GONBEEE_project) までリプDMでご連絡ください。