見出し画像

らぷりげーむExtreme

この記事はLa prière Advent Calendar 2023 25日目の記事です。
24日目はしゅんさんの「友人に布教し続けたら沼ってくれる説」でした。自分は布教の時に相手のYoutubeで曲を流すようにしているのですが、これで妹のYoutubeのランダムプレイリストの先頭が常に『君と話を』になりました。大成功です。


はじめに

こんぷりえ~る!
らぷりげーむ開発部プログラマーの、のぱふぃるです。
本記事ではらぷりげーむを遊び倒して、語り尽くします。

①DeadScream RTA理論値

『DeadScream』は人力で25秒を切るのは大変で、スタッフ記録ユーザー記録24秒です。23秒台は配置がよほど都合がよくプレイヤースキルもカンストしていないと無理でしょう。では理論値は何秒なのでしょうか?
チートプログラムを作って検証してみます。

①群衆の直前で最速(1フレーム)でさえぎりゅなを撃つ
②群衆ができるだけまとまるように乱数調整する
③できるだけ最高速度を維持する

ができればよいです。特に②について、群衆は6人1組で10列現れます。列ごとに出現する可能性のある範囲が決まっているのですが、運がいいと「1列目が範囲の最後、2列目が範囲の最初にいて、12人まとめてさえぎりゅなできる」ことがあります。今回は乱数調整してこれを常に起こし、1-2列目、3-4列目……9-10列目が、1フレームさえぎりゅな範囲内に隣り合って現れるようにします(なお、3列まとめてさえぎりゅなできる範囲に出現することはあり得ません)
棗いつきは加速力が高く、さえぎりゅな以外で減速もしないため、②を満たすと③が自動的に満たされます。
出来上がったものがこちらです。

※gifは倍速再生

ということで記録は21秒です。正確には内部的には(60FPSなので)1/60秒単位でカウントしており、1318フレーム(約21.97秒)でした。これが理論上最速です。

おまけ:人がいないと20秒。ちなみに道のりは1068mある
おまけ:竹下通りをさえぎりゅな

幕間:効率厨なゆた☆振り付け練習

上上下下左右左右BA

帝京平成大学が東京千葉に4つのキャンパスがあるように、『ラブリーアイドル』は「左」「右」「両方」の3つの矢印がありますが、実は振り付け差分は4種類(+失敗の5種類)あります。
これは同じ矢印が連続した時にもアニメーションに動きがあるようにするための工夫らしいです。また、アイドル衣装でなくThree piece!衣装を採用しつつ髪型はアイドル仕様にしているのは、それが1番ドット絵にした時にポーズが分かりやすかったかららしいです。
この辺りはリリースの2週間くらい前まで話し合いが行われており、担当プランナーとデザイナーのこだわりの結果、最高に可愛く仕上がったんじゃないでしょうか!

②デザイナーとDriven Star

リリースver
開発途中ver

『Driven Star』の開発話をします。
下のgifは背景素材とアニメーション素材を取り込んだ直後の、12月2日のバージョンです(リリースは1月22日)。
ゲームの動きは差がありませんが、リリースverの方が遥かに完成度が高いように見えます。何が違うのでしょうか?

①床の視認性が格段に上がっている
②一時停止ボタンが実装されている
③藍月なくるが空中で暴れてない
④背景の縦方向のスクロール速度が緩やかになっている
背景が近景中景遠景で別々の速度で動いている
です(gif外ではステージ改修やスタート位置修正も入っています)

①はパッと見で分かる改善ですが、実は⑤もとても効いています。どちらも担当デザイナーの折メ先生の大活躍により取り入れることが出来ました。
たしかに電車から外を眺めると、遠くの景色に比べて近くの景色は高速に流れていきます。この視覚特性に寄せるために近景と遠景で速度を変えるというのはアニメでもよく使われる手法らしいのですが、これはエンジニアだけではやれない改善です。
そもそも素材が作れないのはさておき、メンタルモデルとして「1枚絵として完成済みの背景をバラして別々に動かす」という引き出しがないんですよね。「1つのゲームワールドがあって、そこに背景と床は固定化されていて、車が自動スクロールでワールドを左から右に移動し、カメラが車に追従する」という風に世界が見えていて、その通りに設計しています。
これを「背景がバラバラに右から左に流れていく」となると、車を左から右に動かすよりも「車とカメラは固定で、背景と床が右から左に流れてくる。車は実はその場でジャンプしているだけ」という設計の方が自然になります。まさにコペルニクス的転回です。

