誰も止めないので書けるだけ書く

読みやすくするように頑張ります

BMSの難易度に関する話 またはbeatorajaのHARDはLR2のHARDよりどれほど簡単なのか

皆様、私は年が明けるまでにこの記事を書ききれているでしょうか。Ashrmです。

 

音ゲーサークルの皆さんや、…とにかく文章をまとめる文化のある何らかのトピックの周辺で活動している集団の方々はこの時期「アドベントカレンダー」と呼ばれる企画を実施しているようなので、私もこれにあやかり年末に寄せる記事を書こうと思ったわけです。いや、それにふさわしい話題を見つけたという方が正しいでしょう。そのため、今回はいつにもまして頑張らなければなりません。

 

 

 

なんとも刺激的なタイトルをつけたものです。

 

 

 

 

 

最初に

時代が流れ、BMSプレイヤーとしてbeatorajaを使う人が私の周辺にもぽつぽつと増え始めたように思われます。

私もbeatorajaを使っています。

実質的には2020年からBMSを始め、ほぼゼロからのスタートだったためにbeatorajaで抵抗なく始めたといったところです。

 

LR2とbeatorajaのどちらが良いかというのは、いい話題ではありませんね。

いかに多くのことを検討できるとはいえ、

主観に左右されるところが非常に大きい」、

と言って持論を出すことを回避すべきです。

 

しかし、LR2とbeatorajaの違いは無視できませんよね。公式HD対応、BMSON対応といった違いがありますが、私にとって最も決定的な違いの一つは、HARDゲージの仕様です。

beatorajaで難しい、HARDクリアがギリギリの譜面をHARDクリアしたら、どうしてもこういうゲージ推移になります。

 

 

私はBMS環境を本家に寄せることにさほど興味ありません。

 

 

これ絶対LR2のHARDゲージでは落ちてましたよね?

 

beatorajaではLR2よりも低%でのゲージ減少量の補正が大きいことが知られていて、特にゲージグラフのごく0%付近を折り返した箇所はLR2だったらおそらく0%を割っていたでしょう。

そして、私個人の経験で言えば、最近の新規HARDほぼ全部こんな感じです。ギリギリの譜面をプレイしていることを考えると自然ではあります。

 

HARDゲージの仕様の違いについて、ここで復習しましょう。探せばどこにでも書かれていると思いますし、後で書くようにもう少し詳細な仕様がありますが、基本的に各判定を得たときのゲージ変動(%)は下表のようです。

  PGREAT GREAT GOOD BAD POOR 空POOR
beatoraja 0.15 0.12 0.03 -5 -10 -5
LR2 0.1 0.1 0.05 -6 -10 -2

典型的な発狂BMSではGOODはGREAT以上に比べるととても少ないので、基本的にゲージ回復はbeatorajaのほうがやさしいようです。

そして、ゲージ減少量については、ここでは空POORの減少量の増加が目立ちます。実際、上に挙げたリザルトの場合で低%補正を考えずにゲージ減少量の合計を計算すると、beatoraja 395 %、LR2 344 %で、空POORによる減少量が大きく影響していることがわかります*1

しかし、そのゲージ減少は低%補正により弱体化します。その補正は下表のように50%以下から段階的にかかり始め、減少量に以下のように倍率がかかります。

残% 50 40 30 20 10
beatoraja 0.8 0.7 0.6 0.5 0.4
LR2 1 1 0.6 0.6 0.6

これらのことを考えると、まず間違いなくbeatorajaのHARDはLR2のHARDより簡単です。

 

 

私自身はbeatorajaを使っていくにあたり、この違いを受け入れるほかないと思っていますが、Twitterなど覗くと「不正」とか「甘え」とか言っている人もいます。たぶん冗談ですが。

 

 

beatorajaの開発陣はLR2のゲージを初心者には難しすぎるとして、意図的に差をつけているようです。

 

 

あ、これ、書き忘れてたんですが、この記事はBMSというより発狂BMSの話題です。

 

私たち発狂BMSプレイヤーは客観的に見て間違いなく初心者とは言えないわけで、実際、beatorajaは発狂BMSプレイヤーよりも音ゲー新規参入者に配慮したという意図があるようです。難易度調整以外にも、GOODの回復量とGREAT以上の回復量に大きな差がつけられていたり、空POORのゲージ減少量が大きく増加しているのは初心者への教育の意味合いがあるのかもしれませんね。

 

 

これは発狂BMSの立場からも大変に理解可能です。曲や、譜面や、BGAの作者がいてこそ、曲が作られ続け、それに対する発狂差分譜面が生まれ続け、発狂BMSに有益な変化をもたらすといえます。

 

 

とにかく「beatorajaのHARDゲージは不正」というのは絶対に間違いです。確かにbeatorajaのHARDゲージのほうが簡単ですが、それ自体はbeatorajaのマイナスポイントではありません。というか、ほとんどのbeatorajaを使用している発狂BMSプレイヤーは気にしていないと思います。

 

ただ、beatorajaのHARDとLR2のHARDでどれくらい難易度差があるか調べられるとしたら、ちょっと興味がわくのではないでしょうか。

 

そこで今回は、この問いにある程度こたえるために、おおざっぱに難易度差を見積もってみようという記事です。習ったばかりのpythonを使います。

 

 

 

 

 

調査の方法

まず、この記事で私がやろうとしていることは(たぶん)既出です。

 

 

