マジックデータ駆動設計

翻訳者からのメモ
英語から私たちに来たいくつかの用語の簡潔な翻訳がないため、私はそれらを元の言語のままにしておきます。 この業界に興味がある人はいらいらさせることはないと思います。




ゲームは、ロジックとデータの2つの部分で構成されています。 それらを一緒に接続することでゲームを活性化しますが、個別には役に立ちません。 ロジックはゲームエンジンの基本的なルールとアルゴリズムを定義し、データはゲームコンテンツとその動作に関する詳細情報を記述します。 魔法は、これらのコンポーネントの両方が互いに分離されており、個別に開発できることです。





思考1:基本



まず、テキストファイルをオンデマンドで(およびブートストラップだけでなく)読み取ることができるシステムが必要です。 プロセス全体の基礎となるデータ駆動型のパラダイムに従う必要があります。 各ゲームにはファイルからデータを読み取る方法が必要であり、最終的にゲームはバイナリファイルを処理する必要があるという事実にもかかわらず、開発プロセス中にテキストファイルを処理する方がはるかに便利です。 結局のところ、彼らは不可能に単純です! また、チーム全体の作業をより効率的に整理できます。コードを1行も変更することなく、チームのメンバー(テスターやゲームデザイナーを含む)は新しいことを試して、既存のもののさまざまなバージョンを試すことができます。 したがって、簡単に実装できる機能は、すぐに仕事に不可欠なツールになります。



思考2​​:エッセンシャルミニマム



定数をハードコードする必要はありません。 コードを再コンパイルせずに簡単に変更できるように、すべてをテキストファイル(またはファイル)に入れます。 たとえば、主な機能、カメラの動作など。 このように完全に説明できます。 もしそうなら、ゲームデザイナー、プロデューサー、次の入り口の少年-誰でもメモ帳で目的のファイルを編集するだけでゲームの動作を変更できます。 また、すべてのチームメンバーがプログラミングに慣れているわけではないため、定数の値を使用してプレイすることで、プロデューサーやゲームデザイナーはプログラマーを心配することなくゲームで必要な動作を実現できるため、これを覚えておくことが重要です。



考え3:制限なし



何かが変更される可能性があると仮定します(ほとんどの場合変更されます)。 ゲームで分割画面モードが必要な場合、正確に2つを正確に指定する必要はありません。 独自のゲームを作成します。これは、カメラごとに独自のロジックを持つ任意の数の画面をサポートできます。 これに対する仕事の量は、ビジネスへの正しいアプローチで、大幅に増加することはありません。 テキストファイルの魔法を使用して、ゲーム内の画面の数(1つ、2つ、4つ、またはそれ以上)を決定します。 ファイルはカメラの初期データも提供します:位置、方向、カバレッジの角度、傾き。 最良の部分は、ゲームデザイナーがこれらの設定を変更するために直接アクセスできることです。

このゲームは、柔軟なコード設計で完全に開発されています。 ゲームのコアを抽象化してレイアウトするプロセスは、ゲームの設計と開発に大いに役立ちます。 特定の目的のためにゲームを設計する代わりに、各コンポーネントとその一般的な機能を設計できます。 このアプローチの効果は、ゲームのプロジェクトドキュメントに記載されている動作をやみくもに追跡するのではなく、本当に必要なことをよりよく理解することです。

たとえば、ゲームに必要な武器が4種類しかない場合、それらすべてを個別に記述する完璧なシステムをプログラムできます。 ただし、動作を決定するデータを使用して各タイプの武器の機能から抽象化した場合、将来、無数のタイプの武器を追加して、新しいアイデアやゲームプレイのダイナミクスを試すことができます。 このような考え方により、最終的にゲームの改善と開発が可能になります。

「何もない」と言ったとき、私を信じていましたか?

真実は、ゲームはカスタマイズ可能でなければならず、大きなゲームはプロットに従って元のバージョンから進化する必要があるということです。 あなたのゲームは、ルール、キャラクター、レース、武器、レベル、制御スキーム、オブジェクトの変化に対応できる必要があります。 この柔軟性がなければ、ゲームの変更にはコストがかかり、小さな変更でもプログラマーの参加が必要になります。これは基本的にリソースの無駄です。 変更が複雑であることが判明した場合、これによりゲームの元のデザインがわずかに改善される可能性があり、ゲームはその潜在能力を十分に発揮することができません。



