複雑なゲームのテスト駆動開発


8

暇なときにゲームのコーディングをしていますが、プログラミングに関しては、まだ初心者です。この質問がトピックから外れている場合や、他の人に役に立たない場合は、申し訳ありませんが、うまくいけば、役に立ちます。

コードの設計や、コーディングのさまざまな方法論やアプローチについての本を読むのに多くの時間を費やしてきました。この調査の過程で、私はテスト駆動開発の概念に出会います。このアイデアを支持する人々は通常、それについて非常に情熱的です。私はそれがソフトウェアを書くスピードと効率を助けることができると信じています。時間は非常に貴重なリソースであるため、プログラミングクラフトの知識を広げようとせずに、何とかやり過ごすのではなく、最善の方法で学ぶことを学びたいと思います。

とにかく、私は初心者だからといって、テスト駆動開発をゲームにどのように適用するか想像できません。この件についていくつかの記事を見つけましたが、あまり役に立ちませんでした。私が見た単体テストの例のほとんどは、非常に単純な定型の例、またはまったくゲームに似ていないソフトウェアの例です。

私自身のコーディングでは、同様の考え方でテスト駆動開発に取り組みますが、実際にはTDDとしての資格はないと確信しています。ゲームに追加する機能を実装するための最小限のコードを記述し、すぐにゲームをテストして、機能するかどうかを確認します。意図したとおりに起こらない場合は、すぐに変更を加えて、自分が望むものに近づけます。機能していないか壊れている場合、およびコードを読み取ってもバグを見つけることができない場合は、予期しない動作が見つかるまでデバッガーのメソッドを順に実行し、それを削除します。私が言おうとしているのは、ほぼすべての増分変更の後で、常にゲームをテストしているということです。テストは私の開発を推進します。「単体テスト」は私の頭の中にあります、

私の実際の質問に移ります。複雑なゲームの単体テストを作成するにはどうすればよいですか?複雑に言うと、ゲームプレイの多くの創発的な側面を意味します。つまり、ゲームプレイの本質は、プレイヤーの選択と組み合わされたゲーム内のさまざまな要素間の相互作用から生まれます。たとえば、手続き型の世界を持つローグライクなRPG。そのようなゲームのためにどんなユニットテストを書くでしょうか?このようなゲームにテスト駆動開発をどのように適用できますか?


2
:質問のこの王は、より良いゲームDevのセクションに適した可能性がありますgamedev.stackexchange.com
glampert

1
テスト駆動開発では、設計を小さな管理可能な単位に分割することが推奨されることに注意してください。単体テストを使用して、プロジェクトの機能に使用される場合も使用されない場合もあるロジックをテストします。代わりに、コンセプト自体をテストする目的で機能することもあります。ゲーム開発でユニットテストを使用する方法の実例として、成熟したオープンソースゲームを探してください
Keldon Alleyne

回答:


12

単体テストはゲームプレイをテストしません。ゲームが楽しいかどうか、またはレベルが適切な難易度かどうかを確認するプログラム基準はありません。ユニットテストでは、ローグライクなmapgenが実際に階段を上って階段を降りるレベルを生成するかどうかをテストします。これは、重み付け時にキャラクターの動きが実際より遅くなるように、妨害規則が設定されていることをテストします。それはあなたのキャラクターが50の帽子を着ることができないことを確実にします。それは、メカニズムがすべて相対的に分離して正しく実装されていることを確認します。


1
あなたの答えは私が物事を少しよく理解するのに役立ちますが、完全にではありません。私の理解から、それが実際にテスト駆動開発であるためには、テストが最初に書かれるべきです。したがって、失敗したテストを記述し、それをパスするコードを記述して、コードを修正します。これは、mapgenが階段を上下するレベルを生成するかどうかのテストにどのように適用できますか?TDDの要件を満たすのはどのような単体テストですか?
バゾラ2014

1
@bazola-理解できませんか?mapgenを呼び出すテストを記述してから、結果に階段があるかどうかを確認します。mapgenも階段の概念もないため、コンパイルできません。だからあなたはそれらを作る。次に、mapgenが実際に基準を満たすようにします...
Telastyn

それは理にかなっている。とても有難い!
バゾラ2014

4
関連性:TDDは、ユニットテストが開発の唯一の推進力であるとは限りません。高レベルの失敗する「受け入れ」や統合テストを作成することで「ドライブ」を開始できます。そこから解決策を考え出し、最初に失敗する単体テストを作成することができます...しかし、正直なところ、重要なゲームの意味のある自動化された受け入れテストを作成する必要があります。
svidgen 14

2

非決定的であるコードの単体テストを記述することは困難です。乱数を含むコードがある場合、期待される結果を表明する単体テストを作成することはできません。

したがって、決定論的であるコードにはユニットテストの方が適しています。メソッドにこれらの入力を与えると、これらの出力が期待されます。例として:強さが15の戦闘機が両手式のブロードソードを使用して、10の装甲を持つアンデッドグールを正常に攻撃した場合、8のダメージを期待します。非決定的な部分(ヒットが成功したかどうか)は必ずしもユニットテストであるとは限りませんが、その後に何が起こるかはわかりません。ダメージ量がある程度の範囲内であると予想される場合でも、それをテストすることができます。

単体テストを作成するコードを見つけるのに苦労している場合は、決定論的ロジックがメソッドまたはクラスに分離されるようにリファクタリングする必要があります。最初にサイコロを振って成功を判断し、次に関連する入力(クラス、強さ、鎧など)をテスト可能なメソッドに渡します。

単体テストを頭に入れていることについてのあなたのコメントに対して、単体テストの要点は、新しく書かれたコードだけではありません。また、避けられない変更を加えた後でもコードが機能するという自信を持つことが重要です。


3
ランダム性を使用するコードを単体テストする1つの方法は、コードを何度も実行して、結果が統計的に予想される分布にほぼ一致するかどうかを確認することです。したがって、攻撃が10 + 2d6のダメージを与えると想定されている場合は、コードを1000回実行し、結果が22より大きく、12より小さくないこと、およびその範囲内にほぼベル形の分布があることを確認します。
フィリップ

1
この方法は、レベル1のキャラクターが90%の確率でゴブリンに対してシミュレートされた戦いに勝つようにするなど、より複雑な状況にも適用できます。
フィリップ

3
通常、コードの一部が乱数を使用している場合は、乱数ジェネレーターをサービス(IRandomNumberGenerator)に抽象化し、乱数を使用する必要があるものはすべて、コンストラクターでそのサービスインターフェイスへの参照を受け入れます。次に、テストがそのオブジェクトを作成して単体テストを実行するときに、MockRandomNumberGenerator既知の固定数のストリームを供給するを注入します。次に、繰り返し可能なテストがあります。同じアイデアは、現在の日付/時刻を取得したり、Webサービスから情報をダウンロードしたりする必要がある場合に役立ちます-モックサービスを挿入するだけです。
スコットウィットロック

...その後、統計的手法を使用して、の実際の実装の実際の動作をチェックする別のテストを作成できますRandomNumberGenerator
スコットウィットロック2014

できれば反対票を投じます。結果の統計的特徴は、ランダムアルゴリズムに対してテストされます。
リガ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.