Qman's Diary

多趣味人間の備忘録

2023-12-10

maimaiのべ枠画像生成ツールとかマイ定数表作るために譜面定数データ欲しい

タグ
技術
音楽ゲーム
maimai

欲しい!

有り体に言えば、なんでmaimaiのツールを作ってないのかの話をします。

一言で言えばクソバカアホボケ大変だからです。が、それで納得してもらえるとも思えないので、プログラミング的な話をちまちま挟みつつ解説します。

もっと詳しい話

ツールを作るためには譜面定数データが必要

当たり前ですね。こういった譜面定数データはどこからやってきているのでしょうか?

それは、CHUNITHMであればchunirecから、オンゲキであればOngekiScoreLogからデータをいただいています。(本当にありがとうございます)

CHUNITHM (chunirec) の場合

例えば、chunirecの曲のデータはこのようになっています。(1曲だけ抜粋しています)

[
  {
    "meta": {
      "id": "6a88218b1a936bd3",
      "title": "B.B.K.K.B.K.K.",
      "genre": "VARIETY",
      "artist": "nora2r",
      "release": "2015-07-17",
      "bpm": 170
    },
    "data": {
      "BAS": {
        "level": 3,
        "const": 0,
        "maxcombo": 333,
        "is_const_unknown": 1
      },
      "ADV": {
        "level": 5,
        "const": 0,
        "maxcombo": 541,
        "is_const_unknown": 1
      },
      "EXP": {
        "level": 10,
        "const": 10,
        "maxcombo": 1051,
        "is_const_unknown": 0
      },
      "MAS": {
        "level": 12.5,
        "const": 12.5,
        "maxcombo": 960,
        "is_const_unknown": 0
      },
      "ULT": {
        "level": 13.5,
        "const": 13.7,
        "maxcombo": 1626,
        "is_const_unknown": 0
      }
    }
  }
]

プログラミング的なことが何もわからない人でも、何が書かれているのかはなんとなくわかると思います。このようなカッチリした書き方のおかげで、プログラムから読みやすいようになっているわけです。

オンゲキ (OngekiScoreLogの場合)

OngekiScoreLogは上記のような形ではありませんが、表の形で定数を提供してくれています。(参照: OngekiScoreLog - 楽曲リスト)

これを、プログラミングの力で、こうして……

Google Spreadsheet、愛してる

これだけだと曲を作った人の情報とかが欠けてるので、公式サイトからもデータを持ってきて……

色分けすると"表"って感じしていいよね

気合で合体します。

𝓟𝓮𝓻𝓯𝓮𝓬𝓽...

まあやってることは二つのデータの曲のタイトルを照らし合わせながらデータをいい感じに組み合わせていくという作業なんですが、これもちょっと大変です。Singularityが3つあるせいで。

なんか苦労してて草
同じタイトルの曲がなかったら必要なかった数行のコード。せっかくなので晒しておきます

そしてこれをプログラミングの力でさらにごにょごにょして……

[
  {
    "title": "GO!GO!ラブリズム♥",
    "artist": "片霧烈火オンザみんマンション",
    "has_lunatic": false,
    "only_lunatic": false,
    "category": "チュウマイ",
    "img_url": "5a9758493362722b.png",
    "music_id": 51,
    "add_date": "2018-07-25T15:00:00.000Z",
    "lnt_add_date": "",
    "basic": {
      "level": "3",
      "const": 3,
      "is_unknown": true
    },
    "advanced": {
      "level": "6",
      "const": 6,
      "is_unknown": true
    },
    "expert": {
      "level": "8+",
      "const": 8.7,
      "is_unknown": true
    },
    "master": {
      "level": "11+",
      "const": 11.9,
      "is_unknown": false
    },
    "lunatic": {
      "level": "",
      "const": "",
      "is_unknown": false
    }
  }
]

完成です。お疲れ様でした。これを作るのには結構苦労しましたが、結果としてそれなりに良いものができたんじゃないでしょうか。

