Tile-Based Map Generation using Wave Function Collapse in 'Caves of Qud'

GDC
11 Apr 202222:17

Summary

TLDRブライアン・バクリィは、プロシージャル生成ゲーム「ケイブズ・オブ・カット」の開発者であり、同社の共同創業者であるフリーホールド・ゲームズのメンバーです。彼は、ゲームのマップ生成に使用されている「波動関数崩壊」という手法について語りました。この手法は、パーリンノイズなどの一般的な手法に加えて、新しい手法も使用していると述べました。波動関数崩壊は、俄国の数学者マキシム・グーマンによって開発され、MITライセンスで公開されています。この手法はタイルベースのマップデザインにも適用できますが、彼らはテクスチャモードを使用し、小さなトレーニング画像から任意の大きさの出力を生み出すことができます。この手法は、タイルの隣接性を強力に制約づけることができるため、より強力な結果を得ることができます。また、この手法を応用して、マップのセグメント化や詳細なドアや家具の配置など、より複雑なマップを生成する方法についても説明しました。最後に、この手法を他のプロジェクトに取り入れることの容易さと、ドキュメントの充実度について触れ、話は終了しました。

Takeaways

  • 🎮 Brian Buckleyは、Freehold Gamesの共同創設者で、ゲーム「Caves of Qud」の開発に携わっています。
  • 🧩 「Caves of Qud」は、プロシージャル・ジェネレーションを用いて、タイルベースのゲームマップを作成しています。
  • 📈 ゲームのマップは80×25タイルで、壁、生物、植物などの要素が抽象的に表現されています。
  • 🌐 Wave Function Collapse(WFC)というテクスチャ合成手法を使用し、マップの多様性を実現しています。
  • 🤖 WFCは、ロシアの数学者Maxim Guminによって開発され、MITライセンスで公開されています。
  • 🔍 WFCはタイルとテクスチャの2つのモードで動作し、小さなトレーニング画像から大きな出力を生み出すことができます。
  • 🛠️ WFCは、入力されたトレーニング画像に基づいて、すべてのタイルの可能性を超位置状態にし、徐々に選択を狭めます。
  • 🏗️ ゲームマップの生成では、WFCを用いて大域的な構造を作り、その後詳細を手動で追加することで、均質性の問題を解決しています。
  • 🔄 WFCを使用する際には、同種のタイルが繰り返し生成されることを避けるため、制約を追加することが重要です。
  • 📉 過剰適合を防ぐために、WFCの出力を用いて基本的な壁構造を生成し、その後にドアや家具などの詳細を追加します。
  • 🔢 WFCのトレーニングセットは、できるだけ小さな画像を使用し、必要とする性格を詰め込んでいます。
  • 🔄 対称性を使用することで、WFCは同じタイルが異なる角度で繰り返されることを防ぎ、タイル配置の多様性を確保できます。

Q & A

  • ブライアン・バクリーが開発したゲームは何ですか?

    -ブライアン・バクリーが開発したゲームは「Caves of Qud」です。

  • Caves of Qudのマップ生成にはどのような手法が使用されていますか?

    -Caves of Qudのマップ生成には、パーリンノイズなどの一般的な手法に加えて、波動関数崩壊という新しいテクスチャー合成手法が使用されています。

  • 波動関数崩壊とは何ですか?

    -波動関数崩壊は、マキシム・グーマンというロシアの数学者が開発した、タイルベースのプロシージャル生成手法です。タイルやテクスチャに対して作用し、入力されたトレーニング画像の性質を持ちながら、より大きな出力を生み出します。

  • 波動関数崩壊の訓練画像はどのくらいの大きさが良いですか?

    -波動関数崩壊の訓練画像は、8x8ピクセルや16x16ピクセルなどの小さいサイズが効果的です。訓練画像が小さいほど、より強力な結果を得ることができます。

  • Caves of Qudのマップはどのようにして生成されますか?

    -Caves of Qudのマップは、波動関数崩壊手法を使用して生成されます。タイルベースのゲームであるため、各マップは80x25タイルで構成され、壁、生物、植物などが抽象的な形で表現されています。

  • 波動関数崩壊手法を実装する際のコードは複雑ですか?

    -波動関数崩壊手法を実装する際のコードは、3行のシンプルなコードで済むため、複雑ではありません。モデルを初期化し、実行させ、出力を取得するだけで済みます。

  • Caves of Qudのマップ生成で直面した問題は何ですか?

    -Caves of Qudのマップ生成で直面した問題は、同質性とオーバーフィッティングの2つです。同質性は、大きな出力が均質的になる傾向があることを意味し、オーバーフィッティングは、訓練画像に色を追加することで出力が多様でなくなる傾向があることを意味します。

  • 同質性の問題はどのように解決されましたか?

    -同質性の問題は、出力空間をセグメント化し、波動関数崩壊を使用して詳細を埋めることで解決されました。これにより、均質的な出力ではなく、より興味深いグラフ構造が得られます。

  • オーバーフィッティングの問題はどのように対処されましたか?

    -オーバーフィッティングの問題は、波動関数崩壊の出力を用いて高いレベルの壁構造を生成し、その後のプロセッシングでドアや家具などの詳細を生成することで対処されました。

  • Caves of Qudの開発チームはどのようにして波動関数崩壊手法を実装しましたか?

    -Caves of Qudの開発チームは、ゲームのアエスセティックに沿って、生成システムを自由自在に動かし、出力を組み合わせることで実装しました。また、タイルベースの手法を用いて、デザイナーが制御できるプリファブを組み合わせることで、より細かい制御が可能です。

  • 波動関数崩壊手法のリポジトリはどの言語で利用できますか?

    -波動関数崩壊手法のリポジトリは、20以上の異なる言語で利用可能です。MITライセンスで公開されており、幅広く利用されています。

