日々、雑雑と。

いろいろなことを垂れ流し

難易度表のコンテンツをGoogleスプレッドシート+GASで管理してみる

BMS制作について Advent Calendar 2017 - Adventar
BMS制作について Advent Calendar 2017」の23日目の記事です。
「難易度表を作ってみたい」、「難易度表を簡単に管理したい」という方に向けて、Googleスプレッドシート+GASを使った管理しやすい難易度表を作るTIPsを紹介します。
Webアプリケーションを絡ませるため、若干敷居が高いですが、お覚悟を。f:id:zatsuzatsu:20171223012717p:plain

はじめに

難易度表とは

 難易度表とは、数あるBMSから抜粋した譜面を難易度順に並べたリストです。主に下記の理由で作られたりします。

  • 好きな楽曲・人気な楽曲を纏めたい
  • 特定の属性に縛った譜面を集めて練習したい
  • 自作差分・楽曲を難易度表の体裁で公開したい

難易度表の作成

 現在主流の難易度表フォーマットについては、以下のページが参考になります。難易度表を作るときは必ず目を通してください。
 このフォーマットに従ってコンテンツを揃えることで、難易度表として機能します。
第2通常難易度表:難易度表導入支援ツール(難易度表管理者様向け資料)bmsnormal2.syuriken.jp
 
 難易度表を公開するといった場合、Webサーバ上に3点のファイルを上げる必要があります。これらのファイルは同一サーバに置かれている必要はありません。

  • 難易度表のWebページ(*.html)
    • このファイルのアクセスURLは難易度表を読み込むときに真っ先に読み込まれます。
    • ↓のヘッダファイルへのリンクが入っています。
  • 難易度表のヘッダファイル(*.json)
    • 難易度表の概要とデータファイルへのリンクが入ってます。
    • ↓のデータファイルへのリンクが入っています。
  • 難易度表のデータファイル(*.json)
    • 難易度表の各譜面の情報が入っています。JSONのオブジェクト型配列として表現されます。

難易度表の管理

 難易度表は作ったら終わりではなく、今後も逐次更新されていくコンテンツです。ところが、更新の度に、データファイルのJSONを直で変更するのは効率悪いですし、なによりいつの間にかフォーマットを崩す危険性もあります。「JSONとして正しいフォーマットなのに難易度表として取り込まれない!!!」といった問題も十分に起こり得ます。この場合、問題の特定が非常に大変です。
 また、更新する度に毎回FTPでアップロードするの、面倒くさいです。変更したら即座に最新版の難易度表が読み込められる仕組みになってたらラクチンです。
 
 今回は、難易度表の管理方式をスマートにすべく、Googleスプレッドシート上で管理を行い、GASのWebアプリケーションで最新版の難易度表のJSONを取得できるようなシステムを作ってみました。

構成

f:id:zatsuzatsu:20171222232903p:plain
 これから構築する難易度表の構成は上図のようになります。難易度表のトップページとヘッダファイルは、従来通り任意のWebサーバ上に置きます。
 データファイルについては、まず難易度表管理者がGoogleスプレッドシート上に情報を入力して、シート形式で保持しておきます。次に、REST APIが叩かれたときにJSONに変換してデータ情報を返すようにします。
 RESTとはWebアプリケーションの形式の1つで、HTTPのリクエストに対してサーバ側で処理を行い、レスポンスで必要なデータを返すようなモデルです。REST形式で用意されたWebアプリケーションのメソッド群をREST APIと呼びます。詳しくは他のサイトを参照してください。

Googleスプレッドシート

 ブラウザから操作でき、他の人と同時編集が可能なオンライン表作成ツールです。基本的にExcelと操作は同じです。難易度表を管理するときにこのツールを使います。
www.google.com

