2018年2月3日土曜日

東方VGS(iOS)コードレビュー① AppDelegate

先日OSSとして公開したiOS版東方VGSのアプリ実装を眺めつつザックリと解説するシリーズ。(シリーズが続くかは不明)
本稿は、iOSアプリケーション開発経験者ではなくても意味が分かるように書いていき、最終的にはiOS版東方VGSの全体的な作りが何となく分かるようになることを目標にしています。
第1回の今回はAppDelegateというiOSアプリの一番根っこの部分で何をやっているかを見ていきます。

↓このソースの解説
https://github.com/suzukiplan/tohovgs-ios/blob/master/Touhou%20VGS/VGSAppDelegate.m

(1) AppDelegate(起動時の処理)

iOSアプリの場合、起動が完了するとAppDelegateのdidFinishLaunchingWithOptionsが呼び出されます。(もっと正確に言えば他のUNIXプログラムと同様main関数から起動して、そこでAppDelegateが登録されます。そして、iOS側の制御でアプリの起動処理が完了した時にdidFinishLaunchingWithOptionsがコールバックされます)
https://github.com/suzukiplan/tohovgs-ios/blob/71464aae09f107fbf02e9ce1989d9bfb80381e37/Touhou%20VGS/VGSAppDelegate.m#L23

そこでやっていることは大まかに、
・ViewControllerの登録
・OpenALの初期化
・AudioSessionへのproperty-listenerとinterruption-listenerの登録

ViewControllerはAndroidで言うところのActivityやFragmentのことで、アプリのViewを制御するコードを書きます。ViewとControllerが登場したということは、Modelを作ってMVCのデザインパターンで設計すべしと考えるのが普通ですが、東方VGSはMVCとかそういうデザインパターンでは作っていません。もちろん、DDDとかそういうモノでもなくて、デザインパターン的には好き勝手に作っています。一人でプログラミングする場合、それが一番生産性が高い。

OpenALは音を再生する為に使っています。普通音を再生するにはAudioPlayer等を使いますが、東方VGSの場合、VGSが音声を発生する装置をエミュレーションしてパルス符号データを時系列に吐き出し続け、それを拾って再生するのでAudioPlayerよりも波形を逐次直書きできるOpenALを使っています。(Androidの場合はOpenSL/ESを使っています)

AudioSessionのproperty-listenerは、kAudioSessionRouteChangeReason_OldDeviceUnavailableというハードウェアイベントを拾う為に登録していて、これは、ヘッドセットがデバイスから外された時に発生するイベントで、これを検知した時に音声の再生をポーズするために使っています。これは、アプリ公開後にユーザからそういった要望を受けて実装しました。(iTunesがそういう仕様だったらしく、東方VGSも同じ仕様だと思ってしまったのだとか。学校の休み時間に東方VGSを聴いて授業が始まる時にヘッドセットを抜いて仕舞ったところ、授業中にうっすらとBGMが流れてしまうハプニングがあったと伺ったので、申し訳なく思って速攻で実装しました)
https://github.com/suzukiplan/tohovgs-ios/blob/71464aae09f107fbf02e9ce1989d9bfb80381e37/Touhou%20VGS/VGSAppDelegate.m#L72

interruption-listenerは、東方VGSのオーディオセッションに対して割り込みが発生した時にアプリを停止させる処理を実行しています。これは、バックグラウンドで再生中に電話が掛かってきたり、別の音楽アプリ(iTunesなど)を起動した時にアプリが動き続けると煩わしいので、それなら止めた方が良かろうということで実装しました。この影響で一部アプリ(オーディオセッションを奪うアプリ)とは共存できないという仕様になりました。この仕様については、アプリ公開中に一部ユーザから不満を言われていたので、直せばもっと高い評価が得られたかもしれません(ちなみにiOS版のレビュー評価件数は最終的に、DL数約20万に対して5千件ほどで平均4.8ぐらいでした)が、逆に治してしまうと電話が掛かってきた時にアプリがちゃんと止まってくれるか分からなかった(開発当時はiPhoneではなくiPod touchしか持っていなかった)ので、怖くて修正できなかったと記憶しています。
https://github.com/suzukiplan/tohovgs-ios/blob/71464aae09f107fbf02e9ce1989d9bfb80381e37/Touhou%20VGS/VGSAppDelegate.m#L84

