質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%

Q&A

解決済

4回答

3936閲覧

ゲームプログラミングにおける条件分岐実装のベストプラクティスについて

HikaruS.

総合スコア33

0グッド

1クリップ

投稿2019/06/07 00:33

編集2019/06/07 01:19

お世話になっております。

質問内容

この度初めてプログラミング言語を用いてゲーム開発(に類似したもの)を行おうとしているのですが、例えばRPGにおける セリフ→選択肢→選択肢に対応するセリフ事象→状態チェック→状態チェック結果に対応するイベント などの膨大なシナリオ選択肢(と呼ばせてください)の実装はどのように行われるのが最もよいのでしょうか?

ある程度のモジュール化・引数化は可能だと思いますが、あらゆる状態や条件をチェックする場合これをデータベースのカラム・データのみで管理するのは無理があるのではないか、と感じています(もしくは、レコードのフィールドの中に「これがTrueなら選択肢1に飛ぶ」のようなカラムを実装 するとか して、そこにコードのようなものをそのまま記入してしまうとか)。

このような場合、やはりシナリオのためのコードを逐一記述することになるのでしょうか?シナリオ追加について コード変更ではなくデータの変更のみで対応するためのベストプラクティス などありますか?

とりとめなく恐縮ですが文意をご理解いただけましたらご回答くださいますと幸いです。
どうぞよろしくお願い致します。

補足情報

すみません、以下ご指摘を受けたので補足情報です。

知識レベルについて

「配列・リストの知識があるか」

これについては大丈夫だと思います。よく利用する言語はC#ですが、頻出の型であれば扱えます。

「実際にそのようなツールを触ってみたか」

はい、少しだけですがVisualStudioを用いてASP.net関係の開発をしておりました。ゲーム開発という分野はまったく不慣れでして(WEBやWindowsフォームなどばかり触っていたので)、そのため一般的にはどのように実装されるのか?という趣旨で今回の質問をさせていただきました。

私が何をしたか(この質問を解決するためにしたこと)

思いつくワードで何度かGoogle検索を行いました。
コード変更なしで、データベースのレコード追加でシナリオを(ある程度)作成できることが理想だったので、以下のようなワードを組み合わせて検索しています。

  • ゲーム 選択肢 膨大 データベース 設計 コーディング シナリオ 条件 分岐

ただ、やはりデータベースを用いたシナリオ追加ではなくコーディングによる追加を前提とする大量分岐の効率的な実装に関する記事が多く、やはりデータベースでの実装は現実的ではないのかな、と思っている状態です。
これまでの経験でなるべくコードを変更せず、データのみで拡張性をもたせることがよいと感じていたので、本当にコードによる追加しか(適切な)方法がないのか?データベースで拡張性をもたせるよい手法があるならば知りたい。と思っています。
「あるフラグが1だったら」というような単純な条件であればデータベースメインでも実装できるとは思うのですが、「この値がこれで、この値がこれでこの値がこうであるとき」などのような場合は 『「これがTrueなら選択肢1に飛ぶ」のようなカラム』の値としてコードをもたせるしか方法がないのかなと思っております(=その場合、コードを変更するほうがまだメンテナンスしやすい設計なのかな、と)。
実際のところデータベースで実装することは非現実的で「普通ではない」のか、コードを追加する方法でシナリオを追加していくべきなのか、という一般的な感覚…のようなものをご提示いただければ大変幸いです。

利用予定のエンジンについて

実際は「ゲームのようなもの」でして、ビジュアルを持つ一般的な「ゲーム」ではないのでエンジンについては特殊なゲームエンジン等を用いる予定はありません(Windowsのコンソールアプリケーションになると思います)。
ただ、要求仕様が「RPGのシナリオ」とほとんど同じものですので、ゲーム開発の手法を伺えばヒントになるんじゃないか、と思い質問致しております。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sakura_hana

2019/06/07 00:48

https://teratail.com/help/question-tips こちらを参考の上、自分で調べたこと・試したことを記載してください。「ノベルゲーム 条件分岐 管理」辺りで検索するといいのではないかと思います。 個人的に何がベストか分からないのでこちらに書きますが、手法選定の為には質問主さん自身の「配列・リストの知識があるか」と「実際にそのようなツールを触ってみたか」が重要になると思います。 エンジンは何を使うか分かりませんが、例えば以下はUnityでノベルゲームが作れるアセットのページです。チュートリアル等を見るだけでも「このツールではどうやっているか」が分かると思います。 http://madnesslabo.net/utage/ 『レコードのフィールドの中に「これがTrueなら選択肢1に飛ぶ」のようなカラムを実装する』 割とこれが全てになりそうな気はしていますが、参考までに。
HikaruS.

2019/06/07 01:21

すみません!ご指摘の件追記いたしました。情報が足りておらず失礼いたしました。
guest

回答4

0

解決済みですが折角質問編集頂いたので、これがベストかは分かりませんが一案として。

例えばシナリオファイル(データベース)側では、
set|bool[1]|true→bool[1]をtrueにする
goto|bool[123]|123→bool[123]がtrueなら123行目に飛ぶ
goto|item[1]&&item[2]&&bool[3]|10→アイテム1とアイテム2を所持し、かつbool[3]がtureなら10行目に飛ぶ
などと記載しておきます。