Outlines

00:00

🎮 プロシージャルジェネレーションの紹介とWFCの活用

Brian Buckleyが開発したゲーム「Caves of Qud」のプロシージャルジェネレーションについて紹介。特に、Wave Function Collapse (WFC)という手法について解説し、ゲーム内のマップ生成にどのように応用されているかを説明。WFCは、タイルベースのマップデザインに適しており、小さなトレーニング画像から大きな出力が生成できるという驚くべき機能を持ち、ゲームのマップ生成において非常に強力なツールとなっている。

05:01

🧠 WFCアルゴリズムの基礎と動作原理

WFCアルゴリズムの基本的な動作原理について解説。アルゴリズムは、入力されたタイルを3x3タイルのスーパーポジションとして開始し、逐次的にタイルを選択して確定化していく。このプロセスでは、タイル間の隣接性制約を利用して、最終的なマップを生成。Brianは、WFCの決定プロセスを視覚的に説明し、どのようにして隣接するタイルを選択し、マップを確定させるかを解説。

10:03

🏡 テクスチャモードでのWFC実験とマップ生成

BrianがテクスチャモードでWFCを実験し、タイルマップを構築する手法を探求した経験について語る。最初の試みでは、単純な3色パターンから始め、空間的整合性を持つ結果を得ることができた。さらに、より複雑なトレーニング画像を用いて自然な庭園のような構造を生成することができると示す。WFCのパラメータ設定についても触れ、同質性の問題やオーバーフィッティングの問題に対する解決策として、出力空間のセグメント化とポストプロセスを使用した方法を紹介。

15:04

🛠️ WFCを用いたマップ生成のプロセス

Brianが実際にCaves of Qudのマップを生成するプロセスを説明。大まかなセグメント化から始め、WFCを使用して詳細を埋め、単純なA*アルゴリズムでドアの設置などを行う。この手法により、複雑なマップが生成されるが、プロセスは非常に単純である。また、WFCを使用する際の設計に関する議論や、他のチームがどのようにWFCを応用しているかについて触れる。

20:05

📚 WFCアルゴリズムの応用と改善

WFCアルゴリズムに追加の制約を加えることで、特定の領域内にタイルが繰り返し表示されないようにするなどの改善が提案された。Brianは、実際には追加の制約を試行錯誤したが、問題に遭遇したため、基本的なWFCの活用に留めた。また、より詳細なトレーニングセットを使用することで、隣接する素材のバリエーションを増やす方法についても議論。最後に、聴衆からの質問に対して応答し、WFCの応用に関する洞察を提供。

Mindmap

Keywords

💡プロシージャルジェネレーション

プロシージャルジェネレーションは、コンピュータグラフィックスやゲーム開発でよく使われる手法で、アルゴリズムを用いてランダムに生成された環境やオブジェクトを作成します。このビデオでは、ゲーム「Caves of Qud」のマップ生成に使われています。

💡パーリンノイズ

パーリンノイズは、グラフィックスソフトウェアで使用されるノイズ関数で、自然現象をシミュレーションするために使われます。ビデオでは、マップのプロシージャル生成で使用される一般的な技術の一つとして言及されています。

💡ウェーブファンクションコラプス

ウェーブファンクションコラプスは、タイルベースのマップ生成に用いられるテクスチャ合成手法で、小さなトレーニング画像から大きな出力を生み出すことができます。ビデオでは、この手法がゲームのマップ生成にどのように適用され、多様な結果を生むかに重点的に説明されています。

💡トレーニング画像

トレーニング画像とは、ウェーブファンクションコラプスで用いられる小さな入力画像のことです。これらの画像は、アルゴリズムに生成する結果の性質を教える役割を果たします。ビデオでは、8x8や16x16の小さなサイズのトレーニング画像が強力な結果を生むと示されています。

💡タイル

タイルは、タイルベースのゲームマップで使用される正方形のブロックで、マップの地形や構造を形成します。ビデオでは、タイルがウェーブファンクションコラプスアルゴリズムによってどのように生成されるかが説明されています。