Google Apps Script (GAS)

 同じく、Googleが用意しているWebアプリケーション作成ツールです。言語はJavaScriptですが、HTTPリクエスト時に呼び出される関数も既に用意されています。また、Googleスプレッドシート内にスクリプトを埋め込むことができ、シート内の情報に容易にアクセス可能です。
 今回はGASで「スプレッドシートからデータをJSON形式に変換する」機能と「REST APIが叩かれたらJSONを返す」Webアプリケーションを実装してみます。
developers.google.com

【システム構築】スプレッドシートREST API

Googleスプレッドシートでテーブル情報作成

 シートを新規作成し、難易度表に必要な情報+任意で欲しい情報を付け加えます。2つ以上の譜面を登録する場合は、カラムそのままで1つ下の行に追記していってください。難易度昇順でソートされているのが好ましいです。
f:id:zatsuzatsu:20171221021023p:plain
 上画像の中で使用しているパラメータはこんな感じです。levelとmd5は必須事項で、他は任意です。データ型は、後述するGASのアプリケーション内で全てString型に統一されるため、気にする必要はありません。

必須 カラム名 概要
level 譜面の難易度
md5 譜面のファイルハッシュ値(md5)
lr2_bmsid IR上で割り振られたID
title 楽曲タイトル(+譜面特有の名前)
artist 楽曲制作者
url 楽曲のダウンロードURL
url_diff 譜面のダウンロードURL
comment 注釈等

 

Googleスプレッドシートの公開

 一通り難易度表の情報を書いたら、Googleスプレッドシートを公開します。「ファイル」->「ウェブに公開」を選択後、以下の赤丸のところをクリックします。
f:id:zatsuzatsu:20171221022956p:plain
 また、スプレッドシートのIDは後ほど使うので、URLからIDを拾ってください(下図参照)。
f:id:zatsuzatsu:20171223000906p:plain

GASのエディタを開く

 次に、「ツール」->「スクリプトエディタ」を選択して、GAS(Google Apps Script)をのエディタ画面を開きます。
f:id:zatsuzatsu:20171221023302p:plain

スクリプトの作成

 エディタにはデフォルトでコード.gsという何もしない関数が用意されたファイルがあるかと思います。そのファイルに、以下のソースコードをコピペしてください。なお、ssIdとsheetNameの初期化は作成した各Googleスプレッドシートの情報に基づいて適宜埋めてください。

  • コード.gs サンプル
/* --------------------------------
 GETメソッドのエントリポイント
--------------------------------- */
function doGet(e) {
  var ssId = "~~~~~"; // GoogleスプレッドシートのID
  var sheetName = "~~~~~"; // シート名
  var data = _getData(ssId, sheetName);
  if (e.parameters.hasOwnProperty("callback") == false) {
    return _createContent(null, data);
  }
  return _createContent(e.parameter.callback, data);
}

/* --------------------------------
 シート内の難易度情報をJSON形式に変換
--------------------------------- */
function _getData(id, sheetName) {
  const sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);
  const rows = sheet.getDataRange().getValues();
  const keys = rows.splice(0, 1)[0];
  var obj = {};
  return rows.map(function(row) {
    row.map(function(item, index) {
      obj[keys[index]] =  item.toString();
    });
    return obj;
  });
}

/* --------------------------------
 レスポンス内容の生成(JSON/JSONP対応)
--------------------------------- */
function _createContent(callback, returnObject) {
  if(callback != null) {
    return ContentService.createTextOutput(callback + '(' + JSON.stringify(returnObject) + ')').setMimeType(ContentService.MimeType.JAVASCRIPT);
  } else {
    return ContentService.createTextOutput(JSON.stringify(returnObject)).setMimeType(ContentService.MimeType.JSON);
  }  
}

Webアプリケーションの公開

 スクリプトを作成(コピペ)したら、上記メニューから「公開」->「ウェブアプリケーションとして導入」を選択してください。
 その後、下図のように設定して公開ボタンを押すと、Webアプリケーションが駆動して、かつ公開されます。
