“憂鬱”の記事への反応として、「アウトゲームはクリーンに作った方がいいし、インゲームはダーティでもしゃーない」という意見がいくつかありました。
私にとって、この”Unityゲームをインゲームとアウトゲームに分けて考えよう”という発想は、目からウロコで、大きな気付きを与えてもらいました。
ぶっちゃけた話、インゲーム、アウトゲームという用語自体、これまでほとんど聞いたことがありませんでした。
みなさんは知ってましたか?
Unityで作るのは全部ゲームだろ。そのゲームの中にさらにイン(内側)とアウト(外側)があるって何のこっちゃ?とか思いませんか?
ググったら用語の意味が分かりました。
インゲームとアウトゲームの用語を知らなかったので調べた【ゲーム開発】
インゲーム、アウトゲームと言うのは、いわゆるソシャゲ的なゲームアプリ業界で使われる用語だそうです。
私はスマホゲーム会社にいた事もありますが、その時は聞いた事ありませんでした。
インゲームとは、そのアプリ固有の、遊びの部分です。まあハッキリ言ってしまうと、戦闘パートの部分ですね。FGOとかパズドラとかアークナイツとか、戦闘パートでそれぞれのアプリの個性がでます。
で、アウトゲームと言うのはそれ以外の部分です。どんなアプリでも見た目がちょっと異なるだけで大体同じです。なによりもまずガチャがあって、編成画面とか、お知らせ、プレゼント、デイリーミッション、などなど。
インゲームはそれぞれのアプリに固有であり、他のアプリで使い回しは(ほとんど)しません。
最近はスマホゲームでも家庭用ゲームと同等の、凝った3Dゲームが遊べます。
メチャクチャ複雑な構成になっていて、常にオブジェクト生成、消滅が入り乱れて、非常にカオスな状態になってます。(例えば原神とかを想像してください)
インゲームでは、プレイヤーをたのしませるための”体験”を作る必要があります。開発中は、毎日イテレーションが行われ、常に仕様は流動的です。
イテレーションを高速に回して試行錯誤できる環境を維持するのが最優先されますので、いちいちコードを固く設計しても、ちゃぶ台返しなどですぐに崩壊する気がします。
それに対して、アウトゲームはどのアプリでも大体共通であり、他のアプリでも使い回す必要があります。
ですから、バグが無い事、固く作る事が優先されます。
バグが出ないようにするためには、テストを書く事も重要視されます。
アウトゲームでは、UIを操作する事でユーザーのデータに対して変更を行います。
ゲームと言うより業務アプリケーションに近い作りになります。
ですので、クリーンアーキテクチャのようなものも持ち出されてきます。
また、アウトゲームのコードがビュー(UI)と紐づいてると、使い回しが効かなくなるので、コードとビューが分離されてる必要があります。
アウトゲームの仕様は最初からほとんど分かりきっており、あらかじめ完全に設計して仕様を決める事が可能です。
アウトゲームでは、ゲームに必要な”機能”を作る必要があります。
”固く”、”使い回せる”ように作るために、きちんとした設計が求められ始めています。
私はこのまったく正反対といっていいインゲームとアウトゲームをゴッチャに考えていたため、大きな矛盾に悩まされ、どうにかなっちゃいそうでした。
インゲームの考え方でアウトゲームを作ろうとしてもダメだし、アウトゲームの考え方でインゲームを作ろうとしても上手くいかないでしょう。
Unityの作法を無視してUnityでゲーム作ろうとしても、それは船に乗って山を登ろうとするようなもんです。
Unityにだって”コンポーネント指向”という立派な設計指針があります。これを尊重して開発しないとうまく行きません。
ですので、インゲーム(Unity的)とアウトゲーム(クリーン的)はまったくの別物、別の世界として分けて考える方が上手く行きそうです。
すなわち、アウトゲームはカッチリとクリーンに作る。インゲームは普通のUnityの作り方で自由に作る。という事です。
どっちが偉いとか、そういう事ではありません。
インゲームがダメでもアウトゲームがダメでもアプリは上手く行きません。
Unityでソシャゲを作る需要が巨大すぎる
ここまで読んで、「な~んだ、ソシャゲの話だったのか」と思った方もいるかもしれません。
そもそも論として、Unityはソシャゲツクールではありません。
Unityには特にソシャゲ向けの機能はありません。強いて言えばUGUIができて、UIを作るのはラクになりました。
普通はUnityでゲームを作ると言えば、家庭用ゲームとかのインゲームしか存在しないゲームを指すはずです。
ですから、普通にUnityを学んだ人は、私もそうですがインゲーム的な使い方しか知りません。
そりゃそうです。Unityには元々インゲームの機能しか無いですし、インゲーム的な作法しか用意されてません。
アウトゲーム的な考え方と言うのは、悪く言えば何だか知らない内にいつの間にかUnity本来の用法に対してどんどん侵食してきている新たな概念およびツール類だと思います。
特に、こと日本においては、ソシャゲ開発のエンジニア需要があまりにもメチャクチャでかいです。
多分ですが、日本のUnityエンジニアの5割くらいはソシャゲ作ってるんじゃないかな…適当ですが。
そんなんですから、アウトゲーム部分をいい感じに作る技術は大いに求められています。
…という、ここまでの話を前提として押さえておかないと、なんで巷でZenjectがもてはやされてるのかとかの文脈が掴めないと思います。
UnityのC#って醜くないか?
UnityはC#でコードを書きます。
いや…コードってか、UnityのC#って元々単なるスクリプトって扱いなんですよね。
昔はC#以外にも、javascript風のunityscriptとか、Boo言語とかのワケ分らん言語も使えました。
そういう有象無象の言語でゲームのスクリプトが書けますよって選択肢の中の一つにたまたまC#があっただけです。
大体、UnityのC#ってどうかしてると思いませんか?
MonoBehaviourを継承しないと(普通は)使用できない。MonoBehaviourを継承したらnewできないって。変じゃないですか。
昔はnamespaceさえ使えませんでした!
だからそんなキッチリしたプログラムのコードと言うより単なる書き捨てのスクリプトという扱いです。
昔はVisualStudioも使えなくて、Monodevelopとかいう訳分らんIDEを使うハメになってたし。
そんなスクリプト風情を、いちいちコードレビューしますか?
例えばカメラがプレイヤーキャラをフォローするスクリプトを書いたとして、それをコードだけ見て何をどうレビューするんでしょうか。(まあ変数名がコード規約に沿ってるかとか…?)
たとえばたまごっちみたいなゲームを作るにあたって、キャラがうんこするスクリプトを書いたとしますよね?
うんこするスクリプト、コードレビューしますか?
うんこするスクリプト、テストしますか?
うんこするスクリプト、別のアプリで使い回しますか?
必ずしもインゲームのスクリプトにテストとかレビューが必要とも限らないんじゃないかしら…。
まあ、最近はUnityのC#もnamespace使えるようになって、新しいC#機能にも対応して、モダンでマトモなC#みたいな空気を匂わせ始めました。
それがまた事態をややこしくしてるとも言えます。
UE4だとスクリプトは基本、ノードベースのブループリントで作るんですが、インゲームスクリプトもレビューが必要と言う人は、だったらブループリントもレビューするんでしょうか。
UnityのBoltを使った場合はどうなんでしょうか。
まあそこまでインゲームにレビュー、テスト不要説をムキになって主張するでも無いですが、ちょっと思っただけです。
[21/01/27追記] この記事を公開した後、インゲームにレビュー不要説に対してご意見をいただきました。
UE4のブループリントでもコードレビューをやってるそうです。
私はブループリントはそもそもコードじゃないからレビュー不可能だろうくらいに思ってましたが、プルリクにブループリントのスクショを貼ってそれを見てレビューするそうです。
悲惨なブループリントのスクショがまとめられてます。
そういえば前に、ブループリントみたいなノードでロジック書いたらグッチャグチャになるに決まってんだから、C++で書いた方がいいんじゃないの説をツイートした事があります。
その段階では大してUE4触ってませんでしたが、始めるにあたってどっち使えばいいんだと悩んだからです。
でも案外ブループリントだけでもゲーム作れるよという事を教えていただきました。
ちなみにジラフとアンニカではC++じゃないと実装が難しかった箇所はalweiさんの会社に協力してもらったそうです。
話を戻しますが、インゲームのスクリプトのレビューと言っても、スクリプト読んでバグがあるとか無いとか分かるもんなのかな?と思ったので、どういう指針でコードレビューしてるのか教えていただきました。
このツイートの流れの通りですが、インゲームのレビューでは、バグはともかく明らかにヤバそうなコードを通さないという指針でやってるとの事です。
インゲームは仕様が流動的な分、キッチリ設計とかできないので、むしろ常に綺麗なコードを心がけておかないと、メテオ降ってきた時に困るという話みたいです。
のたぐすさんもジョニーさんも、見事に意見が一致してますし、二人とも私より現場経験豊富そうですし、これは実際インゲームでレビューやっとかないと大変な事になるんだろうなと分かりました。
1人でモック作ってるような段階ならレビューしようがなさそうですが、チーム開発になったら、インゲームもちゃんとレビューした方が良さそうです!
インゲームに設計なんてものがあるのか?
インゲームに設計なんてもんがあるんでしょうか?
まああるような気もしますが、あるとしても、それはクリーンアーキテクチャとかではない気がします。
クリーンアーキテクチャについてはこちらのページを見てちょっと勉強しました。
これによると、クリーンアーキテクチャは、「フレームワークなんかと結婚するな!」などと言っており、つまり、フレームワークとかはころころ変更されちゃう部分で本質的な所ではないので、ロジックの外側に追い出して依存しないようにしようって事です。
Unityもフレームワークだと思いますが、インゲームのコードをUnityに依存しないように書く事になんか意味あるんでしょうか。
Unity以外へコード使い回したりしますか?
↓こちらのページでは、質問者が「Unityでクリーンアーキテクチャって使えますか?」的な質問を投げており、それに対して「UnityでUnityに依存しないコードは書けない」みたいな回答がされています。FPSゲームでカメラをコントロールするスクリプトなどはUnityの機能にべったり依存してるので、抽象化しようがありません。
https://answers.unity.com/questions/1520540/clean-architecture-or-ecs-or-both-ecs-architecture.html
また、↓こちらのRedditのスレでも、「クリーンアーキテクチャはゲーム開発に適しているのか?」という話題で色々と興味深い議論がされてます。
「クリーンアーキテクチャはどんなソフトウェアにも適用可能なアーキテクチャである」との事ですが、果たしてそのソフトウェアの範疇にインゲームも含まれてんでしょうか?
クリーンアーキテクチャはさておくとして、インゲームではそもそも全体から作り始めるとは限らないという話があります。
例えばスーパーマリオブラザーズは、とりあえずジャンプするゲームだ!っていうコンセプトで始まったそうです。
ゲームは体験を作るものですから、まず先にジャンプの気持ちよさを作りこんだのでしょう。
そこから色々ギミックを生み出して広げていったってところではないでしょうか。
いくらエンジニアが全体から設計したいと思ったところで、ゲームクリエイター、あるいはプランナーのゲームの生み出し方は、そういう細部から全体を作る流れだったり、割と行き当たりばったりだったりするでしょう。
本質的にカオスだと言えるかもしれません。
ちなみに、Unityのインゲームの設計の話で言うと、例えばAdventure Creatorというアセットが売ってます。
https://assetstore.unity.com/packages/tools/game-toolkits/adventure-creator-11896?locale=ja-JP
このアセットを導入すると、まるでUnityがアドベンチャーゲームツクールと化したがごとく、簡単にアドベンチャーゲームが作れます。
また、宴というアセットを使えば簡単にノベルゲームが作れるらしいです。
インゲームで設計と言ったらつまりこういう物なのかもしれません。
インゲームにクリーンなコードを要求する人は、プロジェクトにUnityアセットをいくつか導入したら、アセット作者がそれぞれ好き勝手な思想で書いたコードがプロジェクトやシーンを汚染しまくっちゃう件についてはどのように考えてるんでしょうか。
もう少しインゲームについて物申しますが、インゲームは最悪チートされる事が前提になってます。
と言うのも、インゲームはクライアント側でゲームが進行するので、不正にクエストクリアAPIとかを叩かれたら、チートかどうか完全に判定できる方法はありません。
ですので、ぶっちゃけ最悪チートされても諦める(どっちみちスタミナが無くなればそれ以上クエスト遊べないから言うほどチートプレイヤーが有利にならない)ようなゲームの作りにしてるはずです。
ですので、いくらテストでバグをどうにかしようとしても、それ以前のガバガバさを内包してるやるせない気分みたいなものがある気がします。
アウトゲームの設計スキルも身に付けた方がオトク!?
インゲームとアウトゲームを完全に分けるという発想のおかげで考え方がクリアになり、むしろアウトゲームの設計も学んでみようかなと言う意欲も湧いてきた気がします。
と言うのも、Unityソルジャーと言えども、インゲームもアウトゲームも両方一人で書け!みたいな仕事を今後請けないとも限らないですし。
なんとなく、アウトゲーム書けるエンジニアの方が給料高そうなイメージです。
と言うのも、ソシャゲアプリで実際に金を生み出すのは、インゲームではありません(もちろんインゲームは重要ですが)。直接金を生み出すのはガチャです。ガチャはアウトゲームです。
ですから、アウトゲームをキッチリ書ける人は、「金を生み出すコード」を書けるエンジニアって感じで、評価が高まりそうです。
金を生み出すエンジニアには金が多く払われるでしょう。
今では個人開発のゲームでもアウトゲームのノウハウはあると便利かもしれません。
例えばPlayfabをバックエンドに採用したら、やる事はまんまソシャゲと同じになりますから。
さて、アウトゲームの設計って、それこそクリーンアーキテクチャだの何だのと、何だか難しそうなイメージがありますね。
しかし、実際にはインゲームと比べて全然難しくないかもしれません。
何故ならアウトゲームはどのアプリでもほとんど同じで、使い回せるものだからです。
そもそも、アウトゲームでやる事って、プレゼントをインベントリに入れるとか、編成データを保存するとか、UIを操作した通りに処理するだけで、大して難しい処理の実装は無さそうですから。
例えば、こちらのページでは、サイバーエージェントの「ボーイフレンド(仮)きらめき☆ノート」というゲームアプリのアウトゲームの設計について詳しく書かれています。
Web出身のUnityエンジニアによる大規模ゲームの基盤設計
やってる事は、この前このブログでも記事を書いた、MVPパターンの応用にすぎません。
しつこく言ってますが、アウトゲームは”どのアプリで大体同じ”で”使い回せます”。
つまり、こちらの記事の内容をありがたく真似させてもらって、一度だけシステムを作れば、あとは今のソシャゲの作りが今後廃れない限り、ずっとこれで食ってけるという事になるハズです。
簡単!
他にも、こちらでは、ミクシィで実際の開発事例を紹介した記事が載ってる、XFLAG Tech NoteがPDFとして公開されてます。
これもやはり、MVPパターンの応用です。ModelがEntityとRepositoryとUseCaseとFactoryの4つに分解されてるのがポイントみたいです。
さらにそのXFLAG Tech Noteの内容を噛み砕いた記事もこちらにあります。
ありがたいですね。
インゲームは常に新しい事を覚え続けないといけません。Unityも常にあれこれ新機能が追加されてます。
それに比べてアウトゲームは一度覚えれば当分食えそうな感じで、学習のコスパがいいかもしれません。
私も勉強して色々分かったらまたブログ記事にしたいです。
ちなみに、「アウトゲームはしっかりテストを書こう!」という風潮があるっぽいです。だからそのためにアウトゲームはピュアC#クラスで書く必要があるとかないとか。
私なんかからすると、どうせロジック自体はサーバーサイドにあって、クライアントはそれを叩くだけなんだから、そこまでキッチリやんなくてもいいんじゃないの?という気がしないでもないですが、よく考えると、例えば”購入”ボタンと”売却”ボタンに逆のメソッドを紐づけちゃったらえらい事になるから、たしかにカッチリテストした方がいいのかも。
おわり
インゲームとアウトゲームの世界を完全に分けるという考え方について書いてみました。
この記事ではまるで全部自分の意見だったかのようにアレコレと書きましたが、実際は”憂鬱”の記事への色々な反応を見て、いいとこ取りして折衷したような考えをまとめた感じです。
色々な人の意見がもらえたのはつくづくありがたかったですね。
その分、この記事もなにか読んだ人の参考になれば幸いです。