このツイートをした人に接触もなにもしていないので真相はよくわかりませんが、その後この指標に関する発信が見当たらないことを見るに、この「NPS」はおそらく冗談か、非常にタチの悪いリテラシーテストのようなものです。よく考えてください。NPSはおそらく「Notes Per Second」、つまりただの譜面密度です。

愚かにも、私はこれに気づくのに1週間かかりました。

 

さて、基本的なアイデアはこうです。

 

①譜面密度を、時刻 t の関数 d(t) として記述する。

 

②その譜面を、各種ゲージでクリアするのに必要な「処理力」n (以下、要求処理力)を計算する。

ここで、n はプレイヤーの能力を示す値であり、「処理力」が n のプレイヤーはその譜面の時刻 t において毎秒  \mathrm{max}(0, d(t)-n) 個のPOORを出し、それ以外はすべてGREAT以上を出すものとする*2。この記事は主にHARDの難易度差に焦点を当てていますが、一応EASYとNORMALについても計算します。

 

見てわかる通り、各譜面の特性を大幅に無視した*3、非常にナイーブなモデルではありますが、「beatorajaのHARDはLR2のHARDよりどれほど簡単なのか」という問いを考えるには十分だと考えます。

 

しかし、①はよく考えると難儀なものです。譜面密度関数の定め方は何通りもあります。譜面全体での時間積分がおよそノーツ数と同じになってさえいれば、密度関数と言えなくもないでしょう。たとえば、曲中全体にわたり 

 \displaystyle d(t)=\frac{ノーツ数}{曲の長さ}

のように定めるのも「密度」ではありますが、クリア難易度をよりよく評価するためには、時間変化する密度関数が欲しいです。

 

時間変化する密度といえばいわゆる「秒間密度」が知られています。これは、曲を1秒ごとの区間に区切り、その区間内のノーツ数をその区間での「密度」とするものですが、密度が1秒ごとにしか変化しないのはなんだか心配です。もう少し柔軟に時間変化する関数が欲しいと思います。

まず、「時間的に柔軟な秒間密度」とでもいうべきものを考えました。これは、各時刻において、その1秒前までのノーツ数を密度とするものです。各ノーツが1秒間にわたり1ノーツとして数えられるので、この時間積分はノーツ数になることが保証されています。

 

「時間的に柔軟な秒間密度」イメージ図

 

 

この方針で計算すると、下のような密度の時間変化が現れます。実際には、1msごとに計算しています。

 

譜面はsl0 Babel [ANOTHER]、以下同じ。横軸の単位はミリ秒、縦軸の単位はノーツ/秒。

確かに時間的に柔軟に変化していますが、密度自体は1刻みの整数にしかなりません。1秒前までのノーツ数を数えているのですから当然ですが、この分解能はちょっと不安です。また、密度の急激な変化に応答するのに1秒かかります。これをなんとかしようと、例えば「0.5秒前までのノーツ数を数えてから2倍する」と得られる密度が2の倍数のみと、さらに分解能が悪化します。

これを改善する方法として、その時刻までの時間に応じてノーツ数に重率をかけて加算するという方法が考えられます。要するに下の式の窓関数 w(t) の形を工夫するということです。こうすると確かに密度はどんな実数でも取れるようになりますし、もしかしたら密度の急激な変化にそれなりに対応できるかもしれません。

 \displaystyle d(t)=\int^t  w(t-t') \sum _{\tau:各ノーツの時刻}\delta \left( \tau-t'\right) dt'

しかし、このような音声信号のスペクトル分析めいた方法を、音声信号ではまず取り扱わないデルタ関数をたくさん足しただけの形とみなせるノーツパターンに用いるのはなんか違う気がしますし、難易度や譜面傾向が大きく違う様々な譜面に対し、最適な窓関数が存在しない可能性があります*4

 

特にレーンに分かれてノーツが配置されたパターンにより適した計算方法を探しましょう。

 

最も時間変化に敏感で、急激な密度変化をよく表せそうなものは、各レーンのノーツとノーツの間の時間を用いるもので、すなわち以下のようなものです。 i レーン目の、k 番目のノーツの時刻を \tau_{ik}として iレーン目(皿を0レーン目としてですが)の密度を

 \displaystyle d_i ( \tau_{ik} \leqq t \leqq \tau_{ik+1} ) = \frac{1}{\tau_{ik+1}-\tau_{ik}}

とし、 d(t)=\sum_{i=0}^7 d_i(t) とするものです*5。これを用いると、先ほどのグラフで示した譜面の密度は下図のように計算されます。

矩形窓で計算した密度と同様、時間的に柔軟に変化しているうえに、とれる密度の値が連続的になりました。譜面においては58~64小節の24分乱打にあたる、~80000msあたりのやや密度の高い部分では、矩形窓では17 notes/sと18 notes/sの間を振動している様子しか見られませんでしたが、ここではさらに細かく、より幅広い密度を動いている様子が見られました。人間のプレイしている感覚ではここまで細かく密度変化を知覚しないかもしれませんが、たとえば2回ある24分階段の折り返しに当たる部分で鋭いピークが表れているのが見えます。こうした部分は、周りの部分より処理力を多く要求するとみなしているわけです。

 

こうした急なピークを和らげるため、ここで使用した「1ノーツ後の時刻」の代わりに「2ノーツ後の時刻」を用いる方法もありますが、こうした「処理力を大きく必要とする、非常に短い区間」で要求される処理力を過小評価するため、より難易度の見積もりが不正確になってしまいます*6

 

