すべての記事
チュートリアル · 6 min read

再現可能な散布:シード、決定論、そして散布されたレベルのバージョン管理

なぜプロシージャル散布は決定論的でなければならないか。シードがランダム性を再現可能にする方法、ネイティブインスタンスへのベイクが散布されたレベルをdiff可能かつマージ可能にする理由、そしてチームの植生をソース管理下で静かに変化させないようにする方法。

Coloured prayer flags strung across a mossy, fern-covered forest floor

要するに: プロシージャル散布は再現可能である場合にのみ信頼できる。同じ入力は、 すべてのマシンとすべてのビルドで常に同じ森を生成しなければならない。それはシードを理解する こと(ランダム性を再現可能にする方法)、生きているプロシージャルシステムがなぜソース管理下 で危険なのか、そして散布をネイティブエンジンインスタンスにベイクすることがなぜマージ不可能な ブラックボックスをdiff可能でレビュー可能でバージョン管理可能なアセットに変えるのかを意味する。 この記事は決定論、シード、そしてチームの植生を全員の足元で静かに変えないようにする方法を カバーする。

シダが繰り返しながらも変化のある塊で森の床を覆う これはランダムに見えるが、チームにとっては再現可能なランダムでなければならない。あなたの マシン、チームメイトのマシン、ビルドサーバー上で同じ。決定論こそが美しい散布を実際に出荷し 維持できる何かに変えるものだ。

なぜ決定論が重要か

散布が開かれるかビルドされるたびに異なる形で再生成されるなら、あなたのレベルは 静かに変化する。衝突が動き、隠れたオブジェクトが現れ、プレイテストが再現不可能になる。決定論 的な散布は、同じ入力から常に正確に同じ結果を生成する。

再現可能でないランダム性はレベルにおけるバグ工場だ。異なるマシンでシーンを開くこと、または 来週それを再ビルドすることが、すべての岩と茂みが着地する場所を再シャッフルするなら、開いて いた場所は今ブロックされ、あなたが調整した視線は壊れ、テスト中のレベルが出荷したレベルではない のでプレイテストの結果は信頼できない。決定論(同じ入力、同じ出力、常に)、がプロシージャル 散布を安全にするものだ。それは「コンピューターがいくつかの植物を配置した」と「レベルには 私が信頼できる定義された安定した状態がある」との違いだ。

シード:ランダム性を再現可能にする

シードはランダムシーケンスの開始番号だ。同じシード → 毎回同じ「ランダム」な 配置。シードを露出させて保存すれば、あなたの散布は再現可能だ;それを真のランダム性に任せる なら、実行のたびに異なるレベルだ。

コンピューターは真のランダム性を行わない。決定論的なシーケンスを実行し、それらはランダムに 見える、各シーケンスはシードと呼ばれる開始番号によって定義される。同じシードを与えれば 同じシーケンス、したがって同じ配置が、毎回得られる。これが再現可能な散布への鍵だ:ツールは シードを露出させ、あなたはそれをシーンと共に保存し、森は今や(シード + パラメータ + 表面)の 純粋な関数だ。気に入った異なる配置を探るためにシードを変更し、それからロックする。代わりに 真にシードなしのランダムソースから引くもの(時計、開くたびの新鮮な出目)、は、ロードするたびに 異なるレベルを生成し、それはプロダクションには使えない。

バージョン管理の問題

「システム + パラメータ」として保存された生きているプロシージャル散布はソース 管理にとってブラックボックスだ。それをdiffできない、レビューできない、そして2人の人がそれを 編集するとマージ不可能な衝突が生じる。チームは、GitやPerforceが実際に追跡できる形の散布を 必要とする。

ここで散布はチームの現実に出会う。あなたの森が「これらの設定を持つ散布システム」としてのみ 存在するなら、ソース管理はそれが何を生成したかを見ることができない。いくつかのパラメータが 変わったことしか。プルリクエストで配置の変更をレビューできない、何が動いたか言えない、そして 2人のアーティストが同じ散布に触れると、どのツールも意味のある形で解決できないマージ衝突を得る。 生きているジェネレーター内にしか存在しない散布されたレベルは、チームが安全に協力するために 頼っているまさにそのシステムに見えない、そのため「すべてプロシージャル」は静かに「誰も安全に 森を編集できない」になり得る。

森の床に散らばる小さなキノコ これらのそれぞれは位置、回転、スケールを持つインスタンスだ。散布がネイティブインスタンスに ベイクされると、それらは本物の、検査可能なデータになる。森は式であることを止め、行ごとに レビューできるものになる。

