43

完全自動生成の宇宙・交易・戦闘ゲームを作ります。しかし、銀河全体のすべての詳細をメモリに保存することは実行不可能であることを私は知っています. その結果、シードを使って太陽系を生成し、その太陽系からジャンプゲートを使用して他の太陽系に移動できると考えてきました。問題は、最初の太陽系から別の太陽系にジャンプした場合、まったく同じ機能 (惑星、小惑星など) を持つまったく同じ最初の太陽系に戻ることができる必要があることです。

基本的に、1 つの数値から銀河全体を生成できる必要があります。そして、1 つの太陽系を生成するその 1 つの数値から、最初の太陽系からリンクする他のすべての太陽系、およびそれらからリンクするすべての太陽系を生成できる必要があります。そして、私がそれらに戻った場合、各太陽系は機能的にまったく同じままでなければなりません. また、各太陽系からのリンクの数は、ランダムまたは固定のいずれかを選択できます。ランダムのほうがいいですけどね。

4

19 に答える 19

23

勇気があるなら、イアン・ベルがエリートのオリジナル版でどのようにそれをしたかを見るよりも悪いことをすることができます

于 2008-12-07T23:39:30.183 に答える
15

Gamasutra のこのシリーズをチェックしてください。

リアルタイム プロシージャル ユニバース、最初の 4 つのリンク

また、これ:無限宇宙のアルゴリズム

于 2008-12-08T00:56:34.630 に答える
7

私が理解している基本的な考え方は次のとおりです。スター システム #42 に到着し、その中に何があるかを調べる必要があるとします。惑星がありnplanetsます -- 0 から 10 までの数字です。

>>> star_system = 42
>>> nplanets = hash('nplanets%d' % star_system) % (10 + 1)
>>> nplanets
4

では、惑星 #2 のそばで、ゲーム開始時に軌道上にある宇宙ステーションはいくつありますか? 0 から 3 の間の数を見つけます。

>>> planet = 2
>>> nstations = hash('nstations%d/%d' % (star_system, planet)) % (3 + 1)
>>> nstations
1