ということで、①としては「レーンごとのノーツの間隔から計算したレーンごとの密度を、各レーンで足す」方法で計算したものを密度関数として用います。なお、LNは始点の時刻だけを、通常ノーツの時刻と混ぜて取り扱いました。いくつかの譜面では非常に短い「ほぼ通常ノーツ」が多数あり、LN終点の時刻を含めるとその部分の密度が異常を示して要求処理力が異常値を示したため、終点を含めることはできませんでした。

 

①の説明に遠回りを含めて長い文章量を割きましたが、②はそれに比べるとすべきことは比較的明確なようです。必要なのはゲージの仕様の説明です。まあ探せば大抵のことは書いてありますが、ここでもまとめておきます。

まず、基本的なゲージの増加量・減少量です。今回のモデルで使用したGREATとPOORでの値だけ示しておきます*7a=\mathrm{TOTAL/NOTES} として、

beatoraja GREAT POOR
EASY a -4.5
NORMAL a -6
HARD 0.12~0.14 -10

HARDの回復量はJUDGERANKで変えています。

LR2 GREAT POOR
EASY 1.2a -4.8
NORMAL a -6
HARD 0.1 -10

そして、HARDの減少量補正について、

beatoraja: 50%以下で0.8倍、40%以下で0.7倍、30%以下で0.6倍、20%以下で0.5倍、10%以下で0.4倍

*8

LR2: 30%以下で0.6倍

としています。

そして、TOTAL補正は、

beatoraja: TOTAL値が低いと回復量が

Math.max(Math.min(0.15f, (2 * model.getTotal() - 320) / model.getTotalNotes()), 0);

に低下する(beatorajaのソースコードより)。

 

LR2:TOTAL値が240未満からゲージ減少量が増加し始め、120未満で即死。増加量の詳細は以下の通り(beatorajaのソースコードより)*9

if(model.getTotal()>=240.0){
	fix1=1.0f;
}else if(model.getTotal()>=230.0){
	fix1=1.11f;
}else if(model.getTotal()>=210.0){
	fix1=1.25f;
}else if(model.getTotal()>=200.0){
	fix1=1.5f;
}else if(model.getTotal()>=180.0){
	fix1=1.666f;
}else if(model.getTotal()>=160.0){
	fix1=2.0f;
}else if(model.getTotal()>=150.0){
	fix1=2.5f;
}else if(model.getTotal()>=130.0){
	fix1=3.333f;
}else if(model.getTotal()>=120.0){
	fix1=5.0f;
}else{
	fix1=10.0f;
}

 

そして、当初気が付かなかったのですが、なんとsatellite難易度表にすらTOTAL未定義の譜面が数個存在しており、そしてTOTAL未定義の譜面に対するTOTALの定め方もLR2とbeatorajaで異なっておりました。ただし、そこから算出されるTOTAL値はHARDの低TOTAL補正には引っ掛かりようがないため、主にEASYとNORMALの難易度に影響するものになります。

beatoraja: (beatorajaのソースコードより)

Math.max(260.0, 7.605 * totalnotes / (0.01 * totalnotes + 6.5))

LR2: (LR2orajaのソースコードより)

160.0 + (totalnotes + Math.min(Math.max(totalnotes-400, 0), 200))*0.16

譜面製作者各位はぜひTOTAL値を設定していただきますようお願い申し上げます…



 


これらのゲージに関する条件を踏まえたうえで、必要な処理力を計算します。計算は、②の仮定の下ゲージ推移のシミュレーションを行い*10、易・ノマゲであれば「ちょうど80%になる」処理力、難であれば「途中で0%を割らずにラストで0%になる」処理力を、二分法を使って求めます*11。せっかくなので先ほど密度を示した譜面について計算結果と要求処理力でのゲージ推移シミュレーションを示してみます。

各グラフの上の数字は計算された要求処理力ですが、正確なのは小数点以下7~8桁までです。

HARDよりNORMALのほうが要求処理力が大きく、さらにbeatorajaのほうではEASYすらHARDより難しいという結果になりました。もっとも密度が高いのがラストであり、HARDはこれまで回復した分で耐えられる一方でほかのゲージは100%から80%までしかない、というのがここに表れているようです。そして、beatorajaの場合はその「これまで回復した分での耐久」がより強化されているというところです。

 

 

 

調査の結果

6種類すべてのゲージに対し*12、satellite、stella*13、そして発狂難易度表とOverjoyの譜面に対してクリアするのに要求される処理力を計算しました*14。全部で9時間くらいかかったと思いますが、私の思い違いや計算ミス、そして想定外の譜面などによるプログラムの間違いがあるたびに計算をし直していたため、結局データ収集には2週間くらいかかりました*15。beatorajaのHARDとLR2のHARDの要求処理力の差を概観したのち、その差が際立った譜面とそうでない譜面を見てみます。

まず、発狂難易度表・Overjoy(旧)で要求される処理力の大きさを知る意味で、バイオリンプロットを提示します。バイオリンプロットというのは「連続的な箱ひげ図」のようなもので、連続的なので箱もひげもないというわけです*16知名度がないのは、手書きできないので学校の授業で教えられないからでしょう。最近の学校をよく知りませんが。

手間を惜しんでbemusicseekerの難度推定表からエクスポートしたjsonのデータを用いたためOverjoyの難易度などが現在と異なっています。なお★★7は要求処理力が大きすぎてグラフが見づらくなるので省略しました。