これは設計を大幅に変更するだけでなくゲーム内の物理法則にも影響が及びます。
らぷりげーむはPhaser 3というゲームライブラリを使っていて、ジャンプ後の落下や衝突判定はPhaser 3の物理エンジンで比較的簡単に実装できるようになっています。しかし「背景はバラバラの速度で動いていて、車はその場で垂直跳びをしていて、地面が車に向かって動いてきて、車と床の摩擦係数は0で、床は車が落ちてきても下に動かないでほしいけど、接地判定はしたい」となってくると、これくらいシンプルなゲームでもかなり個別に制御する箇所が出てきます。

つまりエンジニアにとって「物理法則に反した方が良くなる」というアイディアは相当に思いつきにくいわけです。背景のそれぞれの速度の微調整も大変でした……。でも取り入れてみると明らかに良くなってますよね。
このように、ゲームとしてバグなく成立させるという責務はエンジニアが負っている一方で、世界観の作り込みとユーザ満足度にはデザインやBGMが多大な貢献をしています。両輪となって協力してドライブできたことにハ・ハロー High-Fiveですほんと。

実は『Flyby Anomaly』もPhaser 3の物理エンジンを使わずに実装されています。こちらは惑星同士の引力は無視したいとか、惑星にロケットが衝突したらロケットが反発してほしいとかあるので、万有引力の法則通りの世界をシミュレーションすると面倒そうですよね。担当プログラマが頑張って1から実装していました。

僕はリリース1ヵ月後に知りました

幕間:ちょっとだけお味見チャンス

『ふぁんはおれ』では最大5皿までの出題のため、店員のなくるさんに8皿持たせることは基本的にできません。
出題パート、クリア後、ラウンド切り替え中、一時停止中などはクリックが無効になっており、皿を押しても何も起こらないようにしています。
しかし実はクリア失敗判定直後はクリックや料理移動アニメーションが無効になっておらず、「FAILURE画像を表示し、クリックするとメニューに戻るようにする」状態まで500msの猶予があるため、この間に全ての皿をクリックすることでなくるさんにクライマックスフルコースを食べさせることができます。
(人力では500msで8皿クリックするのは難しいため、再現する場合はラウンド3の5皿目で間違えるのがオススメです)

ちなみに料理は「餃子」「ラーメン」「小籠包」「シュウマイ」「酢豚」「中華丼」「油淋鶏」「炒飯」の8種類です。
こちらは担当プランナーとデザイナーの油淋鶏へのこだわりです(*1)

*1:元ネタが気になる方は「藍月なくる ゆーりんちーのゆーりんちー」とかで調べると出てきます

③アルビレオを自動化する技術

回答パート
正解時に出るイラスト

『アルビレオ』は正誤判定プログラムは1度作ってしまえば使い回せるのでステージを量産できそうですが、作問がめちゃめちゃ大変です。

まず、星座の点を「お手本図」「回答図」「正解図」の3パターン人力で用意する必要があります。お手本図は実際の星座に忠実であればいいので頑張れば作れます。
一方で回答図は、星座そのままだと間隔が狭すぎて画面の小さいスマホでプレイすると誤操作が起こりやすくなる箇所があるため、誤操作が起きにくくするように座標を弄っています。また、正解図ではイラストの上に星が載るよう調整しています。