等々。数値はそれぞれインデックス (この場合は星系 #42、惑星 #2) のハッシュ関数であり、適切な範囲に縮小されます。ハッシュ関数は決定論的ですが「ランダム」であるため、毎回同じですが、プレーヤーにはランダムに見えます。

もちろん、「nstations」のような長いシーケンスを含む文字列をハッシュすることは、可能な限り最速の方法ではありませんが、アイデアを示しています。

于 2008-12-08T01:46:21.487 に答える
6

オリジナルのWormsゲームを見てみましょう。約40億の可能なレベルがあると主張したと思います。各レベルは、おそらく 20 文字の短いシード文字列に基づいて生成されました。これにより決定された

  • レベルのテーマ (北極、森など)
  • 風景の形
  • 地面の滑りやすさ
  • 事前に作成されたレベルの詳細 (雪だるま、岩など) の配置
  • ワーム、地雷、武器箱のチームの配置。

レベルを楽しんだ場合は、シード文字列を書き留めて、後で同じレベルを再生成するために使用できます。

これは非常に複雑ですが、単一の入力パラメーターを持つ決定論的な関数の例です。これが必要なものの本質的な概念だと思います。

于 2008-12-08T12:24:50.077 に答える
5

Galaxy ID を SHA1 で入力していただけませんか、EG:

ギャラクシー 1

Sha1(1) = 356a192b7913b04c54574d18c28d46e6395428ab

ギャラクシー 2

Sha1(2) = da4b9237bacccdf19c0760cab7aec4a8359010b0

ギャラクシー3

Sha1(3) = 77de68daecd823babbb58edb1c8e14d7106e83bb

その後、IE のコードをセグメント化できます。

最初の 4 文字 = 惑星の数

356a
da4b
77de

ある種の文字列から数値へのアルゴリズムが必要になります。単純なものの1つは、数値以外のすべての文字のASCIIコードを取得し、それらをすべて一緒に乗算することです。

では、銀河系に惑星がいくつあるかがわかったところで、銀河の x、y、z 次元はどうでしょうか?

次の 9 文字 = Galaxy の寸法 (x、y、z)

上記と同じ原理で、コードを大きな数に変換します。感度チェックもいくつか行ってください。10milesx10milesx10miles の銀河に 2000 万の惑星は必要ありません。最小サイズが惑星の数 * 10000 のように、ある種の加重アルゴリズムを使用します。範囲がすべて互換性があり、ハッシュから選択された文字が実際に妥当な範囲を与えることを確認するために、数値を操作する必要があります。

または、これの代わりに、銀河の最小サイズと最大サイズの間の数値を乱数で選択することができますが、銀河 ID などの一定の RNG シードを使用してください! このように、銀河のサイズは観察者にとって本質的に「ランダム」ですが、毎回同じになります。

などなど!

これは宇宙のプロパティを取得する 1 つの方法ですが、惑星のプロパティはどうでしょうか。人口とかその他とか?

20,000 の惑星を持つ Galaxy 1 がある場合、次のことができます。

Sha1('1:340') = bc02ab36f163baee2a04cebaed8b141505cc26b5

つまり、銀河 1、惑星 340 です。その後、そのコードを好きなようにつなぎ合わせることができます。ハッシュを使用する利点は、すべての惑星が完全に一意のコードを持つ必要があることです。

于 2011-03-30T15:28:10.843 に答える
5

特筆すべきだと思いますが、

  1. 同じ入力に対して同じランダムに見える出力を生成するジェネレーターは、疑似乱数ジェネレーター「PRNG」と呼ばれます。通常、最初に 1 つの「シード」入力番号を指定し、そこから乱数を取り出して、それ以上入力せずに呼び出します。注: 少なくとも最初から開始しない限り、以前の番号に「戻る」ことはできません。

  2. 各呼び出しの入力として座標を使用して呼び出される PRNG のような関数は、通常、「ノイズ」関数です。ここでは、「元に戻せない」という問題はありません。「以前の」入力で再度呼び出すだけです。ノイズ関数は PRNG を (バックエンドとして、または少なくとも可能性があります) 使用しますが、これは最初からシードすることができるため、「1 つの数値からの宇宙」機能を失うことはありません。

  3. PRNG を使用して毎回銀河座標を「シード」に結合することもできますが、せいぜい「ホワイト ノイズ」しか得られず、それ以上の属性はありません。ノイズ関数は、タイル化可能/平滑化/らせん状の外観などを提供するように選択または調整できるため、この仕事にはるかに適しています。結果。例として、パーリン ノイズを使用して作成されたテクスチャ イメージを検索します。同じノイズ関数を使用して、たとえば数千のランダムな雲を作成できることがわかると思いますが、ノイズ関数を必要に応じて (シードや座標だけでなく) 調整することで、代わりに溶岩や銀河が得られる場合があります。ただし、それを調整することは簡単ではないかもしれません。

  4. 各呼び出しの入力座標の数によってノイズ関数の次元数が決まるため、2 次元マップ (またはテクスチャなど) の場合は 2 次元ノイズ関数を使用できます。次に、毎回 Noise2d(x,y) のように呼び出します。

あなたの状況では、私は 3 次元シンプレックス ノイズ関数を試します (シンプレックスはパーリン ノイズの作成者によるもので、より優れていると推奨されています)。

各星系の座標トリプレットは、1 つの結果番号を提供します。次の決定は次のとおりです。数字は何を表しているか? シンプレックス ノイズの平滑化機能を有効に活用するには、数値が小さいほど空の太陽系にマッピングし、数値が大きいほど質量の大きいシステムにマッピングします。または、システムコールごとに、サブ座標を使用してシンプレックスノイズを複数回呼び出す方がよいでしょう。中規模の結果の数字は惑星であり、小さな数字は真空または小惑星です。大きな数の星など

トピックはアクティブではなく、古いですが、私のように検索がここで終わる可能性があります。

于 2012-10-03T17:09:16.517 に答える
3

各太陽系のランダムなシードは実行可能な解決策ですが、ここで間違ったツリーを吠えているように感じます.

プレーヤーはそこにあるものを変更するために何かをすることができますか? (たとえば、何かを構築したり、枯渇しやすいリソースを採掘したりしますか?) もしそうなら、とにかく状態を保存する必要があります。

プレイヤーは実際にそこに戻らなくても、その場所がどのようなものだったかを調べることができますか? (そして、彼ができないのなら、なぜですか?!) あなたはそれを調べるつもりですか、それとも太陽系全体を再生させて、それに関する情報を見つけるだけですか? (PRNG ソリューションでは、太陽系の一部だけを取得することはできません。すべてを作成する必要があります。)

とにかく、保存する必要がある詳細はどれくらいありますか?

于 2008-12-08T02:43:52.400 に答える
2

「銀河」には、今日のコンピューターに保存できないほど多くの情報があるとは思いません。銀河には 100 個の星があり、各星には 10 個の惑星があり、各惑星には 3 つの月があるとします。それは 100 個の星 + 1,000 個の惑星 + 追跡しなければならない 3,000 個の月、つまり 4,100 個の天体です。

惑星のために追跡したいことは次のとおりです。

質量 X、Y、Z 位置 1 日の長さ (自身の軸を中心に回転する時間) 1 年の長さ 人口 50 種類のリソースのリソース量

各値を格納するために double が必要であり、格納する値が 57 個あると仮定すると (端数を切り上げて 100 とします)、100 個の値 * 8 バイト * 4100 個のボディ = 3,280,000 バイトになります。今、それは 3 メガのデータです。多いように思えるかもしれませんが、実際にはそれほど多くはありません。また、単一の銀河にこれほど多くの星を持ちたいとは思わないでしょう。ゲームは実際には大きすぎて探索できず、特定の銀河で起こっているすべてのものを実際にシミュレートしようとすると、おそらく手に負えないほど大きくなるでしょう.

このように見てください。SimCity のようなゲームで、都市グリッド上の各正方形を潜在的な惑星として見ると、小さなファイルにどれだけ多くの情報を保存できるかがわかるため、ランダムに何かを生成する必要はありません。

于 2008-12-08T01:05:09.713 に答える
2

銀河のシード、つまり 1234 から始めて、このシードを取り、10000 個の乱数を生成するとします。それぞれが星系を表します。星に近づくと、星の乱数を取得し、それを新しい乱数関数のシードとして使用します。星を周回する天体の数に対して乱数を生成し、天体ごとに 1 つの数値を生成します (常に 2 番目のランダム関数を使用します)。これが役立つかどうかはわかりませんが、ランダム関数は内部的に混沌としており、初期状態では関数全体が変化することを覚えておく必要があります。

銀河の星の種は常に同じ星を生み出さなければならず、星の種は同じ体を生み出さなければならない、など.

統計、密度計算、結果の改善を使用して、いつでも物事をより興味深いものにすることができます。関数が同じ入力に対して同じ結果を生成することを常に確認してください。

私の英語が下手で申し訳ありません、私はアルゼンチン出身で、英語は私の訓練された資質の1つではありません:p

PD: 私も同じタイプのゲームをやっています ;)