もちろん、自作のせいで変なバグをいろいろ仕込んだりもしましたが……報告してくれた方々、ありがとうございます。

maimaiの譜面定数の話

maimaiにも譜面定数表はあるだろって? そうですね。あります。ありますが、正直言って実用に堪えません

譜面定数表を作ってくださる皆様へ: めっちゃディスるようなことを言って申し訳ありません。理由についてはちゃんとこの後に書いてあるので読んでいただければ幸いです。役に立たないのは我々の特殊な理由によるものであって、実際のところ、ほとんどの人にとって皆様の作ってくださる譜面定数表は大変役に立ちます。本当にありがとうございます。

……言い訳も済んだので、ちゃんと説明します。

ここで言う『実用に堪えない』という結論は、以下の4つの理由から構成されています。

機械的に読み取りづらい

ここでは、とりあえず有力な定数情報ソースたりうるWikiを例に取り上げます。

突然ですが、皆さんは以下の表を見てどう思いますか?

CHUNITHM Wikiより引用。あげつらうつもりはないので許して欲しい

別に見やすいですよね?私もそう思います。

しかし、何も考えずに作られたプログラムには、おそらく以下のように見えます。ここでは15.1の最初のところだけ抜粋します。

15.1

ULT

VAR

Aleph-0

1519

15.0

MAS

撃舞

sølips

2750

N

LAMIA

3000

N

ORI

POTENTIAL

2808

-

ここでは、『列ごとの情報の種類が同一でない』という問題が生じています。

Webサイトを表示するための言語であるHTMLの都合上、ここで言うMASや撃舞のような複数行にまたがる長いセルは、それが登場する最初の行で「このセルは◯行分の高さです」と宣言する構造になっています(詳しい方向けに言えばtdのrowspanの値が行数分になっています)。そのため以降の行ではMASセルや撃舞が登場せず、いきなり曲名から始まります。

まあ、行あたりのデータの数を最大5つと決め打ちして、数に応じて右からデータを見ていくのでもできなくはないでしょうが……正直、面倒です。

ちなみに余談ですが、Excelのセルを結合するなと怒り狂うエンジニアをよく見かけるのもだいたい同じ理由です。機械的に読み取りにくいんだわ。

さらに言えば、この表にはもう1つ問題があります。それは、今見ている行の曲の定数がわからないことです。

譜面定数は上の行を1行まるまる使って表示されていますが、普通プログラムが表を見るときは上から1行ずつ読んでいくので、譜面定数の行を読み込んだら一旦その譜面定数を記憶しておかなければいけないという面倒くささが生じます。

それを考えると、OngekiScoreLogの提供しているこちらの定数表がいかに読みやすいかを実感できますね。1行読めば必要な情報が全部手に入るわけですから。

冗長な表現もたまには必要

曲名が間違っていることがある

表示の都合上か、あるいは単純に見間違えたのか、曲名の文字が本来と違うこともあります。例えば、Wikiでは『[CRYSTAL_ACCESS]』が『[CRYSTAL_ACEESS]』になっていたのを見たことがあります。カッコが全角になっていますね。

先程オンゲキのところで述べたように、「曲名を照らし合わせてデータを扱う」ということはよくあります。少し込み入った話になりますが、例えば私が曲のジャケット画像を公式サイトから取得する際は、曲タイトルと作曲者名を組み合わせたものにmd5という処理をかけた名前にしています。

曲タイトルとかそのままだとファイル名に使えない特殊な文字使ってることがありますからね

md5については、不正確ですがここでは『突っ込まれたデータをいじくり回して32文字にする処理』と考えてくれればいいです。同じデータを突っ込んだら必ず同じ32文字が出てきます。そして、別々のデータを突っ込んで同じ32文字が出てくる確率はほぼ0です。詳しくは『暗号学的ハッシュ関数』で検索!