💡エントロピー

エントロピーは、情報理論で使用される概念で、システムの無序さを測定します。ビデオでは、ウェーブファンクションコラプスアルゴリズムが最初にエントロピーが低いタイルを選択することで、ランダム性から始めながらも決定的な結果に至るプロセスを説明しています。

💡同質性

同質性は、生成されたマップが同じような構造で構成される傾向を指します。ビデオでは、ウェーブファンクションコラプスが生成するマップが同質的になる問題と、それがどのように解決されるかが議論されています。

💡オーバーフィッティング

オーバーフィッティングは、学習アルゴリズムがトレーニングデータに過剰に適応し、汎化能力が低下することを指します。ビデオでは、ウェーブファンクションコラプスで高レベルの壁構造を生成し、詳細を後処理で追加することでオーバーフィッティングを防ぐ方法が説明されています。

💡A*アルゴリズム

A*アルゴリズムは、経路探索問題を解決するための有効な手法で、ゲーム開発でよく使われます。ビデオでは、A*アルゴリズムを使ってマップ内のドアの位置を決定し、マップの詳細を生成するプロセスが説明されています。

💡MITライセンス

MITライセンスは、ソフトウェアがオープンソースで配布される際によく使われるライセンスです。ビデオでは、ウェーブファンクションコラプスがMITライセンスでリリースされ、誰もがプロジェクトに組み込むことができると説明されています。

Highlights

Brian Buckley, co-founder of Freehold Games, discusses the game 'Caves of Qud' which utilizes procedural generation.

The game features a procedural generation technique called 'wave function collapse' developed by Russian mathematician Maxim Gootman.

Wave function collapse operates in two primary modes: tiles and textures, offering powerful results for tile-based map design.

The technique uses small training inputs to produce arbitrarily large outputs with the character of the input image.

An algorithm can be applied to generate different map types, from rectilinear rooms to naturalistic gardens, using simple training inputs.

The algorithm begins by chopping the input into n by n tiles and sets up the output as a superposition of all possible tiles.

The process involves selecting tiles at random and collapsing them down to a single tile based on entropy and adjacency.

The algorithm propagates by removing adjacencies from the list as it continues to select tiles.

The technique can create complex and varied outputs from simple training inputs, offering a single algorithm for multiple map generation styles.

The speaker shares initial experiments with the algorithm, highlighting the creation of structured outputs like square buildings for a village.

To address homogeneity, the output space is segmented, and WFC is used to fill in details with different character.

Overfitting is solved by using WFC to generate high-level wall structures and post-processing to add detailed elements like doors and furniture.

The algorithm is simple to implement, requiring only a few lines of code for initialization, running, and obtaining the output image.

Design challenges are addressed by segmenting the map and using WFC for broad strokes, followed by detailed prefabs.

The speaker discusses the aesthetic of 'Caves of Qud', which embraces the generative systems and allows for unique game environments.

The repository for WFC is well-documented and available in multiple languages, making it accessible for integration into various projects.

The talk concludes with a Q&A session addressing practical implementation, communication with traditional level designers, and potential constraints within the algorithm.

Transcripts

play00:02

[Music]

play00:05

why are we here

play00:06

uh caves of cud is a game that i develop

play00:10

i'm brian buckley i'm a co-founder at

play00:12

freehold games

play00:14

caves of cut has

play00:15

a ton of procedural generation

play00:17

we use a bunch of normal techniques that

play00:19

you've heard of perlin noise etc

play00:21

and we use a few novel techniques and

play00:23

today we're going to talk about a

play00:25

specific one wave function collapse

play00:27

which sounds scary but i hope by the end

play00:29

you'll realize it's not particularly

play00:30

terrifying

play00:32

so we're going to first start by looking

play00:34

at some final results that we get by

play00:35

utilizing this technique

play00:37

and then we'll go through some slides to

play00:39

talk about how we get there

play00:41

so here's a map in caves of cut if

play00:43

you're not familiar with it it's a

play00:44

tile-based game so each of the maps is

play00:47

80 by 25 and it's very discreet so you

play00:49

can see walls and creatures and plants

play00:51

here and they're represented in a sort

play00:52

of abstract way so here we have a sort

play00:55

of rectilinear palace it has sort of an

play00:58

outer wall

play00:59

and inner buildings and they're

play01:00

populated by various things blood

play01:02

splatters and centipedes and gardens

play01:06

and here we have an underground map

play01:07

where we have some very narrow corridors

play01:09

goalies full of water

play01:12

little rooms full of water this is very

play01:14

sort of maisy narrow map

play01:17

and here we have a

play01:19

circular tower embedded in some rock

play01:21

salt it's filled with bears i guess an

play01:23

asphalt

play01:25

and a little statuary on the right it's

play01:27

got

play01:28