于 2011-03-30T15:18:22.940 に答える
2

メルセンヌツイスターを使っています。任意の長さのシード配列として受け入れるのは PRNG です。
たとえば、座標 x=25,y=72 に銀河を生成したいとします。ツイスターをシードで再初期化します [25,72]。
この銀河で 1138 番目の惑星を生成したい場合は、[25,72,1138] を使用します。
国?[25,72,1138,10]
市? [25,72,1138,10,32]
など。
この方法を使用すると、たった 1 つの数値 (x 座標の前の数値、この場合は 25 の前の数値) を使用して、数十億の数兆のオブジェクトを生成できます。
現在、それを使用するプロジェクトがいくつかあります。
ノクティス: anynowhere.com/ インフィニ
バース: http://www.infiniverse-game.com/

于 2010-12-03T09:00:58.577 に答える
0

同じシードでsrandom()を呼び出す限り、random()から同じ値を取得します。したがって、srandom()への1回の呼び出しに基づいて、スターシステムのすべてをベースにするだけです...次に、スターシステム全体に対して1つの整数(シード)を格納するだけで済みます。これで圧縮です!

于 2008-12-21T02:47:35.410 に答える
0

これは私の2番目の改善されたソリューションです。プレイヤーはランダムに生成された太陽系から始めます。各システムは、1〜4個の他のシステムに接続されています。それらを北、南、東、西のシステムと考えてください。プレイヤーが北のジャンプゲートを通過する場合、シードが以前のシステムより1つ多いシステムに移動します。彼が南に行くと、そのシステムのシードは1つ少なくなります。2+と2-それぞれ東と西。これらのシステムまでの距離(パーセクや光年など)は、システムのシードと到着する方向を使用して計算されます。このように、銀河のサイズは、シードを保持するために使用される数の最大値と最小値によってのみ制限されます。

他の銀河に行くためのワープホールは、開始システムから一定の距離に配置されます。次の銀河は、シード数が同じように増加し、銀河のワープホールの反対側にあるシステムが「東」または「北」になるという点で、この銀河の続きのようになります。 "起動システムからの接続。

ちなみに、シードをインクリメントするこの使用は、上記のソリューションとは異なり、ウェブにつながります。また、この方法では四角形を使用していますが、上記のソリューションでは六角形を使用しているため、ウェブを作成できませんでした。

もちろん、これはすべて、すべてのシードが他のシーケンスとは異なる数列をランダムに生成するという仮定に基づいています。これにより、各システムが一意になります。