ベイクはそれをdiff可能にする

散布をネイティブエンジンインスタンスにベイクする。具体的な変換を持つ実際の 配置されたオブジェクト。今それは普通のシーンデータだ:diff可能、レビュー可能、マージ可能、そして すべてのマシンで同一、なぜなら再生成されているのではなく保存されているからだ。

決定論とバージョン管理の両方の解決策は同じ動きだ:ベイク。生きているジェネレーターを 出荷する代わりに、散布を単純なネイティブエンジンインスタンスにベイクする。シーンに保存された 具体的な位置、回転、スケールを持つ実際の配置されたメッシュ。これはすべての問題を一度に崩壊 させる。定義により決定論的だ(それは再抽選ではなく、保存されたデータだ)。diff可能だ(ソース 管理は変化した具体的な変換を見る)。レビュー可能だ(リードはプルリクエストで正確に何が動いた かを見ることができる)。そして実行時にエンジンに異常なコストはかからない、なぜならそれは 単にインスタンス化されたメッシュだからだ。密度をルールで塗り、それからネイティブインスタンス にベイクするワークフロー(まさに Numivo がそう動くように)、は、プロシージャル 散布の作成速度手動配置コンテンツの安定性を、ブラックボックスの脆弱性なしに与えてくれる。

チームの植生を安定に保つ

シードをロックし、コミット前にベイクし、ベイクされた結果を真実の源として扱う。 意図的に再散布する(シードを上げる、diffをレビューする)、決して偶然でなく。そうすれば森は 誰かがそう意図した時にのみ変わる。

チームのための実践的な規律は短い。散布が再現可能であるようにシードをロック。ソース管理に あるものが皆が共有する具体的な結果であり、マシンごとに再抽選するレシピではないよう、コミット 前にベイクベイクされたインスタンスを真実の源として扱う。あなたがレビューし出荷する もの。そして森を変えたい時は、意図的にそれを行う:パラメータやシードを調整し、再ベイクし、 他のあらゆる変更のようにdiffをレビューする。目標は、人間がそうすべきだと決めた時にのみ変わり、 すべての変更が可視でレビュー可能である森。レベルの他のあらゆる部分に保つのと同じ基準。速度の ためのプロシージャル、安定性のためのベイク:それがすべてのトリックだ。

盗む価値のある現場の数字

  • 決定論のルール:同じ入力 → 同じ出力、常に(さもなくばあなたのレベルはドリフトする
  • シードはランダム性を再現可能にする)、露出させ、保存し、ロックせよ
  • 生きているプロシージャル散布はGit/Perforceにとってブラックボックスだ。diff不可、 マージ不可
  • ネイティブインスタンスにベイク → diff可能、レビュー可能、マージ可能、どこでも同一
  • チームの習慣:シードをロック → ベイク → コミット;意図的に再散布し、決して偶然でなく

ミニFAQ

散布をプロシージャルに保ち、決してベイクしないことはできないのか?ソロクイックプロジェクト にはたぶん。チームやあなたが維持するものには、いいえ。diffing、レビューと安全なマージを失い、 静かなドリフトを危険にさらす。ベイクこそがプロシージャル散布をプロダクション安全にするものだ。

ソース管理に正確に何を置くべきか。設定か結果か?ベイクされた結果は真実の源だ;意図的に 再生成できるように設定/シードも保持せよ。設定のみをコミットすることは、ソース管理がレベルで 実際に何が変わったかを見ることができないことを意味する。

2人のアーティストが同じ森を編集した。どうマージするか?ベイクされたインスタンスでは、 それは普通のシーンデータで、あなたの通常のマージツールが適用される。生きているジェネレーターで は、それはしばしば解決不能だ。これがコミット前のベイクと、特定の散布を誰が所有するかの調整の 中心的な議論だ。

ベイクは後で調整する能力を奪うか?いいえ。シードとパラメータを保持し、再ベイクは配置を 変えたい時の意図的なステップだ。再散布が自動的に起こる何かではなく意図的で、レビューされた アクションである限り、あなたはイテレーション安定性を得る。

プロシージャル散布は再現可能である場合にのみその場所を得る。シードをロックし、ネイティブ インスタンスにベイクし、そのベイクされた結果をレベルの真実として扱え。そしてあなたの森は チーム全体が構築できるものになる:作成が速く、出荷が安定し、誰かがそう意図した時にのみ変更が 安全だ。