sort of curvy labyrinthine halls

play01:31

and here we have a little town we've got

play01:33

maybe a big ruined civic structure up

play01:35

north and in the south we have

play01:38

a bunch of rectilinear village buildings

play01:40

adjacent laid out along a nice forested

play01:43

path

play01:46

so these are a wide

play01:48

variety of results but the result of a

play01:50

single algorithm so these each had a

play01:52

very different character you had little

play01:54

maisy corridors you had a fairly

play01:56

dispersed village with well-ordered

play01:58

buildings you had a

play02:00

water filled goalies

play02:02

and instead of using an individual

play02:04

technique to generate each of these we

play02:05

use a powerful new texture synthesis

play02:07

technique called wave function collapse

play02:09

alongside a few other tools that we use

play02:11

to supplement its weaknesses when

play02:14

applied to maps

play02:16

so wave function collapse it was

play02:17

developed by a russian mathematician

play02:19

named maxim gooman released open source

play02:22

mit licensed and the repositories out

play02:24

here it's in 20 different languages you

play02:26

can go out there and download it now and

play02:27

use it hopefully after this talk you'll

play02:29

be able to go out there and build into

play02:30

your projects

play02:31

caves of code was its first commercial

play02:33

commercial use a bunch of others quickly

play02:35

followed because it's such a powerful

play02:36

technique

play02:39

wave function collapse has two primary

play02:40

modes it operates on tiles

play02:43

and operates on textures

play02:46

if you do procedural generation you've

play02:48

probably encountered wong tile maps

play02:50

which are based on edge colored

play02:51

adjacencies

play02:52

the tile map generation is sort of

play02:54

similar to that but

play02:55

the adjacency constraints are much more

play02:57

powerful than edge coloring you can get

play02:59

a much more powerful result so if you're

play03:01

interested in tile-based

play03:03

map design

play03:04

this is great we're not going to talk

play03:05

about it

play03:07

instead we use texture mode

play03:09

texture mode

play03:10

uses small training inputs they can be

play03:12

big but it's most powerful when they're

play03:14

small

play03:16

maybe 8 by 8 or 16x16 training images

play03:19

and they can produce arbitrarily large

play03:20

outputs with the character of that input

play03:22

training image

play03:24

this is pretty amazing so on the left

play03:26

you have three separate inputs and the

play03:29

top you see a sort of rectilinear room

play03:31

hall and you can see seven sample

play03:33

outputs here just bigger you can see

play03:35

that each of them has a pretty different

play03:37

layout but

play03:38

shares structurally uh the same

play03:41

character as the input

play03:42

on the second row you see some caves

play03:45

these are caves that you would typically

play03:46

generate via cellular automata system or

play03:49

something

play03:50

or box filters something very different

play03:52

from that that first rectilinear room

play03:55

hall arrangement

play03:56

and then third you see an input texture

play03:58

that's five by five simple couple dots

play04:00

in a line and you get some very complex

play04:03

uh

play04:04

quilted patterns and this would be some

play04:06

custom line drawing technique so instead

play04:08

of having to have three very different

play04:10

algorithms you're able to have

play04:12

one single algorithm that's fed

play04:14

different very simple training inputs

play04:16

this is something you can pop open ms

play04:17

paint right any training input and throw

play04:19

it through the algorithm

play04:20

very cool so i'm going to run quickly

play04:23

through this text slide don't feel like

play04:24

you have to load this into your brain

play04:25

we're going to walk through it more

play04:26

carefully i just want to prime your

play04:28

system for

play04:29

what we're going to talk about i'm

play04:30

actually not going to go way down to the

play04:32

nuts of bolts of this algorithm they're

play04:33

good papers to do that i want to give

play04:35

you a intuitive understanding of how

play04:37

this algorithm is making decisions when

play04:38

it's painting its output

play04:40

so first what it does is it chops it up

play04:42

into n by end tiles

play04:44

n is something you pick um

play04:46

three is a very typical size so it's

play04:49

going to operate on individual three by

play04:51

three tiles chop up your input image

play04:53

into those it's going to operate on

play04:55

those as its basic atom you can choose

play04:57

bigger or smaller atoms depending on

play04:59

the character you want out of your

play05:00

output then we output

play05:02

the or we set up the output as a

play05:04

superposition of all those possible

play05:06

tiles so you can imagine each element of

play05:08

the output being superimposed of each of

play05:10

the tiles that are pulled out of the

play05:11

input and this is the character it

play05:13

shares with quantum wave function

play05:15

collapse it's it's sort of a snide

play05:17

relationship it's not anything

play05:19

complicated

play05:20

what it does then is it picks one at

play05:22

random to start with and says well of

play05:24

all these possible tiles we're going to

play05:26

select the lowest in by an entropy area

play05:29

and pick one at random and collapse it

play05:31

down to a single tile

play05:32

and then it's got some new information i

play05:34

