初音ミク project miraiで不具合〜ルーム開放判定がスリープで不正確に

売上好調なニンテンドー3DS。その3DS向けタイトルとして発売前から注目されていたタイトルとして初音ミク project miraiがあります。

初音ミク and Future Stars Project mirai ぷちぷくパック(限定版) - 3DS

初音ミク and Future Stars Project mirai ぷちぷくパック(限定版) - 3DS

ねんどろいどミクの可愛らしい造形に立体視ということで自分も注目し、去年の東京ゲームショウでも体験プレイをしていました。

東京ゲームショウ2011 体験プレイ・イベントレポート - わぱのつれづれ日記

ただ、ソフトとしては値段が1000円程度しか変わらずねんどろいどぷちが付いてくる「ぷちぷくパック」の予約に出遅れてしまい、通常版を買う気も起きなかったため発売日はスルー。ただ、先日電撃感謝祭の際に秋葉原に行ったところ、たまたまぷちぷくパックがソフマップで6180円とお手頃価格で売っていたので購入しました。

ざっとプレイしてみた感想としては、一曲一曲のPVはすごく丁寧に作られており、ゲーム部分も慣れてくると体験版よりは楽にスコアを稼げるようになってきたのですが、やはり知らない曲も多く、一曲あたりがフルコーラスで長いためちょっと間延びするのが気になりました。現状は一通りプレイしてエンディングを見た、という状態です。

さてそのmiraiですが、やりこみの特典として「ルームデザイン変更」というのが開放される、というのがあります。自分はこのルーム開放が出現しておらず、まだエンディングを見た程度だったのであまり気にはしていなかったのですが、ネットではすぐに開放できる人となかなか開放出来ない人と意見が分かれているような状況で、不思議がられていたところがありました。それが今回、正式にソフトの不具合であるとセガからアナウンスがあったようです。

スリープ時間がマイナス値として蓄積されてしまう不具合

具体的な不具合の説明は以下のとおり。

他のルームデザインが選べるようになる条件は、次のとおりに設定されています。

① 30以上のお知らせが「おしらせ」タブに届いており、
② かつマイルーム画面を累計1時間以上表示させた
(※ただし、スリープやHOMEボタンによるポーズ中の時間を含まない)
しかしながら、マイルーム画面を表示中にニンテンドー3DS本体のフタを閉じてスリープモードに入った場合、解除後に一旦他のモードに移動してから再度マイルームに戻ることなく電源をオフにしますと、スリープ中の時間が②の累計時間より引かれた状態でデータ保存されてしまいます。
(スリープモード以外にも、HOMEボタンを押してHOMEメニューを表示している際も同様の動作となります)
初音ミク and Future Stars Project mirai

非常に分かりづらいですね。かなりプログライング的な不具合をむりやり普通の言葉で説明しようとするから難しくなっているきがします。ソースコードで示した方が、分かる人には一目瞭然な気もします。

プログラミング的に見た不具合の考察

今回の不具合を、C言語を例に少し推測してみました。以下にその推測を示します。

  • 累計の経過時間の累積値計算に用いる値Aを、unsigned(符号無し・正のみ)でなくsigned(符号有り・正負)で定義していた(ex. int A)
    • 無宣言はC言語仕様上「signed」扱い
  • 現在のルーム経過時間Bもsignedとしていた(ex. int B)
  • スリープ期間の時間は、現在の経過時間Bからマイナスするようにしていた(ex. B = B - sleeptime)
    • この段階でBがマイナスの値になる可能性あり
  • その経過時間Bを、累計経過時間Aに単純に足し算していた (ex. A = A + B)
    • これによりAもマイナスの値になる可能性発生
  • いずれの演算でも負の値になるエラーチェックをしていなかった