次に、そもそも「解ける問題設定」にする必要があります。例えばはくちょう座の場合、真ん中の頂点を通れる回数が2回以下だと解けません。これを自動的に判定する方法について考えます。
『アルビレオ』は頂点と辺からなるグラフと「各頂点は何回まで通っていいか」という制約入力として、制約を満たしながら全ての辺を通る経路出力する問題です。
これは一筆書きの拡張と解釈することができ、一筆書きの可否は(準)オイラーグラフの判定問題に帰着することが知られています(*2)。では『アルビレオ』も同様に判定できるでしょうか?
例えば、もしアルビレオ一筆書きルールでなく「各"辺"を何回通るか」という拡張であれば、辺を多重辺にすれば一筆書き判定に帰着します。
しかし、アルビレオでは「ある辺を通るために頂点を使ったら、別の辺を通ることができなくなる」という辺の間での依存関係があり得るため、単純に各頂点に繋がる辺の数(次数)だけを見て判断することは出来ないです。
したがって「コンピュータに実際に解かせてみて、解けたらOK」という方針でプログラムを組みます。

PythonのNetworkX, matplotlibを使用して可視化
参考:ゲーム内画面

まずはビジュアライザーを作ります。頂点の色と辺の張り方が本質なので、向きや角度は無視していますが、らぷりげーむのはくちょう座が出力されています。

ソルバーと入出力

次にソルバーを作ります。
全ての始点からDFS(深さ優先探索)をして、各頂点の訪問上限を満たしながら全ての辺を通れたら成功です。
右下の出力の最後の行が、ソルバーが見つけた回答経路です。「7 6 5 4 1 0 1 2 3 2 1 8 9 10」になっており、正しく解けていそうです。

7 6 5 4 1 0 1 2 3 2 1 8 9 10は正しい経路
ビジュアライザ改

確認しやすいように、ビジュアライザを改善しました。
左がお手本図で、右は頂点だけの状態からソルバーの出力「7 6 5 4 1 0 1 2 3 2 1 8 9 10」の通りに線を引いていく回答アニメーションです。たしかに解けてますね。

最後に問題ジェネレーターを作ります。
ランダムにグラフと各頂点の訪問可能上限を生成します。
実はこれが技術的には1番難しいです。
アルビレオ一筆書きするためには各頂点はどこかで繋がっている必要があり、このようなグラフを連結グラフと言います。
今回は「訪問可能上限をランダム生成→訪問可能上限から導ける次数上限を満たすようなPrüfer列をランダム生成→Prüfer列をに変換→木にランダムに辺を足す」という方法で連結グラフを生成します(*3)。

10頂点12辺

これでジェネレーター、ソルバー、ビジュアライザーが完成したので、その出力を順に繋ぐスクリプトを書くと、全自動で作問から回答まで生成できるようになりました。無限にアルビレオができます。

ここからの拡張として、たとえばジェネレーターを差し替えて「88星座の画像からグラフを生成して、訪問可能上限だけランダム生成して解けるかチェックする」とかもできますし、ビジュアライザーで各頂点の最低間隔を指定できるようにすることで「スマホプレイ時の誤爆を防ぐ回答図を自動生成」することもできます。
今回は技術的に一番チャレンジングなソルバーの改善をしてみます。

20頂点

さて現在のソルバーは検出可能な全ての経路を愚直に試していて経路の数は頂点が増加すると指数的に増えるため、20頂点くらいでかなり遅くなり、30頂点もあると1日経っても終わらないプログラムになってしまいます。
ところでアニメーションを見るとたしかに解けていますが、かなり無駄がありそうな動きだと思いませんか?無意味に往復しているし、スタート地点を左下の次数1の頂点以外にしても何の得もありません。
そこで「こういう経路は明らかに損だから試す必要がない」という情報をソルバーに加えることで、高速化してみます。

30頂点

すれ違うこの気持ち 分かりたいからぶつかり合うんだ
何度だっていい 遠回りするんだ
心ごと張り裂けそうなのは 目指す場所があるから
届かないことが怖くなる

Infinity Rage / La prière
40頂点

祈りも 奇跡も まるで必然みたいね
そう思えるくらいに描く未来図は
あなたと紡いだ 鮮やかなシンフォニー

50頂点

遥か彼方 遠く 遠く 遠く 夢を描いて
あなたがくれた追い風に乗り込んで
まだ跳べる?跳べない?
跳びたい 跳ぶよ 跳べるよ!
だから ∞の明日へ