know that this tile exists these

play05:36

adjacencies are removed from the list

play05:39

and then it continues until every output

play05:41

has only a single selection and that's

play05:43

pretty much it so didn't catch that

play05:45

we'll walk through that in a little more

play05:46

detail here so the first thing it does

play05:48

is it identifies all the in-by-end

play05:50

patterns

play05:51

so the example here i'm going to use is

play05:52

a very simple three color training input

play05:55

it's got red on the outside and a green

play05:56

box and a blue inside and so it's going

play05:58

to chop it up into all these three by

play06:00

three patterns so i'm showing you five

play06:02

here but they're obviously a bunch in a

play06:04

nine by nine box without wrapping it's

play06:05

gonna be like 49 and uh if you allow

play06:08

wrapping it's like what a 81.

play06:10

if you allow symmetries and rotations

play06:12

it's much more

play06:14

then it goes through and for each tile

play06:16

it figures out where do the other tiles

play06:18

overlap and it's going to use this

play06:19

information in order to do the

play06:21

propagation

play06:22

and so here i'm just showing an example

play06:24

you've got two tiles and you can see

play06:26

that

play06:26

the first tile on the left it overlaps

play06:28

with the two tiles below it sharing

play06:30

those six red pixels

play06:33

so this is an example output of an wfc

play06:36

run so let's unpack what we're looking

play06:38

at here a little bit on the very left

play06:40

you see the training input what you're

play06:41

seeing is the first four steps of the

play06:44

wfc collapse

play06:46

in the very first frame the white

play06:48

outline box is the three by three tile

play06:50

it's decided to collapse it then steps

play06:52

through one three by three section at a

play06:55

time and selects an output tile that

play06:57

correctly overlaps the existing tiles

play06:59

that it knows about and it steps through

play07:00

the image until all of them are

play07:01

collapsed from the existing input data

play07:04

so to give you a real idea what's going

play07:06

on

play07:07

if you look at the area in the box it's

play07:09

very clearly green blue

play07:12

that's a single

play07:13

non-superimposed result the rest of the

play07:16

blending pixels is a visualization of

play07:19

the output tiles that are remain for

play07:21

that available for that area

play07:24

superimposed on one another so pixels

play07:26

that have sort of a green blue box they

play07:28

can still be either green or blue

play07:30

depending on what tiles remain to be

play07:32

chosen

play07:33

so let's look very specifically at this

play07:35

first step and try to build an intuition

play07:38

for how it makes these decisions let's

play07:40

look at this strip of three pixels here

play07:43

unlike the pixels to the left you can

play07:45

see these blue pixels are a little green

play07:47

which means they still have some

play07:49

possibility to become green pixels so

play07:51

why is this

play07:53

well we look to the left of this pattern

play07:56

and we see to the left of this pattern

play07:58

in the input is a strip of blue blue

play08:00

green

play08:02

and where can we find this in the input

play08:04

pattern we can essentially find it in

play08:05

these three places we can find it here

play08:08

each of these magenta boxes

play08:10

is what the output column we're thinking

play08:12

about might be

play08:14

in this case in the most leftmost case

play08:17

you can see left of that is blue blue

play08:19

green

play08:20

and the second case left of that is blue

play08:22

blue green and third case left of that

play08:23

is blue blue green so these are all

play08:25

these could all slot in there

play08:27

two of these outputs that column is blue

play08:29

blue green and the third possible output

play08:31

the column is green green green and so

play08:33

we can see

play08:35

here we go if

play08:36

if we look at

play08:37

two blue blue green inputs and one green

play08:39

green green input you can see that the

play08:41

probability is

play08:42

two blues and one green for each of

play08:44

those top two pixels and oh it's always

play08:47

going to be green in the output so you

play08:48

can see that we though we've selected

play08:51

that

play08:52

initial three by three box we know quite

play08:54

a bit about what possible adjacencies

play08:56

exist based on the input image

play08:59

and so again looking at this you should

play09:01

have a better idea sort of intuitively

play09:02

what it's doing each of these white

play09:04

boxes is selecting for sure what these

play09:06

pixels are in each case it knows a

play09:08

little bit more about the possibilities

play09:10

that remain and it simply sort of flood

play09:12

fills around the area to make it work

play09:15

so let's watch this work it's fun

play09:17

so we have

play09:18

five training inputs on the left we have

play09:19

a little white box

play09:21

a little red box

play09:23

sort of more complex temple

play09:25

you can watch in real time as it decides

play09:28

usually from the edges

play09:29

what the possibilities are

play09:31

and then

play09:32

folds in those

play09:34

overlapping potentials

play09:36

until we've got a final image and you

play09:38

can obviously run this many times and

play09:40

get a different output each time

play09:54

pretty fun so you can get big complex

play09:56

outputs from little inputs

play10:00

so that gives you an idea of how the

play10:02

technique works again you don't have to

play10:04