f:id:zatsuzatsu:20171223001923p:plain

 
 WebアプリケーションのURLにひとまずブラウザからアクセスしてみると、例として以下のようなJSONが得られます。(場合によってはダウンロードされたり、場合によってはブラウザに表示されたりします)

[
    {
        "level": "12",
        "md5": "3bcd7327066ff5872d414ec6d72d841a",
        "lr2_bmsid": "254795",
        "title": "YInMn Blue [CHAOS]",
        "artist": "siqlo",
        "url": "http://manbow.nothing.sh/event/event.cgi?action=More_def&num=220&event=116",
        "url_diff": "https://www.dropbox.com/s/4x3o85nvn81ln63/yinmn_ox_bms.zip?dl=1",
        "comment": "停止・ソフラン"
    }
]

 levelとmd5の項目だけしっかり格納されているのを確認してください。なお、万が一予めIRに登録していなかった場合、後ほどの難易度表読み込み時にエラーが起こるので、気をつけてください。
 

【構築】Webサーバ

 次にWebサーバに難易度表のヘッダと、読み込み用htmlファイルを用意します。

ヘッダファイル(*.json) の作成

 data_urlは前述したGASWebアプリケーションのURLです。name, symbol, data_urlはMUSTですので、漏れなく記述してください。level_order(難易度のソート)はオプションですが、ないと表記時のレベル順序が保証できなくなるため、つけておいたほうが無難です。

{
    "name": "CHAOS難易度表",
    "symbol":"混沌",
    "data_url":"https://script.google.com/macros/s/AKfycbzD5km1Uegw2NTA2Ncr-KZk663JQPKrnYS_-C8lcqwGovJhHGo/exec"
}

難易度表ページ(*.html)の作成

 今回は、最低限難易度表読み込みができることだけを考えて実装します。head内にヘッダ部への参照(URL)を埋め込みます。それだけなので、ブラウザには何も見えません。前述したGASのWebアプリケーションを叩いて、動的にテーブルを生成することで難易度表を可視化することが可能ですが、それを含めると話が長くなるため今回は割愛します。

<html>
    <head>
        <meta name="bmstable" content="http://zatsuzatsu.sakura.ne.jp/chaos-table/header.json"/>
    </head>
</html>

 最後に、ヘッダ部と、難易度表ページをどこかのWebサーバ上にアップロードして公開してください。その後、導入支援ソフトで読み込んで確認してみてください。問題なく読み込めたら構築は完了です! 後はシートの中身を変更するだけで、難易度表の更新ができます。

サンプル

 試しにBeMusicSeeker等で読み込んでみてください。
 ※ブラウザからだと何も見えません。
http://zatsuzatsu.sakura.ne.jp/chaos-table/

注意

 本記事で紹介した構成は、一見便利そうですが、スプレッドシート+GASには以下のデメリットがあります。

  1. アクセスする度にシートからJSONへの変換が走るため、レスポンスまで時間を要する。
  2. 管理者が編集中にアクセスされるとエラーが返ってくる・難易度表として読み込まれない可能性有

 レスポンスの遅さは寛大なプレイヤー様に許してもらいましょう。
 同時アクセス時の難易度表の読み込み失敗は、保存を意図したタイミングで行って回避したいところですが、スプレッドシートの自動更新の変更方法が不明なので、物理的な解決方法は今のところなさそうです。。。せめて更新タイミングを事前に告知しておくぐらいが関の山かと思います。

おわりに

 Googleスプレッドシート+GASで難易度表の管理をしてみる記事でした。快適な難易度表ライフをお楽しみください。
 これからも雑雑とよろしくお願いします。

おまけ

 今回作ったCHAOS難易度表に登録したBMS第一号

[BMS PLAY] YInMn Blue [CHAOS]
 混沌12です。

DAWソフトSonar終了。。。でもしばらく使う

悲しいことに、今まで愛用していたDAWソフトのSonarシリーズが開発・販売中止になった。
ただし、サーバ運用は継続するらしいので、すぐに使えなくなったわけではない。