バグとしては、上記推測通りであるとするならちょっとお粗末なものです。そもそも経過時間の計算にsignedの変数を使う意味がありません。それを使っている(もしくはunsignedの定義が無い)時点で、プログラマの変数型に対する認識の甘さ・未熟さが伺えます。(←unsignedに負の数代入するとむしろ問題が面倒になりそうですね。signedで演算後負の値チェックの方がよいのかも。)また、こうした「時間経過で要素開放」というのも、通常だと単なる累計プレイ時間を使うことが多いのですが、ルーム時間限定でそのルーム起動時間の数字が眼に見えないものだったのも、今回のようにバグ発覚に時間がかかった原因ように感じます。裏の数字がおかしくなっていることに、だれも気がつかなかったと。

今回のバグにより、長時間スリープ時間にしていると、その時間が全て「負の数」として累積されてしまう可能性があるようです。つまり、毎日プレイ後にHP告知にあるような状態でスリープして一晩、また翌日も同様、とかやっていると一日あたり8時間とかのレベルでマイナス積算されていくことに。問題の解決法として、「ルーム開放までスリープを使わず、ルーム画面で起動しっぱなしにすること」と言われていますが、人によると数日つけっぱなしにしなければならないほどマイナス値がたまっている可能性があります。毎日こまめに音ゲーのみプレイしていた人ほどはまりそうですね。

またリリース前に検出できなかったのも問題ですね。おそらくテストでは「1時間経過してルームが開放されること」のみがチェックされていたのでしょう。スリープ関連は、そもそも検査項目から漏れていたんじゃないでしょうか?プログラミングレベルの高い人がコード自体をチェックしていれば気づいたのかもしれませんが、おそらくそういった工程も取っていなかったのではないかと推測されます。

結局はまたユーザーに負担を強いる形に

今回の問題も、おそらくコードの修正としてはほんの数行で済むような内容でしょう。ただ、3DSではパッチが現状当てられない以上、修正内容の規模の問題ではありません。単純に、その不具合のしわ寄せが恒久的にユーザーに来るわけです。

ルームに戻って終了する、というのは自分も普通にやっていた手順です。他のメニューに移動したりセーブのタイミングによってはスリープの時間がクリアされることもあるようなのですが、HPを見ても非常に分かりにくい状態。ルーム開放というのが一応隠し要素だったために弊害が大きくなっていたわけですが、とりあえずユーザーとしてはおしらせが30たまったらさっさとルーム画面で放置してルーム開放してしまう、もしくは終了するときはHOMEに戻った後面倒でも「おわる」を押してソフトを終了させる、という手続きが必要そうです。このお知らせを見ていない人だと、今後も知らないうちにルーム開放条件をどんどん厳しくしていってしまう人が出ていってしまいそうです。

もっとしっかりとした品質チェックを

今回は、進行が止まるという不具合では無いのですが、本来であれば楽しめる隠し要素が全然出てこなくなる可能性があるということで、結構深刻なものだと思います。だからこそセガもこうしてイラスト付きのページを作っているわけですし。

今の時代、バグ無しのソフトを作るというのは相当大変なことでしょう。3DSに限らず、PSでもいろいろ不具合が出ています。ただパッチで解消できようとできまいと、不具合を残したまま市場に出せば、不具合がある間はユーザーには不快な思いを強いり、メーカーもこうした告知や修正、最悪回収などで余計なコストが発生するわけです。パッチがあった方が回収という最悪の事態をメーカーは回避しやすいというのはあります。ただ、ダークソウルのオンライン不具合みたいに発売日からしばらくの間オンラインがまともに遊べないとかは、たとえ直せたとしても発売直後の一番脂ののっている時期にプレイできないというのでは問題は大きいと思います。

メーカー側も現状でも最善を尽くしているつもりではあると思うのですが、結果的に不具合がいろいろ出てきている以上、よりしっかりとした品質チェックを行うようにして欲しいですね。不具合検知には時間も人も非常に掛かるもので、経営者としては頭の痛い問題かもしれません。ケースバイケースのところはあるのは事実ですが、最終的に何が消費者のためになり、それが将来どうメーカーの利益となるか、そういった視線でのビジネスを期待したいところです。