understand it when i started

play10:05

experimenting with it i had no clue what

play10:07

was going on so i i'm sort of a hands-on

play10:09

learner so i just tried to give it input

play10:11

and

play10:12

see what it see what happened and so

play10:13

this was my first experiment in texture

play10:15

mode in respect to building tile maps i

play10:17

wanted to build structured output so in

play10:20

this case i was like well can i make it

play10:21

build little square buildings for a

play10:23

village that would be neat

play10:25

i gave it a black box on a white

play10:28

background and i did not get a bunch of

play10:30

little square buildings and it turns out

play10:33

that's because

play10:34

what is the image telling it it tells

play10:35

it's telling it basically on the order

play10:38

of three by three pixels that a line can

play10:40

turn left or a line can turn right or a

play10:42

line can go straight you'll notice that

play10:44

there's no overlaps but there's also

play10:47

no training in that image that tells

play10:49

that there's an inside and out to side

play10:50

of the square there's no spatial spatial

play10:53

relationship between those turns and so

play10:55

you get the output there

play10:56

i said well what if i had

play10:59

a third color so now i've got white and

play11:01

i've got black and i've got red inside

play11:03

this suddenly produces the kind of

play11:05

spatial coherence that i want across the

play11:07

map you've got little red filled boxes

play11:09

that's awesome because not only do you

play11:11

get the spatial coherence but you also

play11:12

get some structural hinting the red

play11:15

pixels tell me hey that's the inside of

play11:16

a place and when you're building a map

play11:18

that's a pretty interesting distinction

play11:20

to be able to pull out of a real simple

play11:22

texture okay well something i can put

play11:23

furniture inside and plants outside and

play11:25

that looks

play11:26

like a already a coherent village with

play11:28

almost nothing going on we've got a

play11:30

three color texture going into it

play11:33

here's another example as i get more

play11:35

comfortable playing with it hey what if

play11:36

i feed a bigger training image do i get

play11:39

noise or do i get something interesting

play11:40

i get something interesting that's cool

play11:43

another example i said well can i

play11:44

produce sort of naturalistic gardens

play11:46

sure i mean these are like eight second

play11:48

experiments in ms paint this is i'm not

play11:50

i'm not spending 20 hours learning to do

play11:53

high level math

play11:54

so maybe i'm in the wrong lecture also

play11:58

here's an introductory shape and keep

play11:59

this in mind because we're going to

play12:00

return to the star shape i added an

play12:02

additional color here and you can see

play12:03

you get star-like shapes

play12:05

not identical stars but some variation

play12:08

and that's pretty interesting

play12:11

how to use this in your code probably

play12:12

the most interesting slide for people

play12:14

it's not complicated it's three lines of

play12:16

code you initialize the model you tell

play12:18

it to run and you get the output image

play12:21

and that's it and let's take a look at

play12:23

the inputs because sometimes

play12:25

the complexity is hidden in the in the

play12:27

parameterization for wfc it's not

play12:29

there's not even any complexity there

play12:31

you give it the training image you say

play12:33

what is the n i want i want it to be two

play12:34

or three or four

play12:36

how big do i want the output to be do i

play12:38

want the input to wrap across edges do i

play12:40

want the output direct cross edges and

play12:42

do i want it to sample with symmetry

play12:44

symmetry is a little bit interesting not

play12:46

very complicated if you're for instance

play12:48

putting in something where orientation

play12:50

matters and you've got ground at the

play12:51

bottom at sky at the top you probably

play12:52

don't want symmetry unless you want to

play12:54

end up with sky at the bottom if you've

play12:55

got buildings where you don't care about

play12:57

the orientation you want to probably

play12:58

crank that symmetry up to eight where

play13:00

you've got full reflection and

play13:01

rotational symmetry

play13:04

so

play13:05

applied to map design these are not

play13:06

problems with the algorithm per se but

play13:08

only domain specific problems what

play13:10

problems did we run into when we tried

play13:12

to use this problem one was homogeny the

play13:15

outputs are

play13:16

as you get bigger and bigger just

play13:18

completely homogeneous in all directions

play13:19

they're interesting at the small scale

play13:21

but you don't really want to walk across

play13:23

an infinite homogeneous plane of these

play13:24

buildings

play13:26

problem two is overfitting and so we'll

play13:28

return to the star shape

play13:30

one of the things you want to do in maps

play13:31

is have more interesting details than

play13:33

walls you want to have doors and where

play13:35

the monsters are and where the furniture

play13:37

is etc etc and you might think that well

play13:40

let me add more colors to the wfc input

play13:43

and that of course was the first thing i

play13:44

tried the reality is as soon as you

play13:46

start adding more and more colors less

play13:48

of these tiles tend to overlap and so

play13:50

you tend to get

play13:52

very

play13:53

uh

play13:54

very non-varied outputs because the

play13:56

tiles can fit together only in one

play13:57