一部の異常な譜面(おそらく難しくない高密度な部分がある譜面)を除き、大体レベルに応じて要求処理力が大きくなっているのがわかります。

 

これらの譜面について、要求処理力の差は外れ値を除いてこのような分布になりました。

基本的な統計量は以下のようでした。

平均        1.213736
標準偏差    1.327606
最小        -0.096061
25%         0.781041
50%         1.023996
75%         1.401407
最大        37.852594

 

さて、特に要求処理力の差が大きい譜面を見てみましょう。

要求処理力の差が最も大きかった譜面は、幽雅に咲かせ、墨染の桜 [HYPER]でその差は約38 notes/sでした。

密度の時間変化。

2か所ある発狂はラストに来る方が激烈で、ここを耐えきれる処理力があればHARDランプがつきます。一時 900notes/sにも達する凄まじいラス殺しを耐えるにあたり、beatorajaのより多い回復量と50%以下補正が発狂全体にわたりLR2に対してアドバンテージを与え続けるわけですが、それがあまりにも高密度で行われるため、このように要求処理力に大差がつくわけですね。

 

冗談はこれくらいにして、Liberte-SuperSaw Epic mix- -ANOTHER-を見てみましょう。

ゲージ補正の強さというよりは、低TOTAL補正の仕様の違いによりbeatorajaのほうが簡単になっている譜面です。このような譜面では、POOR数が整数であるという縛りを設けなかった今回のモデルでのゲージ推移予測はほとんど意味を成しませんが、HARDの難易度差が生じる理由はよく理解できます。TOTALが100しかないため、LR2ではPOOR1度で即死ですが、beatorajaでは一切回復しないけど100%~0%までダメージを受け続けることができ、単純計算で13POORまでOKということになります。このように許容POOR数が異なるので、ラストをある程度ごまかしてよくなるbeatorajaは、もしかしたら算出される要求処理力の差以上にLR2より簡単かもしれませんね。

しかし、同様の傾向により要求処理力の差が大きくなっている譜面はさほど多くなく、まあ多くないほうがいいんですが、他にはTOTALが66しかないHeart To Heart -collect sky blue- [S-KF]などがあたります。もちろんSatelliteやStellaにはそのような譜面はありません。

ほかに要求処理力の差が大きくなっている譜面はおよそ「局所的な高密度」に特徴がありますが、見たところその高密度部分そのものは全く難しくないものが多く、この指標の欠点が浮き彫りになっています。例えば、conflict [EX-HARD]では下のように、モデルのプレイヤーが人間に比べて縦連地帯がめちゃくちゃ苦手になっています。

 

 

 

一応もう少し普通の譜面も見てみます。Trahison [E]では以下のようになります。

50%以下での補正・ゲージ回復の大きさがすべてHARDゲージの要求処理力の低下にかかわっているのが見えます。

 



なお、先述のような要求処理力の差の統計をEASY難易度についてもとってみると下のヒストグラムのようになりました。


外れ値を除いてあります。

基本的な統計量は下のようになり、全体的にEASYゲージの要求処理力はHARDほど差はありませんが上昇傾向にあることがわかります。

 

平均        -0.276048
標準偏差     0.566175
最小        -14.747367
25%         -0.353802
50%         -0.229400
75%         -0.123583
最大         3.555503

ところで、「beatorajaのHARDはLR2のHARDより簡単である」ことは知られているようですが、このようにEASYはbeatorajaのほうが難しい傾向にあることはあまり言われておりません。HARDと違って「確実にbeatorajaのほうが難しい」とはいえないのですが、この事実を認知しているといいことがあるかもしれません。


さて、ここで「beatorajaのHARDはLR2のHARDよりどれほど簡単なのか」に関する端的な答えを探すために、LR2での要求処理力とbeatorajaでの要求処理力の近い2譜面の組み合わせを探しましょう。こうすれば、一応

「LR2で△△をHARD CLEARできれば、beatorajaでは○○をHARD CLEARできます!」

と言うことができ、△△と○○の組み合わせ次第ではかなり強い言葉(呪い?)になるんじゃないかと思います。

これらの組み合わせには実際のところ、譜面傾向があまりにも違いすぎたり、要求処理力が難易度を十分反映していなかったりして意味をなさない組み合わせが多くあるのですが*17、私の地力と難易度感覚でピンときた譜面の組み合わせは

 

(LR2) ★1 Canon (blazing summer mix) [EXTRA]  19.59

→(beatoraja) ★1 星の器~STAR OF ANDROMEDA (ANOTHER) 19.56

 

くらいしかありませんでした。一応計算で得られたデータをまとめたスプレッドシートを作ってこの記事の末尾に置いておくので探してみてはいかがでしょうか。

 

また、先ほど挙げたようなバイオリンプロットを、satelliteやstellaでも同様に作ることができ、下図のようになります*18

 

若干発狂難易度表・Overjoyのものよりきれいに見えるような…

 

 

 

 

調査の結果(2)

 

さて、譜面の難易度の指標として最もよく使われるのがLR2IRのプレイデータを用いた「リコメンド」です。ここでは「難度推定表」とか「推定難度」とか書くことにしますが、ここで示した密度の指標が難易度とどれくらい相関があるか考えるために、「推定難度」のデータを用いて分析します。

 

 