思考4:主な制御シナリオ



スクリプトは、コード外の動作を定義するための単なる方法です。 シナリオは、ゲームで発生する一連のステップを決定したり、トリガーされるゲームイベントを決定したりするのに最適です。 たとえば、「クエストが完了した場合に何が起こるか」や「どのトリガーがこの環境で機能するか」などの単純な因果論理を説明するゲームシーンのスクリプト。 これらの例はすべて、データ駆動型の設計パラダイムに属します。

スクリプトを設計するときは、分岐ロジックとその編成方法を決定する必要があります。 2つのアプローチがあります。 1つ目は、スクリプト内で変数を引き続き使用し、比較演算子(等号(=)、小なり(<)など)と比較することです。 2番目のアプローチは、コード内に存在する変数を比較する評価関数(isLifeBelowPercentage(50)など)を直接呼び出すことです。 これらの方法を組み合わせて使用​​することもできますが、スクリプトはシンプルにしてください。 ゲームの設計者は、宣言された変数を使用して関数を評価し、それらを更新し、比較するよりもはるかに簡単に作業できます。 また、2番目のアプローチはデバッグを簡素化します。

残念ながら、スクリプトには適切な言語が必要です。 つまり、ゲームの動作を決定するには、構文全体を作成する必要があります。 スクリプト言語には、スクリプトパーサーの作成と、場合によっては、スクリプトをバイナリファイルに変換して将来の実行を高速化するためのコンパイラの作成が含まれます。 別のオプションは、Javaなどの既存の言語を使用することですが、この場合、多数の追加コンポーネントが必要になる場合があります。 スクリプト言語に多くの時間を費やさないようにするには、システムの設計を簡単にする必要があります。 一般に、スクリプト言語に過剰なパワーを与える傾向があります。 以下の考えは、複雑なスクリプト言語の落とし穴のいくつかを説明しています。



考え5:良いシナリオが悪いとき



スクリプトを使用してデータ駆動設計の動作を記述することは、この方法論の当然の結果です。 ただし、常識を忘れずに、重要なアイデア、つまりロジックとデータの分離を忘れないでください。 複雑なロジックがプログラムコードに送信され、データは外部に残ります。

問題は、データに依存したいという欲求が行き過ぎたときに発生します。 ある時点で、スクリプト内の複雑なロジックを記述することができます。 スクリプトが何かの状態を含むようになり、分岐が必要になると、状態マシンのようになります。 彼の財産が増えるにつれて、無実のスクリプトライター(およびいくつかの貧しいゲームデザイナー)はプログラマーとして働かなければなりません。 スクリプトが複雑になりすぎると、作業はプログラマに戻ります。プログラマは、厳密に制限された言語ですべての困難を説明する必要があります。 シナリオは、人々の作業を難しくするのではなく、簡単にする必要があります。

複雑なロジックをコードに保存することが重要なのはなぜですか? 機能性とデバッグの問題。 スクリプトはコードの外部にあるため、プログラミング言語に存在する概念の多くを複製します。 自然な傾向は、スクリプトが実際のプログラミング言語になるまで、より多くの機能をスクリプトに提供することです。 より複雑なスクリプトが表示されるため、デバッグ時にはより多くの情報を追跡する必要があります。これにより、スクリプトを操作するという当初の単純なアイデアが複雑になります。

ご想像のとおり、スクリプトには自明ではないロジックが含まれている場合があり、スクリプトパーサー、コンパイラ、およびデバッガを作成するには数か月かかる場合があります。 これは、プログラマーが自分の前にかなり良いコンパイラーがあることを理解していない場合に起こります。

ぼやけた境界線

コードとスクリプトの境界がぼやけていることは間違いありません。 一般に、人工知能(AI)の動作をスクリプトに入れるのは悪い考えですが、スクリプトにシステムトリガーを配置して世界にインタラクティブ性を持たせるのは良い考えです。 次のルールが判明します。ロジックが複雑な場合は、コード内にある必要があります。 ゲーム(およびすべてのプログラミングリソース)を吸収しないように、スクリプト言語は単純なままにする必要があります。