particular way and so instead you just

play13:59

reflect and rotate the shape across

play14:00

space

play14:02

so how do we solve these

play14:05

the solution to

play14:06

homogeny was very simple we segmented

play14:09

the output space and then used wfc to

play14:11

fill in details

play14:13

so in this case this very simple example

play14:15

we've segmented this map into three high

play14:16

level chunks and each of them is filled

play14:18

with a wfc input with different

play14:20

character so this produces a

play14:22

high level

play14:24

graph that's more interesting than a

play14:25

homogeneous output and then the

play14:27

interiors that interior detailing which

play14:29

can be quite difficult to get with uh

play14:31

standard procedural techniques can be

play14:33

highly varied because you can pick from

play14:35

a big library of 500 templates you made

play14:37

in ms paint and get some really

play14:38

interesting complex output

play14:41

how do we deal with overfitting the

play14:42

solution to overfitting was pretty

play14:44

simple which was to use the output of

play14:46

wsc in order to generate high level wall

play14:49

structure and then use a post-processing

play14:51

pass to generate the more detailed uh

play14:54

more detailed things like doors and

play14:55

furniture you can imagine a bunch of

play14:57

ways to do this i'm going to show you

play14:58

one of the full run throughs that we did

play15:00

we did to get a level in caves of cod

play15:04

so here's a real simple example first we

play15:06

pick some segmentation in this case

play15:08

we're going to pick a big circle in the

play15:09

middle middle of the map

play15:11

where they're going to run a wfc

play15:13

template to fill the whole map up

play15:15

in this case we're just going to run a

play15:17

set of buildings

play15:18

we're going to cookie cutter that circle

play15:20

out and our we are left with some walls

play15:23

you can see that

play15:25

this has created some disjoint rooms and

play15:27

so what we do is we simply

play15:29

segment this map we figure out which are

play15:31

the disconnected spaces and then we a

play15:33

star from segment to segment anywhere we

play15:36

pop through a wall we're going to place

play15:37

a door so you can see in this case we're

play15:39

a-starring here you've got a little red

play15:40

cross where the door is punched and we

play15:42

do it

play15:43

again

play15:45

and again

play15:46

and again

play15:48

and again

play15:49

and once that's done

play15:51

we are able to build a whole map which

play15:53

looks pretty complicated but you can see

play15:56

now that there's there's very little

play15:57

going on right we've we've done a top

play15:59

level segmentation we've filled in the

play16:01

details with wfc and we've punched some

play16:03

doors with a pretty simple a-star and

play16:05

that's

play16:06

the output is pretty complex so let's

play16:08

revisit

play16:10

the initial maps

play16:11

which looked complex before but let's

play16:13

think about how we did these these are

play16:14

each accomplished through the exact same

play16:16

technique in this case we've got a

play16:18

couple square areas that were filled

play16:19

with rectilinear wfc output that's it

play16:22

you get this cool looking palace

play16:24

here we have a full map that's been

play16:26

allowed to run we had a tiny little

play16:28

corridor wfc it's maybe eight by eight

play16:31

we let it just run out across the whole

play16:32

map then we flood fill in some of the

play16:34

edges with with dirt so this looks like

play16:36

a buried

play16:38

buried set of goalies

play16:40

here we've just got a circle and a

play16:42

square output that been filled with real

play16:44

simple labyrinthine wfc

play16:47

and here we have a big square at the top

play16:49

that's been filled with wfc output and a

play16:51

big square at the bottom which has been

play16:53

filled with wfc output and that's it and

play16:54

you get this cool little village right

play16:57

pretty simple so

play17:00

there are some really good papers in the

play17:01

wild

play17:02

isaac karth has written a good one

play17:03

called wfc is constraint solving the

play17:05

wild if you want to go

play17:07

really deep down into how the algorithm

play17:09

works you can go uh grab that the

play17:12

repository is a really excellent

play17:14

resource unlike a lot of reports

play17:15

repositories it's really excellently

play17:17

documented it's got source code in

play17:20

30 different languages because as you

play17:21

can see it's like a super easy technique

play17:23

and a super powerful one and so it's

play17:25

very easy to plug into your project and

play17:27

go

play17:28

and that is it i'm brian buckler that

play17:30

was wfc

play17:40

do i have

play17:43

yeah if you have questions come to

play17:45

mike's happy to answer

play17:55

so

play17:56

how did you deal with

play17:58

communicating the algorithm to

play18:01

like uh people who are more used to

play18:03

traditional level design tools uh or

play18:05

more traditional uh procedural

play18:07

generation

play18:08

uh

play18:09

approaches which tend to work on like

play18:11

kind of room chunks or things like that

play18:12

where there's discrete combat spaces or

play18:15

discrete uh spaces for different

play18:17

gameplay styles yeah the question is how

play18:20

would i how would i communicate that to

play18:21

them or how would you yeah how how did