各ゲージでのクリアで今回算出された「要求処理力」とリコメンドの「推定難度」との散布図がこちらになります*19

(左)LR2、(右)beatorajaの要求処理力と組み合わせたもの。
赤い点はHARD難易度、青い点はNORMAL難易度、緑の点はEASY難易度。

それぞれには回帰直線が引かれており、LR2ではy=-4.18745754+0.17539751x、beatorajaではy=-3.94759955+0.17053797xです。

各色の点のばらつきから目標としているゲージによって回帰直線から系統的にずれが生じているように見えます。

決定係数(相関係数の2乗)は、75.598 % (LR2)、72.643% (beatoraja)でした。この決定係数は、指標が十分良ければある程度100 %に近づくことが期待されますが、難度推定表とて完全ではない*20ので、100 %に近すぎるのは過剰適合です。しかし、この範囲内ではbeatorajaのほうが難易度指標としての「推定難度」の信憑性がある程度低いと見積もることができます。

さて、このように回帰直線が得られたため、相当無理はありますがHARDの要求処理力の差をθの差に変換することができ、これともともとの推定難度から★の差に変換することができるようになりました。そこから得られた★の差のヒストグラムは下のようになります。

これがこの記事で最も「beatorajaのHARDはLR2のHARDよりどれほど簡単なのか」っぽい図だと思います。なお、★の差が大きいほうから4譜面を外れ値として除いています。中央値は★0.84でした。

と同時に、★の単位で表された数字の心を揺さぶる力にも注目しましょう。

まああまりに違うというわけでもなさそうですが、完全に無視するのは心地の悪い微妙な違いです。

 

 

 

 

最後に、あるいは最初に

 この記事では、LR2とbeatorajaの、発狂BMSプレイヤー的には最も決定的な違いであると思われるHARDゲージの仕様の違いに焦点を当て、それが実際にどのような差を生み出しているのかを、譜面密度からゲージの推移をシミュレーションする方針で分析しました。

私が用いた譜面密度によるモデルは非常に雑で、明確に難点はありましたが、それでも当初設定した課題の「beatorajaのHARDはLR2のHARDよりどれほど簡単なのか」という問いについては、ある程度答えになる情報を得ることができたと思います。

 

計算された要求処理力のデータをこちらに置いておきます。

 

docs.google.com

 

音楽ゲームは、「自分の技を磨き、試練を乗り越える」ゲームという性格があります。もしかしたら、当初はそうではなかったのかもしれないが、今は少なくとも一部の人にとっては、ただ高難易度、高スコアを極めるゲームになっています。そのような類のゲームは現在の音ゲー以前からありましたが、音ゲーは「音楽とリズムを楽しむ」という性格と*21、何より「自分の能力のある程度絶対的な可視化がある」という要素により現在まで人気を保っているのではないかと考えられます。

 

その中でも、beatmania IIDXや発狂BMSはその最たるものであり、「理論値に比べて目標とされやすいラインが非常に低く、譜面そのものが非常に難しい」という性格で人気を博しています。

 

しかし、ゲーム内の可視化だけでは、実力という意味での自分の位置づけをはっきりと知覚するには全く不十分であり、プレイヤーデータの統計的解析を用いた指標が考案されました。

 

代表的なものには、発狂BMSでは「リコメンド*22」やIIDXでは「CPI」が存在します。方式は違いますが、どちらも特定の譜面セットに対するプレイヤーの成績をまとめることによって算出される指標であり、成績データベースに依存しています。

「リコメンド」は発狂難易度表・Overjoyでランプ更新できそうな譜面のリストを提供するのに(beatorajaでも)非常に役立ちますが、LR2IRのデータを用いているもののため、beatorajaでのランプから算出される推定実力は「実際の実力よりやや大きい値になってしまう」し*23、EASYとHARDの難易度差がLR2とbeatorajaで異なる以上、元の計算の前提が成立していないところで推定実力やリコメンドリストが導出されている居心地の悪さが少しあります。

そしてこれと、難度推定表がかくも発狂BMSの標準的なツールとして普及している*24ことが、本来マイナスポイントでなかったゲージの仕様の違いがマイナスポイントに見えてしまう原因であることは、もはや言うまでもありません。

 

今はそのようなデータベースに頼らずに難易度の当たりをつける方法を考えるべきだと思うのです。確かに、これは「beatoraja側の人間が発狂BMSをプレイするにあたりLR2に対して引け目を感じないための苦しい方策」かもしれませんが、beatorajaで発狂BMSをやるなら

 

「LR2とbeatorajaの仕様の違いは受け入れながら、その違いに向き合う」

 

ことが大事なのではないでしょうか。

 

というわけで、この記事でこれまでやってきたことはただbeatorajaユーザーを不快にさせるだけだったかもしれませんが、こうした「成績データベースに頼らない、譜面そのものからのクリア難易度の推定」がそもそも私の興味の中心だったわけです。ただ、この大目標を立てるのはよいですが、スタート地点に立ったばかりでこの記事だけで十分納得できる結論を得るにはあまりにも遠すぎるため、とりあえず「beatorajaのHARDはLR2のHARDよりどれほど簡単なのか」というテーマを立て、可能な限り素朴なモデルを作って、「少なくとも雑なモデルでこれくらいのことは言える」という基準を置くという意図がありました。

 

 

理想的な難易度の指標とはどのようなものでしょうか。

 