(2) AppDelegate(バックグラウンド関連)

バックグラウンド関連での処理もAppDelegateで行われますが、ココでやっていることはバックグラウンドに入ったフラグのON/OFFぐらいです。
https://github.com/suzukiplan/tohovgs-ios/blob/71464aae09f107fbf02e9ce1989d9bfb80381e37/Touhou%20VGS/VGSAppDelegate.m#L104
https://github.com/suzukiplan/tohovgs-ios/blob/71464aae09f107fbf02e9ce1989d9bfb80381e37/Touhou%20VGS/VGSAppDelegate.m#L119
後付で、音楽がプレイ状態でない時にバックグラウンド遷移する時はアプリをexitするようにしました。(その方が若干程度ではありますが電池が節約できたので)

もっと淡々と書こうと思ったのですが、コードの1行1行にそれなりに思い出が詰まっているので、全然淡々としていないな。

2018年1月21日日曜日

iOS版東方BGM on VGS(再公開)

iOS版の東方VGSを再公開しました。
ただし、AppStoreではなくGitHubでOSSとして。
https://github.com/suzukiplan/tohovgs-ios

※お手持ちのiPhoneへインストールするにはMac+XCODEが必要になります

流石にこれではあんまりなので、代行公開をOKにしようかとも考えたのですが、様々なリスクが考えられるのでそれについては原則NG(正確には事前許諾が必須)としています。

ImageViewで色を乗算方式で変える方法(programmatically)

AndroidのImageViewで色をプログラム的に変えたいと思って調べると、だいたい「元画像が単色」の場合の変更方法しか出てこない。マテリアルデザインの場合、原則アイコンは単色(tint-color)でデザインするのが基本だから仕方ないですね。

ここでは、元画像が複数色のものを全体的に色調を変える方法を書きます。
オリジナル ⇒ 全体的に色調を変更
(素材はいらすとやから借用)
ImageView#setColorFilter を使えば色を変更できるらしいという情報は、ググれば沢山出てくるのですが、全体的に色調を変える場合は、第二引数のModeに PorterDuff.Mode.MULTIPLY を指定してあげるだけで良いです。

上図のような全体的に緑がかった感じにする場合は、

imageView.setColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY);

でOK。

実際にAndroid上で動かせるようにしたものをGitHubにアップロードしておきました。
https://github.com/suzukiplan/ImageViewTest

2018年1月14日日曜日

音ゲーの譜面を暗譜する方法

ガルパにせよデレステにせよ、音ゲーの譜面を暗譜するのはほぼ無理だと思っています。

音ゲーなんかより遥かに鍵盤数が多いピアノの暗譜なんて人間技じゃない・・・という風に思うかもしれませんが、ピアノの暗譜は音ゲーのそれと比べると遥かに易しい。
ピアノに限らず楽器全般の暗譜は、楽譜を完全に脳内にコピーしている訳ではなく、単に脳内で音を再現できる状態に過ぎないので。
「脳内で音を再現できる状態」とは、例えば、好きな歌を鼻歌でふふ~んと歌うことができる状態のことを言います。(これなら誰でも出来るはず)
そして、楽器演奏は音に紐づく動作を繰り返す運動行為(例えばギターなら一番低いEの音であれば、フレットを抑えずに1弦を弾くといった感じ)で、鳴らしたい音に紐づく動作が記憶できていれば、脳内で再生している音楽に対応づく動作パターンへの変換を行うだけで暗譜演奏ができるという事になります。(実際に楽器をやってみると分かることですが、これは想像するよりも遥かに簡単に誰でも出来ることです)