ただし、一部のゲームは、プレーヤーが独自のAIを作成できるように設計されています。 多くの場合、これらはボットを追加できるファーストパーソンシューティングゲームです。 目標がそれだけである場合、スクリプト言語の実際のプログラミング言語への類似性は避けられません。 例としてQuake Cがあります。ボットの作成はゲーム自体に組み込まれているため、C言語と同じくらい便利なスクリプト言語の作成にリソースとエネルギーが費やされています。

まず、ゲームのデザイナーや脚本家にゲームをプログラムさせたくないことを忘れないでください。 プログラマーは、ゲームデザイナーをゲームプログラミングに誘うスクリプト言語を作成することで、責任を回避しようとすることがあります。 理想的な場合、プログラマは深刻な問題を解決し、制御ロジックの重要な部分を作成する必要があります。 そうでなければ、なぜ彼らはそんなに多くのお金を払うのでしょうか?!



思考6:データリピート症候群の回避



一般的なプログラミング方法は、コードを複製しないことです。 2つの異なる場所で何らかの動作(たとえば、一般的な機能)が必要な場合は、1つの場所にのみ存在する必要があります。 この考え方は、グローバルデータブロックへのリンクを使用したデータの説明にも適用されます。 さらに、データセットへの参照を使用し、それらの値の一部を変更することにより、最終的に継承の概念にアプローチします。

継承は、データに適用する必要がある大きなアイデアです。 ダンジョンに住むゴブリンがあなたのゲームに住んでいると想像してください。 あなたのデータは、各ダンジョンのすべての特性とともに各ゴブリンの位置を決定します。 各ゴブリンインスタンスのグローバル定義データを正しくカプセル化します。 各ゴブリンが一意になるように、リンクには再定義可能なプロパティのリストが付随する場合があります。 このアプローチにより、データを複製することなく、各ゴブリンに独自の動作をさせることができます。

このアイデアは複数のレベルで適用でき、各データセットにリンクを設定できます。 この手法を使用すると、ゴブリンの基本型から継承するグローバルゴブリン定義を作成できます。 各ダンジョンの定義内で、普通のゴブリンまたは速いゴブリンを示すことができます。 図は、参照と値のオーバーライドを使用した継承の概念を示しています。









考え7:データを操作するためのツールを作成する



大規模なゲームでは、テキストファイルが最終的に管理不能になり、それらを操作することが難しくなります。 この問題の解決策は、それらと連携するツールを作成することです。 このツールをゲームエディター、レベルエディター、またはスクリプトエディターと呼び、ゲームの開発をスピードアップします。 ツールを所有しても、データ駆動型の方法論は変わりませんが、より信頼性が高く効率的になります。 そのようなツールで節約される時間は、開発と実装のコストを正当化します。



おわりに



データ駆動型の設計方法論を始めるのは簡単ですが、このアプローチがもたらす驚くべき可能性を想像するのはかなり困難です。

完全な消滅は、この良い例です。 デザイナーのクリス・テイラーは、アームとコアの2つのレースを展開しました。 ゲーム全体は2つのレースに焦点を当てていますが、ゲームにハードコーディングされていません。 理論的には、ゲームのリリース後でも、データを追加して3番目のレースを追加できます。 この機能が使用されなかったという事実にもかかわらず、Total Annihilationはこの点に関して完全にカスタマイズ可能なままです。 すべてのユニットはデータによって決定されるため、新しいユニットはゲームのウェブサイトで毎週公開されました。 実際、多くの人々は、ゲーム開発者自身に衝撃を与えた機能を持つ独自のユニットを作成しました。

データ駆動型の設計により、Total Annihilationはすでに混雑しているジャンルのゲームの忠実なファンをサポートすることができました。 Total Annihilationで実装されたこのアイデアは、ウェブサイトを通じて追加のゲームコンテンツを配信するThe Simsなどの他のゲームにも応用されています。 データ駆動設計の哲学に対する開発者のコ​​ミットメントがなければ、そのような拡張は不可能でした。



All Articles