そもそも一次元的な「難易度と呼べる尺度」にすべての譜面を押し込むことには限界があります。特に高難易度は、この尺度に収まることを拒否するような独特な譜面であふれていることもあるでしょう*25。そのことを踏まえたうえで、それでもそうせざるを得ないときに、最適な方法は「その難易度の譜面が『できる』ギリギリ付近の人の感覚の平均をもとに表をつくること*26」です。難易度表づくりに参加する人数が十分多ければ、奇怪な統計学的技巧を駆使しなくとも、投票などによって適当な難易度表が作られるでしょう。その難易度表に不満があれば、それは譜面の実際の難しさが一次元的でないからです。大体このような思想のもと、ほとんどの音楽ゲームの「非公式難易度表」は投票によってつくられています。しかし、発狂BMSともなると「同じくらいの地力」の人間をたくさん探すのはかなりは困難だし、そもそも難易度表づくりの場が実質的に開かれているようにも思えません*27。そこで出てくるのが数理的な手法による難易度の算出になるわけですね。そのように考えると、難易度の算出に多数のプレイヤーのプレイ結果を用いた項目反応理論やイロレーティングの手法が用いられるのは自然な流れということができます。こういった指標の難点は、プレイデータは譜面の難易度とプレイヤーの実力のみによって形成されるわけではないために、それとは無関係な要素の影響を受けてしまうという点です。問題は、その要素がしばしば特定できないということです。

一方今回提案した「譜面密度ベースの指標」は、こうした統計的手法によって算出された指標よりも雑で、不正確ですが、少なくともその理由はある程度分かりやすいのではないでしょうか。そして、今はこうした「譜面そのものから難易度を見る」指標として最も素朴で、雑なものとして提案しているのであり、この記事で提示したアイデアをより一般化して*28

 

①譜面の「瞬間的な難易度」を、時刻 t の関数 d(t) として記述する。

 

②その譜面を、各種ゲージでクリアするのに必要な「処理力」n (以下、要求処理力)を計算する。

ここで、n はプレイヤーの能力を示す値であり、「処理力」が n のプレイヤーはその譜面の時刻 t において毎秒  f(d(t)-n) %ゲージ変動するものとする

 

として、df の公式をより改善し、どんどん正確な指標を作ることができるでしょう。もちろんこれは楽観的な見方ですが、そういう方向で考察を進めてもよいのではないでしょうか。私はこの問題を、私だけが考える問題ではないと思っています。

 

そもそも私たちは難易度表や指標に何を求めているのでしょうか?

「リコメンド」はただ難度や実力を推定するだけでなく、個人差要素をシグモイド曲線の傾きにすべて押し付ける形ではありますがいちおう定量的に考慮し、ランプデータから「その人のランプ更新できそうな譜面を提案する」ところに意義がありました。ところで、これは「今の実力でよりよいランプをつけたい」という思想によるところが大きいのであって、「地力を上げるのに適した譜面のリストが欲しい」というものとは明確に区別されなければなりません。

とにかく、こうした表は「今の私がプレイするに足る譜面の、短めのリスト」を提示できればその目的は達せたといえるでしょう。その目的であれば、難易度の正確な反映はある程度あれば十分ということになります。例えば、「ライトノベルの主人公最強ランキング」であれば、細かい差も重要視されますが、難易度表に求めるものはそれではないということです。なんか指標が不正確なことの言い訳っぽくなってきましたが、もちろんある程度の正確性は必要で、この記事で示した指標はそれには若干足りないかもしれません。

 

しかし、難易度表にはもう一つ重要な効果があります。

求道としての音楽ゲームには「その目標に権威を感じること」がほぼ必要不可欠であるように思われます。これは、「みんなやってるから私もやる、みんな目指してるから私も目指す」ということを含むものでしょう。本来開かれたコミュニティリズムゲームである発狂BMSにおいてその権威は「有力な難易度表に掲載されること」からくるものが大きいのではないでしょうか。そのような難易度表は、定期的に更新されるものであれば、譜面が提案され、投票を経て一定の条件を満たした譜面が登載されるというシステムになっています。このように手間がかかるうえ、先述のように、理想的には投票によりつくられた難易度表は信頼できるため*29、例えば差分譜面作者が自分の譜面に対して作った難易度表よりも多くプレイされるのだと思います。いや、ここまで合理的に説明しようとしてきましたが、結局現状では「みんなやってる難易度表はみんなやってる」以上のことを言っても仕方がありません。実際(GENOCIDEやOverjoyの場合)「発狂段位」という最も権威ある達成項目がその難易度表周辺で作られているという事実などもあります。

そして、この傾向は「リコメンド」や「cinnamon rating」などのツールにより、さらに強力にサポートされています。そこで取り扱われている譜面セットを逸脱し、様々な譜面をプレイする気のある人は非常に少ないのではないでしょうか。

 

さて、ここでコミュニティリズムゲームの世界第一といえる*30osu!を見てみましょう。ほとんど伝聞でしか知りませんが、譜面難易度の自動計算が行われているようです。ところでその算出方法については(私がソースコードをよく読んでおらず、わからないのですが、)、クリア基準がBMSと比べて非常に厳しいため、もしかしたら最難所の難易度がわかればそれで充分かもしれませんが、それでもosu!maniaでは難易度を決める大きな要素となっているLNに関する難易度の算出方法については学べるところがあるかもしれません。とにかく、難易度の自動計算が最初から組み込まれているような環境なので、譜面の難易度体系への組み込みが非常にスムーズであり、そこには「提案・投票・登載」のプロセスがありません*31。すると、そこには「難易度表からくる権威」はありません。もちろんosu!の場合も人気曲・人気譜面から「目標にしたいもの」が生まれますし、モチベーションを上げるための別のシステムがあるようです。

 