スマホの音ゲーで暗譜がほぼ無理な理由は、楽譜自体の形を暗譜しなければいけない為です。もちろん、出来ている人も居るかもしれませんが。(速度1でフルコンできるタイプの人は恐らくそれです)

ゲーム側に次のようなオプションがあれば、暗譜が簡単に出来るようになる筈。

(1)FX音のPANを左側と右側で変える
※FX音 = タップやスライド等で鳴る音のこと

こうすることで、音と動作(左の方を叩くとか右の方を叩く)を紐付けて記憶できるようになるので、音による暗譜が可能になります。

(2)FX音の音程を左側と右側で変える

左側の音程=低い、右側の音程=高いという感じ。
ただし、曲によってはFX音と合わなくなる可能性があるかも。
(その代わり(1)だけの場合と比べて圧倒的に記憶し易くなる筈)

なんでデレステにもガルパにもそういうオプションが無いのか?(特許絡みの何かがあるのか、あるいは単純に開発会社にそういう発想が無いのか)

まぁ、アプリの改修なんて期待してもしょうがない(こうしてネットで晒しておけばワンチャンあるかも程度の期待は無くはない)ので、ローカルフィックス案も一応あります。
それは、
①イヤフォンは使わない
②FX音をoffにする(アプリ設定)
です。
物凄くアナログですが、要するリアル打鍵音でプレイ。
これなら(1)はアナログ的に何となく実現できます。
まぁ、かなり微量ではありますが0とnone 0の間には大きな隔たりがあることを実感できるかと思います。
ついでに、デレステもガルパも実際にデバイスを叩いたタイミングと音が鳴るタイミングに微妙にズレがある(これは恐らく技術的には改修不可能だと思う)のですが、それも完全に無くなるというメリットもあります。

この分野を純粋に突き詰めていくと、曲の音声もOFFにするのがベストだったりする(完全なサイレントにすることでスライドのこすれる音も構成要素として成立するようになる)のですが、そこまでいくと「なんで、このゲームプレイしてるんだろ」という哲学的な感じになってきます。

2017年10月22日日曜日

スマホ時代の商業動画コンテンツ配信サービスについての簡単な考察

上図はNetflixのAppStore(アメリカ)での過去1年間のセールスランキング推移です。
もちろんガチャとかは一切無く、アプリ上での課金手段はサブスクリプション(定額課金)のみ。ガチャゲー一色の日本のセルランと違って、米国のセルラン上位はNetflix、Spotify、YouTubeなどのストリーミング配信系サービス(全てサブスクリプションの筈)が過半数を占めていて、ゲーム系ではクラクラ、キャンクラ、ポケモンとかぐらいでそれ程多くはありません。ちなみに、ストリーミング配信系以外の非ゲームだとTinder(出会い系)とかが強い。

Netflix補足:
・米国のオンラインDVDレンタル、ストリーミング配信会社
・1997年創業、1998年にウェブ上でのDVDレンタルサービスを開始
・2007年以降VODストリーミング配信を開始
・2002年からNASDAQに公開しているが2013年以降に急成長

株価の成長具合から見て、正にスマホ時代に当たった商業動画コンテンツ配信サービスって感じでしょうか。

日本ではいまいちパッとしませんが。

Netflixの日本のAppStore上でのセールスランキングは100位付近。日本の同業種の他サービスとしては、dTV、RakutenTV、USENなどがありますが、どれもパッとしない印象。海外のその他サービスとしては、Amazonプライムビデオ、Huluなどがあり、Amazonプライムビデオはそこそこ好評ですが、Huluに関してはdTVやRakutenTVと同程度といった感じ。

Amazonプライムビデオは「prime会員になっていれば棚ぼた的に無料で動画が見れる」ことが好調の要因なので、Netflixのような「商業動画コンテンツ配信サービスとしての成功」と同列で考えるのは違和感があります。

