Procedural generation

Cellular Automata

セルオートマトン

近傍セルの状態から洞窟や模様を育てる。

4 / 10

Interactive demo

Preparing the demo…

Cellular Automata

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

マス目の各マスが「壁/床」のような状態を持ち、周りのマスの状態から次の状態を決めるルールを、全部のマスに同時に当てはめることをくり返す仕組みです。ルールは局所的で単純なのに、くり返すと洞窟のような有機的な形や、生き物のように動く模様が生まれます。ゲームでは、でたらめな初期状態から数回くり返すだけで自然な洞窟ができる方法として有名です。

ゲームでの使いどころ

  • 洞窟の生成:でたらめに壁をばらまき、「周りに壁が多ければ壁、少なければ床」のルールを数回かけるだけで、なめらかな洞窟ができる(ローグライクの定番)。
  • 地形・島の形:陸と海のマスに同じ考え方を使って、海岸線をなめらかにする。
  • 広がる現象:火の延焼、水や毒の広がり、植物の繁殖、病気の感染などを、マスごとのルールで表す(『Noita』はこの考え方を大規模に使っている)。
  • 模様:ライフゲームや反応拡散のような、動く模様・生き物っぽい模様。

しくみ

洞窟生成の「4-5 ルール」では、各マスについて周りの 8 マスのうち壁の数 nn を数え、次のように決めます。

次の状態={壁(今が壁で n≥4)壁(今が床で n≥5)床(それ以外)\text{次の状態} = \begin{cases} \text{壁} & (\text{今が壁で } n \ge 4) \\ \text{壁} & (\text{今が床で } n \ge 5) \\ \text{床} & (\text{それ以外}) \end{cases}

壁に囲まれた床は壁に、床に囲まれた壁は床になるので、1 回ごとに孤立した点が消え、壁の縁がなめらかになっていきます。4〜5 回で十分です。マップの外は壁とみなすと、外周が壁で閉じた洞窟になります。

ライフゲーム(B3/S23)は、「ちょうど 3 つの生きたマスに囲まれた死んだマスが生まれ、2 つか 3 つに囲まれた生きたマスが生き残る」というルールです。

大事な点:すべてのマスを「同時に」更新します。更新した結果を同じ配列にその場で書き込むと、先に更新したマスの影響が後のマスに混ざり、結果が偏ります。

実装のポイント

  • 最初の壁の割合:45% 前後が目安です。多いと小さな洞窟がばらばらに、少ないと大きな空間ばかりになります。
  • つながりの確認:生成した洞窟は、いくつかの離れた空洞に分かれていることがあります。塗りつぶし(幅優先探索)で床の領域に番号を付け、一番大きな領域だけを残すか、ほかの領域とトンネルでつなぎます。
  • 見た目の仕上げ:マス目のままだと角ばるので、マーチングスクエアでなめらかな輪郭のメッシュにします。
  • GPU で動かす:各マスの計算が独立しているので、シェーダーで大量のマスを一度に更新できます。

つまずきやすい点

  • 行けない空洞:プレイヤーが入れない空洞に宝やゴールを置いてしまう事故がよく起きます。生成後に必ずつながりを確認します。
  • ルールと割合の相性:ルールのしきい値と最初の壁の割合の組み合わせによっては、全部が壁になったり、全部が床になったりします。
  • 大きな構造は作れない:局所のルールなので、「入口と出口」「部屋の数」のような全体の構造は決められません。BSPなどで大まかな配置を決めてから、細部に使う組み合わせがよく使われます。

デモで試すこと

  1. 最初の雑音のようなマス目が、くり返すたびに小さな点が消え、なめらかな洞窟の壁になっていきます。数値の「くり返し」と見比べてください。
  2. 赤い床は、一番大きな洞窟とつながっていない小さな空洞です。「小さな空洞を埋める」で、行けない場所を壁にできます。
  3. 「最初に壁にする割合」や「床が壁になる壁の数」を変えると、洞窟の広さや複雑さが大きく変わります。
  4. 「ライフゲーム」に切り替えると、同じ「周りの数で次を決める」仕組みで、動き回る模様が生まれます。

References

WaveFunctionCollapse ↗

A general reference for this subcategory.