譜面の数があまりにも膨大で、何をしていいかわからないというのも一つの問題ではありますが、発狂BMSでも譜面そのものにあたった難易度評価を導入してやると、発狂BMSの風景も少し変えられるのではないかと思います。もしちゃんとした指標ができたとしても、正直有力な難易度表を逸脱するプレイヤーは少数しか現れないとは思いますが、もしその少数のプレイヤーの支援や後押しができれば、これは意義のあることだと思います。「譜面そのものからの難易度の推定」は、プレイ人数が十分多いことを前提としないことが重要です。先ほど「適当な地力のある、十分多い人数の投票」が正確な難易度表を作る、と述べましたが、結局のところプレイヤー自身が感じた難易度が最も正確です。しかし、その難易度はプレイしなければわかりません。そこで、プレイ人数の非常に少ない表外譜面や、BMSイベントの新しい同梱譜面など、難易度を譜面作者が勝手につけた数字に頼るしかなかった譜面に対してある程度統一的な指標を用いることができれば、プレイする譜面の選択に大きく役立ちます。

 

いろいろbeatoraja側の人間が不快になるかもしれないようなことを延々と書いてきましたが、私はbeatorajaで発狂BMSをプレイしていて、そうでなければこのような話題で記事を書かないと思います。beatoraja側の人間は成績データベースとしてのLR2IRについて、アンチチート機能の欠落などといったものを指摘し、その信頼性に対して疑問を呈していますが、現状ではそれをもって発狂BMSプレイヤーにとってのLR2IRの権威とLR2IRデータに対する信頼を失墜させることは直ちには不可能であるように思われます。統計的手法を用いた有力な指標の計算のもととなっており、また発狂BMSに関する分析の元データとなっていることなどのために、これからもLR2IRとLR2はしばらくは生き残り続けていくでしょう。そして、beatorajaではそのような巨大なデータベースを作ることには否定的であるため、そこからLR2IRのようには統計的な解析はできないだろうと思います。そこで、信頼できる譜面の難易度分析の方法として、譜面そのものに当たるものに可能性を見出しているわけです。

 

最後に、私は読んだことがありませんが、Satellite・Stellaの譜面そのものを分析し譜面傾向を調べたという内容の同人誌があることに言及しておきます。瞬間密度の算出も行っているらしく、私がこの記事でやっている処理はたぶんこの同人誌でやっているものよりもはるかに原始的で雑です。しかし、その目的にはある程度の方向性の違いがあるのではないかと思います。

 

https://www.melonbooks.co.jp/detail/detail.php?product_id=1595551

 

この長すぎる記事を書くにあたり会津さんに助けていただいた部分が大きいので、感謝します。「ライトノベルの主人公最強ランキング」の例えを提示してくれたのは彼でしたし、この記事を書く意義を何度も再確認させてくれたという意義もあります。彼が年末記事として書いたものは完成したときにここにリンクでも張ろうと思います。

 

Happy Centuryはプレイするたびに複雑な心境になります。readmeを読む限り作者はそこまで深く考えていなかったようですが、「新しい時代」とか言うと一気に胡散臭くなる感じがします。21世紀のこれまでの22年間を教科書的に振り返ると「何がHappy Centuryだよ」と言いたくなりますが、そういうポーズをとる人が非常に多いであろうことから、あえてこれを安易と断じてみてもよいかもしれません。きっと良いこともたくさんあったであろうからです。無条件に「時代を先に進めるべき」という考えには全く賛同しかねるし、「時代を先に進めるしかない」というのは、私にとっては諦めの言葉です。BMSに関しても、部分的にそうです。beatorajaがBMSの新時代を志向するには十分な理由があります。それが必ずしも既存の発狂BMSプレイヤーに向けられたものでないにしても、新規の発狂BMSプレイヤーは、とくに発狂BMSができる地力に至るまでbeatorajaにいた場合、この環境からあえて出たいと思わないでしょう。今のところBMSプレイヤーには選択の自由がありますが、もし時代がLR2を置き去りにするとしたら、それはきっとこのような仕組みによってです。その時に、beatoraja環境のためのプレイヤー支援が充実しているのは大事なことだと思います。この部分が記事全体から見て余計な脇道にしか見えないのであれば、それは私の文章力の問題か、本当に余計な脇道であるかのどちらかです。

*1:しかし、回復量の増加も加味すればゲージ増減はbeatorajaのほうが4%くらい得です。

*2:beatorajaではHARDゲージの回復量がGREAT(0.12%)とPGREAT(0.15%)で異なるため、どうしたものかと思いますが、とりあえずJUDGERANKに応じてEASY: 0.14%、NORMAL: 0.13%、HARD: 0.12%ということにします。

*3:特に皿を過小評価していると思います

*4:実際に起こったこととしては、私が考えなしにハン窓を使ってみたところ高密度地帯の密度が矩形窓での密度よりも過剰に大きくなってしまい、「無理そうだ」と思って、この次に示す方法を思いついたということです。

*5:ただし、時間積分がノーツ数にやや足りなくなるので、最初のノーツまたは最後のノーツのところで適当に処理する必要があります。ここでは、各レーンの最初のノーツの前の時間でd_i(t\leqq \tau_{i0})=1/\tau_{i0}としています。