ということで50頂点が可能なところまで高速化しました。
今回はジェネレーター、ソルバー、ビジュアライザーを作り全自動化し、ビジュアライザーをアニメーション版に改良し、ソルバーも高速になるよう改良することで、人力では作問も回答も難しい規模の『アルビレオ』を生成できるシステムを作りました。
なお、50頂点でアルビレオ一筆書き可能なグラフを見つけるまでに、約4000回ランダム生成が行われていました。更に60頂点を試したところ20000回生成しても1つも見つかりませんでした。
この場合、次はジェネレーターを「ランダム生成の時点で明らかに解けないものは生成されないようにする」よう改良することでより良いシステムになることが期待できます。

(この自動アルビレオのようなプログラミング力は競技プログラミングで鍛えることができます。興味がある人はぜひ一緒に遊びましょう)

*2:普通の一筆書きで今回のように具体的な経路を求める場合はFleuryのアルゴリズム、Hierholzerのアルゴリズムなどで高速に求まることが知られていますが、やはりアルビレオルールには拡張できそうにありません。

*3:このような全域木法で生成できるグラフには偏りがあり(Prüfer列とラベル付き木は一対一対応ですが、ラベル付き木とラベルなし木の対応割合に偏りがあるため)、一様ランダムなグラフが欲しい場合はより高度な構成比近似法などを使用する必要があるのですが、今回は偏りは重要でないため採用しませんでした。

Q&A

らぷり東名阪ツアー感想記事で答えます」と募集した時の質問のうち、らぷりげーむ関連のものに答えます。残りは東京公演後に答えます。

楽しかった思い出

  • 自分のマウス描き素材で動いていたゲームに、イラストチームやBGMチームの最高な素材で命が吹き込まれた瞬間

    • 別記事(後述)で当時のチャット付きでめっちゃ語っているのでよければ!

  • リリース初日から#らぷりげーむ で沢山感想ツイートがあったこと

大変だった思い出

  • アルビレオで誤爆しないための座標調整をリリース当日に徹夜でやったこと

  • PC、iPhone、androidの全てで動作に問題がないことの確認とバグ修正

バズってQiitaトレンド1位になったあの記事(後述)を!?ありがとうございます!!
星座は
はくちょう座:アルビレオがはくちょう座の恒星なので。
ふたご座:Gemini Syndromeから。
やぎ座:ラブリーアイドルの歌詞に出てくるから。
です!なくなゆの誕生日のうお座とてんびん座も候補に挙がっていましたが、他のゲームと同じくらいのボリューム感と考えた時に3ステージにしたかったので、こうなりました。
次回作はらぷりげーむ開発部としては特に動いていないのですが、個人的には最近は深層強化学習やVRコンテンツをかじっているので、個人製作するとしたらそういう方向になるかな~という感じです。

以下、Qiitaに載せていない僕が出した没案たちです。

広告のアレシリーズ
藍月なくるを投げたくて……
ちょうどイリュージョニスタリリース頃にネタ出ししてました
プレゼンバージョン

関連リンク

#らぷりZepp 直前生放送!ライブまであと2日!【#らぷりえーる】
らぷりえーるさんによるらぷりげーむ実況のアーカイブです。

プロジェクト進行や技術面の話など、本記事とは異なる視点でらぷりげーむ制作ウラ話を書いています。僕の没案シリーズも2つ載っています。

ゲーム制作と並行してフラスタも出しました。フラスタリーダーの〇〇っぺさんによる記事です。

あとがき

くぅ~疲れましたw これにてLa prière Advent Calendar 2023完走です!
企画してくれたEtrisさん、参加者の方々、ありがとうございました&お疲れ様でした!この25日間で、文字だけで15万字以上、他にも絵とか写真とかプログラムとか……皆のらぷり愛を感じました。
読んでくれたらぷりすのみなさんもビッグカンシャ!そしてLa prièreさんにもスペシャルサンクス!!からの東京公演まで盛り上がっていくぞぉおうぉうおぉえおえおおおおおおおえおえお!!!!
そして〆を主催にバトンタッチ!

この記事が気に入ったらサポートをしてみませんか?