Amazonプライムビデオ以外で日本でヒットしている同業種としては、少し毛色が違いますがAbemaTVとかでしょうか。(なお、YouTubeやニコニコ動画といった主にUGCを扱っているものは除外してます)

AbemaTVのAppStore上でのランキングは200位ぐらい。主に広告で収益化しようとしているようですが、有料会員登録するとVODで見れるようになるので、AppStore上のランキング=Netflixと純粋に同一形態と見做せるかもしれません。Netflixと違って国内向けのコンテンツ調達は十分できているであろうにも関わらず、Netflixにすら勝てていないところが中々興味深い。

単純に品揃えが原因では無いことは確かなようです。
そもそも品揃えさえ良ければ客が付くのであればdTVあたりがもっとヒットしている筈

以下、推測ですが、
米国は国土が広い関係で電波を隈なく配信することが(最初期の頃は)技術的に困難だったためケーブルテレビ中心に発達してきた一方、国土が狭い日本ではインフラ的な事情を割と簡単にクリアできたので、早期から電波放送中心に発達し、その結果米国では「多様なチャンネルの中から好みのチャンネルを買う文化」みたいなものが定着し、方や日本では(電波配信の性質上、垂れ流し状態にせざるを得ないので)「CM付きのコンテンツを無料で見る文化」が定着したと考えることができます。

参考資料:海外におけるケーブルテレビ市場の動向(総務省)
http://www.soumu.go.jp/main_sosiki/joho_tsusin/policyreports/chousa/2010cabletv/pdf/060421_2_3.pdf
2005年末時点の米国でのケーブルテレビ世帯加入率は84.6%で, 減少傾向ではあるが平成18年時点でも約69%程度とのこと。
参考までに、日本でのケーブルテレビの世帯普及率は実は(全く実感が無いのですが)そこそこ高いのですが、第三セクターが介入していたりするものが含まれているらしく、普通の(多チャンネル放送の受信に対応した)ケーブルテレビの普及率に絞ってみると1千万世帯に届いていない程度のようです。
もちろん、これは最初期の頃の話しで、今の米国には当然ですが地上波放送もあってアンテナさえ買えば無料で商業動画コンテンツを見ることができますが、それでもケーブルテレビの人気には根強いものがあります。

黎明期〜普及期に掛けてヒットすると、それに関わる強力な利権構造(日本なら電通とか)が同時に生まれることで、普及期以降に新たな方式を採り入れようとしても市場から排除される「三つ子の魂は百までメカニズム」と呼ばれる(※私が勝手に呼んでいる)市場原理が生まれます。これが(やや端折りますが)、サブスクリプション方式では商業動画コンテンツ配信サービスとして日本で成功出来ない原因の根本であろうと推測しています。

AbemaTVの広告モデルで何とかしようとする手法は、この推測が正しければ正攻法かもしれません。なので、長い目で見れば上手くいくんじゃないかと思っています。
ただし、仮に上手くいったとしてもせいぜいテレビCMと同程度のコンバージョンしかない(※テレビCMは、母数がメチャクチャ多いからコンバージョン率が低くてもそれなりにペイできるものだと思っている)となると、仮に私が広告を出す側の人間だったら「それならテレビでええやん」と思ってしまいそうな気がする。インプレッション等の数字が正確に分かるようになる筈なので、金を払って広告出稿する側からすると曖昧な「テレビの視聴率」よりもシビアな判断を下しやすいことがメリットといえばメリットかもしれませんが、それってプラットフォーム側からするとリスクでしかないかも。(AdSenceみたいにコンバージョン率が高いとかなら話しは別ですが、既存のテレビをインターネットに持ってきただけではその点はあまり期待できないと思っている)

2017年10月15日日曜日

スマホ音ゲーの傾向