www.cakewalk.com

X1でSonarデビューしてから早6年。
今年の9月にPlatinumバージョン買って、「X1より使い心地が良い!」と喜んでいた矢先の衝撃発表。
Sonarは、ソフト自体は上出来だったのに、周囲の環境(Gibsonとか、Gibsonとか、TASCAMとか)が残念だったとしか。。。


もともとSonarの権利を持っていたローランドは、その権利をGibsonに委譲したわけだが、Gibsonは以前にもDAWソフトを潰した前科持ち。。。
ローランド、「SONAR」などのCakewalkをGibsonに譲渡。「TASCAM」ブランドに - AV Watch

ローランドは「市場ニーズの変化等により、当社グループの中においてCakewalkの継続的な事業拡大は難しい状況にある」として、同社が進めている事業構造改革の一環として、「事業拡大を進めるGibsonの下で事業運営を図ることがCakewalkの成長・発展に寄与する」と判断。

皮肉にも事業拡大を進めるGibsonの下でSonarは打ち切られました。


突然の発表の中、
「そもそもSonarを信用していなかったユーザ」は、既にCubaseとかFL Studioに移住しているらしい。

使えなくなったわけではないので、しばらくは使い慣れたSonarを使って楽曲制作していくつもり。
よく落ちるが良いDAWソフトだ。

ブログに苔が生えたので「Spirea」で一新してみた

何かとtwitterで情報発信をするのと、三日坊主な性格が災いし、著者に放置されてすっかり苔が生えてしまったこのブログ。
今回は新鮮さを求めてブログのデザインを変えてみた。

カスタマイズ性が高い「Spirea」

www.ituore.com
Spireaは今どきかつオリジナリティ溢れるブログデザインを、簡単に作れてしまうテーマ(フレームワーク)である。
とにかく、ドキュメントが充実しており、上記で紹介したSpireaのページでは、やりたいことの逆引きがほぼ網羅して実装方法を紹介している。どこの項目にもスタイルシートが記載されており、これをコピペしてはてなブログCSSを編集するだけで、簡単に今どきのブログデザインを実現できる。

おわり

f:id:zatsuzatsu:20170303203914p:plain
著者も半ば何も考えずソースコードをコピペしていたが、気づいたらこんなデザインになっていた。
現段階ではコピペだらけだからオリジナリティ0だが、見やすいデザインは達成していると思える。

twitterの利便性にハマってしまい、もはやここは廃墟寸前だったが、
今回はSpireaの力でなんとかブログを新鮮な感じにすることができた。

今後も低頻度の更新になりそうだが、
140文字で収まらない話題はたまにここに書き込もうかと。

サイトを大改造:Barba.jsを導入してページ遷移を高速化

はじめに

最近は1つのWebページにヘッダ、フッタ、メインコンテンツ、サイドバーとたくさんの情報を詰め込むため、何かと容量がでかくなる。すると、いちいち別のページに映るたびに、メインコンテンツ以外の共通している要素を再度読み込みなおす必要があり、全体の読み込みの遅さに影響を与える。Barba.jsを使うと、余分な読み込みを省き、更新が必要な箇所だけを置き換えてくれる。今回は、Barba.jsの最低限の実装を行う。

続きを読む

【覚書】PMSをキーボードで遊ぶときの同時押し(3個同時押し編)

はじめに

PMSという9つのボタンをタイミングよく押して演奏する音楽ゲームが一部の界隈で流行っている(テンプレ)
最近アナログコントローラがぶっ壊れて、PMSをキーボードで遊ぶようになったが、殆どのキーボードは全ての入力を同時に受け付けてくれない。なので、そういう入力が求められるときには、スライドするように一瞬キーを押して離して別のキーを押下するというテクニックが求められる。
面倒くさいのは、同時押しの組み合わせが多いことだ。対応・非対応をいちいち覚えきれないので、うっかりして対応していない同時押しを押してしまうことがある。