于 2008-12-21T02:48:57.233 に答える
0

皆さんが直面するであろう最大の問題は、これらすべてのオブジェクトに一貫性があり、プレイヤーにとって意味のある名前を付けるための命名システムを用意することだと思いますが、実際のオブジェクトを体系的に命名するためのスキームはあります。Eliteの命名規則はある時点で崩壊したかどうかを忘れています...

于 2010-12-03T09:28:43.440 に答える
0

これが私が思いついたものです。ただし、それが最終バージョンになるかどうかはわかりません。

六角形のグリッドと、各頂点にある太陽系を想像してみてください。六角形のグリッド上にいるため、どの頂点からも 3 本の線しかありません。1 つは常に水平で、残りの 2 つは対角線です。開始シードに n の値を与えると、開始点に水平に接続された太陽系に n+1 の値を与えることができ、他のものは n+2 と n-2 の値を取得します。

やばい。必ずしもグリッドが得られるとは限りません。くそ。もう一度試してみましょう。

于 2008-12-08T01:04:24.490 に答える
0

これが以前に行われたことを漠然と思い出すことができます。90 年代初頭にフラクタルが大流行し、ある会社がゲーム プログラマーに世界を提供していたことを覚えています。太陽と惑星、惑星上の場所の谷とテクスチャに至るまでのイベントで、銀河でいっぱいの無限の宇宙全体を作成しました。彼らは、ゲーム開発者に適切な仮想不動産を見つけることを申し出ていました。ゲーム開発者は、このフラクタル ユニバース内のプロパティの正確な座標とともに、これをレンダリングして使用するソフトウェアを取得します。

「フラクタル ゲーム ワールド プラネット ユニバース」などを数分間グーグル検索しましたが、見つかりませんでした。パンドロメダだったかもしれませんが、よく覚えていません。

このアイデアのためにフラクタルを研究する必要があります。必要なのは、シードから再作成し、それらの数値をさまざまなプロパティを持つ星、惑星、および衛星として提示できる連続した数値フィールドだけです。

于 2008-12-08T00:01:51.400 に答える
0

特定のシード (「母数」) からN桁の疑似乱数を作成できます。次に、数字をグループに分けて、質問に答えるために使用します。

例: N =20

-> 1 桁: 追加のジャンプ ゲートの数は?
-> 3 桁: 利用可能な各ジャンプの長さを生成するためのシード
-> 6 桁: この太陽系
を生成するためのシード -> 10 桁: リンクされた各太陽系の新しい 20 桁のシードを生成するためのシード

次に、再帰します。各システム (安定した軌道など) は時間 0 で生成され、現在どのように見えるかを計算する必要があります。

もちろん、マザー システムから開始するこのアプローチは、現在のシステムがマザー システムから離れているほど、データの生成に時間がかかることを意味します。また、この方法では、ネットではなくツリーが作成されます (これは私が期待することです)。

座標を生成する方が良いと思います-平面で極座標を使用し、おそらく3次元で楕円体を使用します。

于 2008-12-08T00:04:56.543 に答える
0

本当に固定状態に戻したいのであれば、単一の値からの手続き型生成は正しい方法ではないと思います。

各平面に 256x256 システムの固定グリッドがあり、ユニバースに 16 平面があるとします。各飛行機には、最大 512 のトレーディング ステーションと、他の飛行機への最大 8 つのリンクがあります。すべてのトレーディング ステーションとリンクは固定位置にあります。可能なすべてのユニバースをエンコードするには、初期シード値が少なくとも 2^76 である必要があります。さらにいくつかのオブジェクト (惑星、船など) を追加すると、その数は指数関数的に増加します。

編集: 各システムで複数のトレーディング ステーションまたはリンクを許可しない場合は、少し少なくなります。Firebird や sqlite などの組み込みデータベースなど、永続的なストレージを使用します。ちなみに、私は現在そのようなゲームを開発しています。

于 2008-12-08T00:22:49.707 に答える
0

擬似乱数ジェネレーターを使用すると、生成する各乱数が特定のシードから同じ順序で表示されることを保証できます。特定の数値でシードされたシステムを生成するコードは、生成するたびに同じように表示されます。

疑似乱数ストリームの最初の数値を使用して、「ゲート」の数を生成します。各ゲートを通過し、数値​​ストリームから値を取得して、各ターゲット システムに割り当ててシードします。

そのシードに基づいて各システムの機能を生成します。

ランダム シードを生成するための既知のアルゴリズムがいくつかあります。

メルセンヌツイスターにクラックを与える

于 2008-12-08T01:57:19.250 に答える