play18:23

working with how did working with design

play18:26

people from that background work out for

play18:28

you yeah well our team is so the

play18:30

question is how did it work out working

play18:32

with people who are

play18:34

more interested in discrete level design

play18:36

and the answer is we have no none of

play18:37

those people on the team

play18:42

how did it go with you

play18:44

well i mean this this was a big uh

play18:45

challenge for counter spy because we

play18:47

ended up doing room by room chunking

play18:49

because that was easy to build out

play18:51

spaces and have combat ai work in it but

play18:54

yeah if i can take that question to an

play18:55

adjacent space i think there's a

play18:56

tendency to want to have a little bit

play18:58

more control ability from a designer's

play18:59

perspective these

play19:01

in caves of code we let our generative

play19:03

systems run really wild and it's part of

play19:05

the aesthetic of the game and we can

play19:06

lean into it um and you can see we do

play19:08

things like we just smash outputs on top

play19:10

of each other but because our game is

play19:11

about runes that have been smashed out

play19:13

on top of each other that's great um

play19:15

i think that i think that

play19:18

the when you get into the design space

play19:20

where you want more control the

play19:21

tendencies to move more towards prefabs

play19:24

which designers have control over so you

play19:26

want to lean into like the tile based

play19:28

techniques in order to put fit those

play19:29

prefabs together and then allow the

play19:31

designators to design spaces that

play19:34

can work within a particular bound right

play19:36

so within this prefab this area can be

play19:38

filled in this knuckle so so if i'm

play19:40

following you you're suggesting maybe uh

play19:43

when you're doing the spatial

play19:44

partitioning uh step you can do some of

play19:47

that wfc step to do the kind of broad

play19:50

strokes and then chunk down uh prefabs

play19:52

into the appropriate size spaces yeah i

play19:54

would actually say probably the tile

play19:55

based uh

play19:57

portion of wfc which i didn't talk about

play19:59

is probably more interesting than those

play20:00

teams that gets a little bit more

play20:01

controllability to that out thank you

play20:03

sure

play20:05

did you try building any constraints

play20:07

into the wave function collapse

play20:09

algorithm itself like no repeating tiles

play20:12

in this

play20:13

region or anything like that because

play20:14

i've experimented with that with some

play20:15

other

play20:16

implementations of this and ran into

play20:18

quite a few problems yeah the the

play20:20

question was did we build any additional

play20:22

constraints on top of wfc um the answer

play20:24

is no because i tried it and i ran into

play20:27

a bunch of problems

play20:30

max is is a cool guy and very

play20:33

knowledgeable obviously since he created

play20:34

and if you have a specific question

play20:36

about constraint building i would

play20:37

actually hit him up on twitter and and

play20:39

ask because he's helpful but

play20:41

i i didn't have time to push past those

play20:43

problems in this case and we were able

play20:44

to get really good output without any

play20:46

kind of complex

play20:47

constraint additions i would say there's

play20:49

a great c sharp library on github by guy

play20:51

boris the brave or whatever i think it's

play20:53

linked within that repository works

play20:55

great inside unity yeah awesome

play21:00

great talk um i had a question did you

play21:02

ever try having like a more detailed uh

play21:05

training set to be able to have more

play21:07

permutations of different sort of

play21:08

adjacent materials yeah it's really

play21:11

tricky because the reality is that those

play21:12

bigger training sets like the temple

play21:14

really you can reduce those um

play21:16

quite a bit and still get similar output

play21:18

um those bigger

play21:20

bigger sets

play21:22

unless they're very complicated tend to

play21:23

just start repeating the same patterns

play21:25

and so a good train because as your

play21:27

training set gets bigger the memory

play21:29

impact and the cpu impact of the of the

play21:31

collapse gets bigger

play21:33

it tends to be best just to try to

play21:34

figure out exactly what the character is

play21:36

and pack it into as small as spaces as

play21:38

possible for actual production right um

play21:40

so i meant sort of when um when you have

play21:43

like so when you had multiple colors

play21:44

colors you got the repeating patterns

play21:46

right yeah so uh by having maybe a

play21:48

bigger training set maybe you could have

play21:50

more permutations of colors adjacent to

play21:53

each other to sort of still be able to

play21:55

get the detail but oh yeah could you

play21:58

work around overfitting by by having a

play22:00

bunch of them with different colors yeah

play22:01

i think you probably could i haven't

play22:02

really experimented with it but i mean

play22:04

that would that would certainly be an

play22:06

effective use of it i think something to

play22:08

experiment with

play22:10

any other questions

play22:12

no okay well thank you

Rate This

5.0 / 5 (0 votes)

Related Tags
ウェーブファンクションコラプスプロシージャル生成ケーブズ・オブ・カットゲーム開発Brian Buckleyテクスチャ合成MITライセンスオープンソースタイルベースアルゴリズムマップデザインインタラクション
Do you need a summary in English?