ガルパ、ミリシタ、歌マクロス、うたプリ、SideM、その他諸々。2015年末〜2016年にかけてデレステが好セールスを叩き出した影響か、今年はスマホ音ゲーの新作が続々と登場していますが、セールス的には、
・相変わらず強いデレステ
・地味にしぶといスクフェス
が「二強」といった感じで、新規は中々苦戦しているようです。
以下、各アプリ(iOS版)のセールスランキング(全アプリ総合)の推移を見ていきます。(ランキング推移はAppAnnieで確認)

(デレステ)

・強い
・今年に入ってから下降トレンドになったものの7月ぐらいから徐々に上昇トレンドに転じている
・ガルパ合わせでスライドを導入し、ミリシタ合わせでガチャ率を1.5%→3%に緩め、SideM合わせでスマートモード追加など、着実に新規を潰していく施策を実施できていることに加え、2周年記念で5日間10連ガシャを毎日1回無料といった大盤振る舞いな施策が功を奏した形か
・出戻り勢が多そう(私もその一人)

(スクフェス)

・地味に強い
・100位を割り込んだ時期もあったものの、そのまま落ちることなくそこそこの順位を保つ
・下降トレンドであることには変わりないが「底の強さ」みたいなものが感じられる

以下、これら2強に仕掛けた新規勢を見ていきます。

(ガルパ)

・概ね好調(反発ライン=100位前後)
・ただし、上位キープは出来ていない(新規ガチャ実装→そこそこ上位へ上がる→すぐに落ちている→新規ガチャ実装...の繰り返しで、それは他のゲームでも同じだが、デレステと比べて上位定着期間が短い)
・楽曲コンテンツの追加ペースが早いものの、中長期を見通した運営プランができていないのか、追加コンテンツとイベントが上手く連動出来ていなかったり等の運営面での舵取りの甘さが目立つ
・このゲームの差別化要素は、他音ゲーと比べてゲーマー向けに寄せている点で、それが(アニメが成功しなかったにも関わらず)ヒットできた要因だと思われるが、その半面、この路線だと新規顧客獲得に苦戦することになる(ゲーマー向けに寄せれば寄せる程、かつての格闘ゲームやSTGなどと同様のタコツボ化状態になるので新規から敬遠されるようになる)
・実際、新規流入が8月にドカッと入っている(OVAの地上波+AbemaTVでのOA or ブーストだと考えられる)が、その後セールス的には9月初旬に過去最低を記録していることから、新規顧客の定着化に難がある事が数値的にも浮き彫りになった

(ミリシタ)

・軟調(反発ライン=200位前後)
※図で見ると分かり難いですがガルパの概ね2倍下振れしています
・事前登録100万超えなど、リリース前の話題性はあった
・レビューを見る限り、コンテンツ追加ペースが遅く、イベントも盛り上がりに欠けていたことに加え、ゲーム本編が特に新規性が無かった事がユーザの不満を買った模様
・楽曲実装の遅さは、コンテンツ調達コストが相当重い事が要因か
・このゲームの最大の弱みは、デレステと比較した場合の差別化要素がキャラクタ(IP)しか無い点かもしれない

(歌マクロス)

・不調(200位圏外が安定しつつある)
・テコ入れが必要だと思われるが、ミリシタと同様コンテンツの調達コストが結構重そう(=楽曲コンテンツ数では勝負できない筈)だから、打開策としてはレアリティの投げ売りぐらいだと思われる
・このゲームで強くなるには、最高レアリティが9種必要で、しかも最高レアリティは最低でも同じカードが2枚無いとレベルMAXにならず、更に属性染めアリという具合
・考え得る限りの搾取ロジックが実装されており、その辺が課金慣れしたユーザから敬遠された(かどうかは分からないですが、少なくとも私はそこそこ遊んだものの1円たりと課金する気が起きず、完全無課金プレイでした)

(うたプリ)

・弱い(リリース初日10位以内に入れず)
・そもそも音ゲープレイヤーなんて8割は男なのに、何故女性向けコンテンツで作ろうと思ったのか(開拓を狙うにしても、中身がスクフェスと同じ=無策同然なので、それでは開拓なんて出来る訳もなく)