*6:急に明晰なことを書いたように見えますね。これは実際、後述の検証をこのモデルに対しても行ったから言えることです。

*7:今回は判定幅の違いは考慮しないことにします。

*8:

これを、pythonでは

のように書いており、可読性とはという感じです。

*9:ところで、これ 200 \leqq \mathrm{TOTAL}\lt210を除いてほぼ10/整数倍になっているのですが、小数の桁数などに統一性がなく、結局この長い条件分岐をほぼそのまま突っ込むほかありませんでした。どうして…

*10:こういうとなんかすごそうですね

*11:30回繰り返して小数点以下7〜8桁くらいの精度で求めました。限界の精度を出すには60回くらい繰り返す必要があります。

*12:ノマゲに関してはGREATの回復量とPOORのダメージがそれぞれ同じなので、必要な計算は1譜面につき5回です。

*13:最新のものではなく、2022年11月時点の難易度表データです。

*14:ランダム分岐や文字コードなどの理由により計算できなかった数譜面を除いています。当然ですがU9は除外です。

*15:まだ間違いもあるかもしれませんが。

*16:ただし、seabornで標準的なバイオリンプロットは小さく箱ひげ図も示してあるようです

*17:これらの組み合わせが「密度だけで難易度を比べてはいけません」と語りかけてきているようです。

*18:2022年11月8日時点の難易度表データを用いており、結構古いです。

*19:なお、推定難度はWebPlotDigitizerを用いてここにあるグラフを読み取り、そこから★をθに戻した値を用いています。θは間隔尺度ですが★はそうではないので、直線的な相関を得るにはθを用いたほうが良いと考えられます。

automeris.io

で、読み取って★とθの関係を再現したグラフが下図です。

 

 

*20:

人気曲の推定難度がやたら低いことがよく言われています。また、プレイヤーデータを用いている関係上プレイヤーの少ない超高難度帯のデータの信頼性はどうしても低くなってしまいます。

さらに、この素朴な処理力指標を使うと、すべての曲に対する「EASY<NORMAL<HARD」の仮定を疑うことができます。LR2でEASYとHARDの要求処理力の差をヒストグラムにすると下図のようになり、EASYのほうが要求処理力が高い譜面がそこそこあることがわかります。

そして、EASYのほうが要求処理力が高い譜面は(Overjoyと発狂難易度表の重複を含みますが)1285譜面中227譜面ありました。BMSのゲージの難易度の関係は思ったほど絶対的ではないのかもしれません。そして、同じことをbeatorajaでの要求処理力の差でみるとさらにひどく、441譜面がEASYの要求処理力のほうが高いという結果になりました。全体的にEASYの要求処理力が上がり、HARDの要求処理力が下がったため、ハード逃げした方がよい譜面が多くあるようです。

BMSが項目反応理論の想定するような実力テストではなくゲームであることがよくわかります。

*21:こう書いて、何とか「文化」的なものにしがみつこうとしている私です。

*22:本質的に作り出されたものは「難度推定表」かもしれませんが、結局プレイヤーは「推定実力」の数字に吸い寄せられています。「リコメンド」の目的は「今の自分の実力でランプ更新できそうな譜面をおすすめする」ことであり、Twitterの名前やbioに推定実力を書いたりして自分の到達点を誇示するのは二次的なものとはいえ、やっぱ見える数字の力には抗えないし、自分の到達点を誇示するのは音ゲーにおいて大きなモチベーションになり得るのも事実です。ところで、「推定実力」をリコメンドと呼ぶようになったのは興味深いですね。この記事では、いわゆる「リコメンド」のことを「難度推定表」や「推定実力」という言葉を用いて呼んでいます。

*23:beatorajaのランプではなく、LR2のランプで算出された実力を「実際の実力」と言える根拠は、難度推定表にLR2IRのデータが用いられていること以外にありませんし、そもそも「実際の実力」という言い方は非常によくないと思います。ところで、実はbeatorajaでの推定実力が高めに出る(段位の推定難度よりかなり高い値なのに段位がとれないところが顕著)原因は、本質的にはHARDの難易度差ではなくGASのおかげで可能な限りのノマゲランプがついているところにあるのではないかと思うのですが、その裏付けはこの記事の範囲を超えます。

*24:要出典

*25:ここに「地力」概念の限界をみることもできます。

*26:ここでは「できる」の基準を意図的にあいまいにしています。

*27:beatorajaにはlevel reviewというのがありますが、mocha-repositoryにわざわざ行って難易度を小数でサジェストしなければならず、わざわざそれをする気になる人がどれほどいるか疑問ではあります。

*28:本当は、譜面の難易度の多次元性を反映してさらに一般化を行い、各プレイヤーに合わせたオーダーメイドな難易度表を提示するものを考えられますが、それに当てはまる指標を作れるとするのは望みすぎかもしれません。

*29:そもそも十分な投票が集まる時点で難易度表が信頼されているといえるかもしれませんね。

*30:なぜそうかをBMS側の人間が言うと愚痴になります。

*31:2023年3月14日追記: osu!には「Ranked」という、「osu!の指標で考慮すべき譜面であること」を認証するシステムがあるそうで、譜面をRankedにするには多くの手続きと譜面の質(のような何か)が要求されるようです。そう考えると、この段落の議論はかなり無効に近いかもしれません。