上の方で出したchunirecのデータにも曲タイトルと作曲者名が含まれているので、それを使って画像URLを作っています。1文字でも文字が違えば出てくる32文字は全く違うものになるので、正確性は大切です。

情報ソース元が安定しない

探していると、実は機械的に読みやすいmaimaiの定数表があります。

それは、現時点では[mDX9.0]BUDDiES譜面定数表です。ただし、みんなが見ている見やすい表ではなく、一番右のTmaiタブです。管理ページです。

なんて見やすいんだ……!

ここには『曲名』『譜面種別(でらっくす譜面かスタンダード譜面か)』『難易度』『譜面定数』の情報が揃っています。オンゲキのときと同じ要領で作曲者の情報を組み合わせれば、多分定数表として申し分ないものができるでしょう。曲名の間違いも見た感じなさそうですし、まああったとしても少量なのでこちらでカバーできそうな雰囲気があります。

しかし、この定数表にも問題があります。その1つが、この定数表はBUDDiESの間しか使えないということです。新しいバージョンが稼働すれば、新しいバージョンの定数表が用意されます。その度に、私が手動で定数表のURLを書き換えないといけないわけです。仕方ないとはいえ、正直面倒です。

あと、この定数表がずっとこの形であるとも限りません。次のバージョンで定数の列が1列右にずらされたりしたら、それだけでデータが壊れてしまいます。

全楽曲が載っていない

また、上記の定数表はあくまでも『譜面定数を調べるときに書き込む』ものであり、最初から全楽曲が掲載されているわけではありません。そのため、これを定数表として用いる場合は、情報が見つからなかったら仮の情報に置き換える必要があります。

先程から何度か引き合いに出しているOngekiScoreLogの譜面定数表は、データが欠けている場合は最初から仮のデータが入るようになっています。レベルが12+であればそのレベルの最低定数である12.7が仮で入っているということです。chunirecも同様で、dataの中のis_const_unknown1ならば『譜面定数は未調査で仮の値が入っている』という意味合いになります。

灰色の斜体は未調査・未確定の定数です。もっともADV以下が調べられることはないでしょうが……

これによって、多少不正確であっても欠けのない定数表を作ることができます。

この処理を自前で実装することは、まあ不可能ではありませんが骨が折れる作業です。

まとめ

maimaiの譜面定数表を用意しようと考えると、私は以下のことを自分でやらないといけません。

  • バージョンが変わるごとに譜面定数表のURLを変え、フォーマットが変化していないか確かめる
  • 不完全な譜面定数表と公式サイトのデータをうまく合成する
  • 曲名の間違いを自分で管理する
  • プレイヤーのデータからレートを計算する

まあ、不可能ではないです。しかし、手間が大きいです。新たに一からプログラムを書く必要がありますし、定数表のURLなどプログラムではなく手動で管理する部分もあります。さらに言えば、maimaiにはメジャーなスコア管理ツールが存在していません。強いて言えば舞スコアがありますが、こちらはchunirecやOngekiScoreLogと違って譜面定数なしで管理しているんですよね……そのため、レートを自力で計算する必要があります。

レートの計算の自力実装は、直近だと海外版CHUNITHM用ベスト枠画像ジェネレーターを作ったときにやりました。マジでもうやりたくないです。小数の計算で誤差が出まくった上何度も式をミスっては間違いを指摘されました(もちろん、指摘されるだけマシです)。レートなんて一番間違えちゃいけない部分ですからね。

ツールの作成は維持管理がミソです。バグがあったら直さなきゃいけないし、バージョンアップによって動かなくなることもあります。それを自分一人でmaimaiの分までやるのはマジで荷が重いです。一度作ってしまえばある程度楽なのかもしれないですけどね……誰かが定数表だけでも作ってくれれば、まあ、ぼちぼち作るかもしれないですが……。

Recent Articles
>> キューマンのコンテンツ置き場
Profile

オタクコンテンツで命を繋いでいる人間

Accounts
Category
Tweets