(SideM)

・弱い(リリース5日で100位以下へ落ち、2週間で150位を割り込む)
・そもそも音ゲープレイヤーなんて8割は男なのに(略)
・シングルレーンでゲーム性は完全に捨ててきているスタイルは、ある意味斬新かもしれないが、それならそもそも音ゲーにする必要が無いのでは...(パズルゲームなどの女性ウケの良い別ジャンルで攻めた方がまだマシだったのではないだろうか)
・音ゲーで女性向けマーケット開拓という牙城に無策で挑んだうたプリよりはマシかもしれないと思いきや、うたプリよりもセールス的には弱い(やっぱり、女性向けでもゲー無ではダメみたいですね)

〜〜〜〜〜

総括してみると、
(1) デレステより後の世代でのヒットの傾向としては、高難度化が好まれる傾向
 - 新規勢で唯一ヒットできたガルパだけがこの路線
 - 定着するユーザは(スクフェス/デレステ等の)経験者ばかりだと考えられる
 - つまり、順調にタコツボ化が進んでいる
(2) セールスを上げるのには蛸壺の住人が必要(特徴は下記)
 - 新奇性が無いと寄り付かない
 - IPではなくゲーム性を重視
 - 文脈を踏まえたものを提供しなければ叩かれる
 - ↑は、新規プレイヤから敬遠される要因にもなる
(3) IPは初期流入やメディアミックスしたタイミングで効果はあるが、継続率向上や転化行動の発生などには寄与しない(人気キャラクタ持ってくれば勝てる訳ではない)
(4) 課金慣れしているユーザは、搾取に対する警戒も強い
(5) 3D導入のインパクトはもう無い (コスト的に不利になるだけ)
(6) 女性向け市場拡大は(STGや格ゲーと同様に)性質上困難
という感じでしょうか。

正直なところ、ガチャゲーにうんざりしつつある。

2017年9月18日月曜日

プリペイドSIMから通常SIMに戻した時に「SIMなし」になる現象の解消方法

1週間ほど欧州方面へ行ってきたのですが、プリペイドSIM(コレ)を使ってみてかなり便利でした。
なんやかんやで一番助かったのがGoogleMapとGoogle翻訳が使えること。
あと、殆どのホテルにはWi-Fiがあったものの、有料だったり、無料だったとしても繋がりにくかったりと残念なものが多いので、iPhone(プリペイドを挿したSIMフリーのiPhone SE)のインターネット共有の方が安定的に通信できた印象。(それでも流石にガルパのマルチをやると途中切断がバリバリ発生しそうな程度の安定度なので、イベントは全てフリーライブで回すなどの配慮は必要でしたが)

ただ、帰国後に元のSIM(OCNモバイルONE)に付け替えてみたところ、「SIMなし」のまま変化しない現象が起きて若干焦りました。コレの原因は、ローミング設定が有効なままになっている為だろうと想像できたのですが、「SIMなし」の状態ではローミング設定を変更できないので、さてどうしたものかと。(これiOSの仕様不良じゃないかな)

小一時間ぐらい色々と試した結果、次の手順で無事解消できました。

[手順]
(1)「設定」→「一般」→「ネットワーク設定をリセット」
(2) 端末のアクティベートに使用したダミーSIMを挿してiPhoneを再起動
(3)「設定」→「モバイルデータ通信」で「通信のオプション」が「ローミングオフ」になるように設定
(4) ダミーSIMを取り出して元のSIM(OCNモバイルONE)に付け替える

これで復旧したので、もしかするとプリペイドSIMを挿した状態でローミングオフにしてから元のSIMに戻すだけも大丈夫そうな気がするのですが...(当然ながらそれも試したような気がするのですが、帰国後の体力を消耗しきった状態で弄っていたので何かミスっていたのかも)

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...