スクリプト側ではList<bool>とかList<Item>など各種リストを1つずつと、setやgotoに相当する処理を作っておきます。

実際の動作時、最初に一度シナリオファイルを全走査し「使用されているデータ」の数だけListの中身を生成しておきます。
後は1行ずつシナリオファイルを見て行き、ある文字列が来たらそれに対応する処理を実行する、
という風にやれば、(事前に処理を用意済みなら)幾らでもシナリオが増やせます。

ただしこの方法、お察しの通り文字列処理をバリバリやるのでプログラム言語や動作媒体によっては遅いかもしれません。
開発段階でシナリオファイルをデータ用のコードに変換、実際にアプリに同梱して使用するのはデータ用コードの方、という手法にするなどの工夫が必要かもしれません。
(質問へのコメントで例に挙げた「宴」はこの方法を使っているようです)

ちなみにUnityの場合だと「ScriptableObject」という「コードなんだけどデータベースのようにも使える」クラスがあります。(オブジェクトのリストをGUIで編集&データ保持するだけのものですが)
ご使用の言語・ツールでも簡単に作れそう&使いやすく出来そうなら作ってみるのもいいかもしれません。
(大規模なシナリオだと結局「Excelやテキストファイルの方が楽だわ」となりがちではありますが……)

投稿2019/06/07 04:56

編集2019/06/07 04:56
sakura_hana

総合スコア11427

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HikaruS.

2019/06/07 05:55

先程は修正のご指摘をいただきましてありがとうございます。おかげさまでたくさん回答をいただくことができました。 ご提示いただいた手法なら、間違いなくデータのみの追加でシナリオの拡張ができますね…。 これまでの経験からなるべくデータのみでの拡張を行うべきだと考えておりましたが、他の方の回答も見ますとやはりそれが一般的ではないのだろうな、というのは漠然とわかりますので、コードを記載することによる拡張のほうも試していこうと思います(個人的にはこちらの実装もやってみたいです。メンテナンス性と速度との兼ね合いですが…)。 Unityはまったく触ったことがなかったのですが、ScriptableObjectはすごいですね。設定値種類に応じてGUIで値の更新ができたりするのもすごくいいなと思いました。 今回は言語の制約があるのですが、ゲーム開発も個人的に興味があるのでその際はUnityを最優先候補にしたいと感じます。 質問修正後も確認に来ていただき誠にありがとうございました。
guest

0

すみません。こんな回答でいいとは思いませんが作りたい物にもよります。
敵の挙動にせよ、プレイヤーの挙動にせよ、セリフの管理にせよ基本的には外部ファイルに書くのが、一般的です。
設計にも関わってくる問題ですので、まずはJSON形式など拡張性の高い外部ファイルをおススメ致します。
まずは簡単なint型のイベント管理から初めてみるといいでしょう。

投稿2019/06/07 00:57

stdio

総合スコア3307

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HikaruS.

2019/06/07 01:20

ファイルに書く手法が一般的なのですね。ゲーム開発についてまったく知識がないので助かります。ご教示ありがとうございます。
stdio

2019/06/07 01:34

iOSとかのアプリを作ったことあるなら分かりそうな問題なんですけど...
guest

0

すべての時間や場所がシームレスにつながっているなら別ですが
ステージやシーケンスにわかれていれば
グローバルにフラグをもち、ステージ開始時にグローバルデータをひきつぎ
ステージごとに変化する値をその終了時にグローバルに払い出す処理をいれれば
ステージ側はすきな拡張ができるでしょう

かりにすべてがシームレスだったとしても影響範囲をひとつの
ステージとして認識すればどうようの処理が可能です
(境界処理が若干大変ですが)

投稿2019/06/07 01:46

編集2019/06/07 01:55
yambejp

総合スコア114829

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HikaruS.

2019/06/07 01:53 編集

シーケンスに分かれた処理を取り扱う必要がある場合、オブジェクト指向の概念を用いてコーディングするとよいというご指摘と受け取りました。ご回答頂きありがとうございます。(シーケンスの有無について記載がなくすみません。)
guest

0

ベストアンサー

古いゲームブック(昭和の時代、ですね……)のように、

  • 1ページ、せいぜい見開き2ページで一つのシーンを表す
  • 選択肢がいくつか提示され、その選択によって次に移動する「ページ」を指定している

なんてのはまあ、データベースで再現できる(分岐の選択肢にシーンIDを持っていればいい)のですが、これにアイテム状態などを考慮すると、あるシーン上で処理すべき内容が多岐にわたります。
※例えばあるアイテムを持っていない場合、選択肢自体が存在しなくなるとか

結局はシーン毎のスクリプト制御になるでしょう。データベース内に「そのシーンで使うスクリプト」をまるごと突っ込んで動的に読み込んで処理するなんて手も考えつくことはつきますが、労力に見合うかどうか。
※結局直接実行する方に流れるような気もする

投稿2019/06/07 00:54

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HikaruS.

2019/06/07 01:20

ご指摘よく理解できます。やはり直接コーディングのほうが現実的なのでしょうね。 ご回答頂きありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問