今回は、気軽に遊べるキーボードのPMSにおける同時押しの対応・非対応を調べ、覚書を残してみた。
シリーズを予定していて、最初に3個同時押しを調べたあと、4個同時押しを調べる。5個以上の同時押しは調べるかどうか未定。

対象読者

  1. キーボードでPMSを遊んでいるプレイヤー
  2. キーボード向けPMS譜面を作りたい製作者

環境

キーボード

・ELECOM TK-FCM077PBK
USBを経由して有線で接続する
www2.elecom.co.jp

キー配置

BMSで一般的なボタン配置(zsxdcfv)をベースに右側に2個キーを追加した。また、ボタンの呼称については、左から1,2,...,9と番号で呼ぶことにする。
f:id:zatsuzatsu:20161002205805p:plain

3個同時押しの検証

赤:押せなかった(NG)
灰色:押せたけど、某コントローラだと無理押しの括り
f:id:zatsuzatsu:20161002210501j:plain

1+2+α,1+3+α,3+4+α,3+5+α

3個隣接を除いてほぼ押せる。

塊(隣接3個)の同時押し

1+2+3等の隣接した3つの同時押しは、7+8+9しか対応しない。手痛い。

α+7+9の同時押し

メジャーな同時押し1+7+9、3+7+9、5+7+9がNGなので手痛い。他はOK

2+4+αの同時押し

3を除いて全て網羅

4+6+αの同時押し

α=1,2,3はOK。α=7,8,9はNG。

α+6+8の同時押し

2+6+8、4+6+8といった上段3個同時はことごとくNG。なので、これを含む4個同時押し(代表例:2+4+6+8)もNG。

まとめ

普遍的に用いられる同時押し配置の大半がキーボードで叩けないため、キーボードで遊ぶときは、3つ以上の同時押しにすごい神経を使うことになる。解決策として、

  1. 他のキー配置を試す
  2. スコアを代償にして同時押しではなくスライドとして処理
  3. 全押し可能なキーボードの購入

などが挙げられる。次回はこの情報を基に4つ同時押しの調査を行う。

BOFU2016の差分をいっぱい作るゾイ

EC2でBemuseの楽曲サーバを構築してみた

はじめに

BMSと呼ばれるフリーの音楽ゲームが、一部の界隈で流行っている。
今までにBMSを数十作ぐらい作ってきたが、BMSを遊ぶには、本体をインストールして、曲もダウンロードして、読み込まして、と結構面倒くさい。
その中、最近できたBemuseは、面倒くさい導入の作業をスキップして、ブラウザですぐにBMSを遊ぶことができる。
Bemuse: BEAT☆MUSIC☆SEQUENCEbemuse.ninja

Bemuseは、どこかのサーバに本体があって、どこかのサーバに置かれている楽曲データを読み込んでいる。楽曲データをこちら側で用意すれば、すぐ遊べる環境ができる。今回は、EC2でサーバを構築して、Bemuseで遊べる環境を構築した。

続きを読む

youtubeで見つけたレコメンド曲紹介

youtubeを徘徊してたら数曲印象的なの見つけたので紹介。

TRNDSTTR (Lucian Remix) / Black Coast


Black Coast - TRNDSTTR (Lucian Remix)
エフェクトが強烈だけど綺麗に聴けるオシャンティな良曲。

にちようび / ジッタリン・ジン


ジッタリン・ジン - にちようび
琉球音階を突き通した曲。
歌詞の至る所に「ダーリンラムネを買ってきて二人で飲みましょ散歩道月が昇るまで」という魅了的な句とメロディがあり、聴いたあともしばらく脳内で流れるぐらい印象に残った。

予定調和の毎日 / 鈴木結女


Dina Giga OP
超起動伝説ダイナギガというOVAのOP曲。
楽器編成がコンパクトだから、質素に聴こえるけど不思議と高揚される。