|
1 | 1 | { |
2 | | - "title": "Wave Function Collapse - Overlapping Model", |
| 2 | + "title": "Wave Function Collapse: Overlapping Model", |
3 | 3 | "videoNumber": "186", |
4 | | - "description": "", |
5 | | - "videoId": "", |
6 | | - "nebulaSlug": "codingtrain-coding-challenge-186-wfc-overlapping-model", |
| 4 | + "description": "Wave Function Collapse is an algorithm for procedural image generation. In this long overdue follow-up to my tiled model video, I dive into the overlapping model, coding it step by step (complete with struggles and messy debugging interludes) in JavaScript with p5.js.", |
| 5 | + "videoId": "5iSAvzU2WYY", |
| 6 | + "nebulaSlug": "codingtrain-coding-challenge-186-wave-function-collapse", |
7 | 7 | "date": "2025-01-28", |
8 | 8 | "languages": ["p5.js", "JavaScript"], |
9 | 9 | "topics": ["wave function collapse", "overlapping model", "procedural generation"], |
10 | 10 | "canContribute": true, |
11 | 11 | "relatedChallenges": ["171-wave-function-collapse"], |
12 | 12 | "timestamps": [ |
13 | 13 | { "time": "0:00:00", "title": "Introduction" }, |
14 | | - { "time": "0:01:12", "title": "The Nature of Code" }, |
15 | | - { "time": "0:02:20", "title": "References" }, |
16 | | - { "time": "0:08:19", "title": "Write a function to extract tiles from a source image" }, |
17 | | - { "time": "0:14:32", "title": "Write a function to copy tiles" }, |
18 | | - { "time": "0:21:30", "title": "Add a list of allowed adjacencies to the Tile object" }, |
19 | | - { "time": "0:24:34", "title": "Write an overlapping() function" }, |
20 | | - { "time": "0:32:20", "title": "Look at the first tile's neighbors" }, |
21 | | - { "time": "0:43:30", "title": "Add a Cell class" }, |
22 | | - { "time": "0:44:15", "title": "Add a grid of Cells" }, |
23 | | - { "time": "0:46:21", "title": "Retrieve previous WFC code" }, |
24 | | - { "time": "0:50:50", "title": "Write a reduceEntropy() function" }, |
25 | | - { "time": "0:55:56", "title": "Add a function to render the center pixel" }, |
26 | | - { "time": "0:58:05", "title": "Filter by the valid options" }, |
27 | | - { "time": "1:01:57", "title": "Use recursion to reduce entropy" }, |
28 | | - { "time": "1:05:32", "title": "Add depth of recursion" }, |
29 | | - { "time": "1:06:32", "title": "We have WFC!" }, |
30 | | - { "time": "1:09:42", "title": "Fix mistake" }, |
31 | | - { "time": "1:11:26", "title": "Start refactoring code" }, |
32 | | - { "time": "1:18:41", "title": "Add a console.log if alogrithm gets stuck" }, |
33 | | - { "time": "1:21:38", "title": "Optimizations" }, |
34 | | - { "time": "1:26:28", "title": "Discuss redundant tiles" }, |
35 | | - { "time": "1:28:30", "title": "Rotations and Reflections" }, |
| 14 | + { "time": "0:01:12", "title": "The Nature of Code book!" }, |
| 15 | + { "time": "0:02:20", "title": "WFC Resources and References" }, |
| 16 | + { "time": "0:08:19", "title": "Extracting tiles from a source image" }, |
| 17 | + { "time": "0:21:30", "title": "Calculating adjacency rules for tiles" }, |
| 18 | + { "time": "0:24:34", "title": "Checking for overlapping pixel colors" }, |
| 19 | + { "time": "0:32:20", "title": "Debugging tile adjacencies" }, |
| 20 | + { "time": "0:43:30", "title": "Creating a Cell class" }, |
| 21 | + { "time": "0:46:21", "title": "Incorporate code from WFC tile model" }, |
| 22 | + { "time": "0:50:50", "title": "Reduce entropy of neighboring tiles" }, |
| 23 | + { "time": "0:55:56", "title": "Rendering the center pixel for each tile" }, |
| 24 | + { "time": "0:58:05", "title": "Cross checking valid tile options" }, |
| 25 | + { "time": "1:01:57", "title": "Recursive entropy reduction" }, |
| 26 | + { "time": "1:05:32", "title": "Limit recursion depth" }, |
| 27 | + { "time": "1:06:32", "title": "Challenge complete?" }, |
| 28 | + { "time": "1:08:26", "title": "Bugs found between Day 1 and Day 2" }, |
| 29 | + { "time": "1:09:13", "title": "Starting Day 2" }, |
| 30 | + { "time": "1:10:02", "title": "Correcting pixel color if statement" }, |
| 31 | + { "time": "1:11:16", "title": "Refactoring redundant code" }, |
| 32 | + { "time": "1:17:26", "title": "Running out of tile options" }, |
| 33 | + { "time": "1:21:24", "title": "Optimizing the code" }, |
| 34 | + { "time": "1:23:47", "title": "Rendering average pixel color of remaining tile options" }, |
| 35 | + { "time": "1:26:23", "title": "How to handle redundant tiles?" }, |
| 36 | + { "time": "1:28:30", "title": "More tiles with rotations and reflections" }, |
36 | 37 | { "time": "1:29:39", "title": "Additional performance optimizations" }, |
37 | | - { "time": "1:31:40", "title": "Outro" } |
| 38 | + { "time": "1:31:40", "title": "Thanks for watching!" } |
38 | 39 | ], |
39 | 40 | "codeExamples": [ |
40 | 41 | { |
41 | | - "title": "WFC Overlapping", |
42 | | - "description": "The sketch implements the overlapping model.", |
43 | | - "image": "1.png", |
| 42 | + "title": "Wave Function Collapse: Overlapping Model", |
| 43 | + "description": "Unoptimized code exactly matching the video.", |
| 44 | + "image": "wfc.png", |
44 | 45 | "urls": { |
45 | | - "p5": "https://editor.p5js.org/codingtrain/sketches/PX0Hn6TF8" |
| 46 | + "p5": "https://editor.p5js.org/codingtrain/sketches/SI0c2D_tQ" |
46 | 47 | } |
47 | 48 | }, |
48 | 49 | { |
49 | | - "title": "WFC Overlapping - Shannon entropy", |
50 | | - "description": "This sketch adds Shannon entropy.", |
51 | | - "image": "1.png", |
| 50 | + "title": "WFC Overlapping Model Refactored", |
| 51 | + "description": "Refactored code with optimizations.", |
| 52 | + "image": "wfc_refactored.png", |
| 53 | + "urls": { |
| 54 | + "p5": "https://editor.p5js.org/codingtrain/sketches/2sV4KtcoD" |
| 55 | + } |
| 56 | + }, |
| 57 | + { |
| 58 | + "title": "WFC Overlapping Model: Shannon entropy", |
| 59 | + "description": "This sketch counts tile frequency and incorporates entropy formula.", |
| 60 | + "image": "wfc_entropy.png", |
52 | 61 | "urls": { |
53 | 62 | "p5": "https://editor.p5js.org/codingtrain/sketches/PX0Hn6TF8" |
54 | 63 | } |
55 | 64 | }, |
56 | 65 | { |
57 | | - "title": "WFC Overlapping - Rotations and Reflections", |
| 66 | + "title": "WFC Overlapping Model: More tiles!", |
58 | 67 | "description": "This sketch adds tile rotations and reflections", |
59 | | - "image": "1.png", |
| 68 | + "image": "wfc_rot_reflect.png", |
60 | 69 | "urls": { |
61 | 70 | "p5": "https://editor.p5js.org/codingtrain/sketches/z_N2TVjRH" |
62 | 71 | } |
63 | | - }, |
64 | | - { |
65 | | - "title": "WFC Overlapping - Restart", |
66 | | - "description": "This sketch restarts WFC if there are no more valid choices.", |
67 | | - "image": "1.png", |
68 | | - "urls": { |
69 | | - "p5": "https://editor.p5js.org/codingtrain/sketches/2sV4KtcoD" |
70 | | - } |
71 | | - }, |
72 | | - { |
73 | | - "title": "WFC Overlapping - Refactored", |
74 | | - "description": "This sketch refactors the code and adds performance enhancements.", |
75 | | - "image": "1.png", |
76 | | - "urls": { |
77 | | - "p5": "https://editor.p5js.org/codingtrain/sketches/paJcuQLI0" |
78 | | - } |
79 | | - } |
| 72 | + } |
80 | 73 | ], |
81 | 74 | "groupLinks": [ |
82 | 75 | { |
83 | 76 | "title": "References", |
84 | 77 | "links": [ |
85 | | - { |
86 | | - "icon": "📕", |
87 | | - "title": "The Nature of Code", |
88 | | - "url": "https://natureofcode.com/", |
89 | | - "description": "The Nature of Code book (2024 p5.js edition)" |
90 | | - }, |
91 | | - { |
92 | | - "icon": "🛒", |
93 | | - "title": "Nature of Code shop", |
94 | | - "url": "https://store.natureofcode.com/products/the-nature-of-code", |
95 | | - "description": "The Nature of Code book (2024 p5.js edition) is now available for purchase!" |
96 | | - }, |
97 | 78 | { |
98 | 79 | "icon": "🗄", |
99 | | - "title": "Wave Function Collapse Algorithm", |
| 80 | + "title": "Wave Function Collapse GitHub Repo", |
100 | 81 | "url": "https://github.com/mxgmn/WaveFunctionCollapse", |
101 | | - "description": "The original GitHub repository from mxgmn for the Wave Function Collapse algorithm." |
| 82 | + "description": "Maxim Gumin's source code and documentation for Wave Function Collapse." |
102 | 83 | }, |
103 | 84 | { |
104 | 85 | "icon": "🗄", |
105 | 86 | "title": "Model Synthesis", |
106 | 87 | "url": "https://paulmerrell.org/model-synthesis/", |
107 | | - "description": "Paul Merrell's 2009 PhD Thesis that is a predecessor to WFC." |
| 88 | + "description": "Documentation of Paul Merrell's work on Model Synthesis." |
108 | 89 | }, |
109 | 90 | { |
110 | 91 | "icon": "🗄", |
111 | 92 | "title": "Procedural Generation with Wave Function Collapse", |
112 | 93 | "url": "https://www.gridbugs.org/wave-function-collapse/", |
113 | | - "description": "Article on using WFC for procedural generation." |
| 94 | + "description": "Wave Function Collapse overlapping model algorithm walk through." |
114 | 95 | }, |
115 | 96 | { |
116 | 97 | "icon": "🗄", |
|
120 | 101 | }, |
121 | 102 | { |
122 | 103 | "icon": "🔗", |
123 | | - "title": "p5 copy()", |
| 104 | + "title": "p5.js copy()", |
124 | 105 | "url": "https://p5js.org/reference/p5/copy/", |
125 | | - "description": "Reference for the copy function" |
| 106 | + "description": "p5.js reference page for copy() function" |
126 | 107 | }, |
127 | 108 | { |
128 | 109 | "icon": "🔗", |
129 | | - "title": "Github issue RE console.log problem", |
| 110 | + "title": "p5.js web editor console log GitHub issue", |
130 | 111 | "url": "https://github.com/processing/p5.js-web-editor/issues/3178", |
131 | | - "description": "Cannot console.log objects having circular references." |
| 112 | + "description": "Issue discussing console.log and objects with circular references." |
132 | 113 | }, |
133 | 114 | { |
134 | 115 | "icon": "🔗", |
135 | | - "title": "concat() function", |
| 116 | + "title": "JavaScript concat() method", |
136 | 117 | "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat", |
137 | | - "description": "Reference for the concat function." |
| 118 | + "description": "JavaScript documentation for array concat() method." |
138 | 119 | }, |
139 | 120 | { |
140 | 121 | "icon": "🔗", |
141 | | - "title": "randomSeed()", |
| 122 | + "title": "p5.js randomSeed()", |
142 | 123 | "url": "https://p5js.org/reference/p5/randomSeed/", |
143 | | - "description": "Reference for the randomSeed function" |
| 124 | + "description": "p5.js reference page for randomSeed() function" |
144 | 125 | } |
145 | 126 | ] |
146 | 127 | }, |
|
151 | 132 | "icon": "🎥", |
152 | 133 | "title": "Pixel Array", |
153 | 134 | "url": "/tracks/p5-tips-and-tricks/more-p5/pixel-array", |
154 | | - "description": "Coding Train video with explanation of tracking 2D grid in 1D array (for pixels)." |
| 135 | + "description": "Video tutorial on how to work with pixel array in p5.js." |
155 | 136 | }, |
156 | 137 | { |
157 | 138 | "icon": "🎥", |
158 | 139 | "title": "Modulo Operator", |
159 | 140 | "url": "https://www.youtube.com/watch?v=r5Iy3v1co0A", |
160 | | - "description": "Golan Levin explains what modulus means and its applications in creative coding with p5.js and Processing." |
| 141 | + "description": "Video tutorial with Golan Levin explaining modulo operator." |
161 | 142 | }, |
162 | 143 | { |
163 | 144 | "icon": "🎥", |
164 | 145 | "title": "Array Functions: filter() - Topics of JavaScript/ES6", |
165 | 146 | "url": "/tracks/topics-in-native-javascript/js/array-filter", |
166 | | - "description": "This video covers the JavaScript Array higher order function filter()." |
| 147 | + "description": "Video tutorial on higher order array function filter()." |
167 | 148 | }, |
168 | 149 | { |
169 | 150 | "icon": "🎥", |
170 | 151 | "title": "Arrow Function", |
171 | 152 | "url": "/tracks/topics-in-native-javascript/js/arrow-functions", |
172 | | - "description": "Coding Train video covering JavaScript arrow (=>) function." |
| 153 | + "description": "Video tutorial on JavaScript arrow notation." |
| 154 | + } |
| 155 | + ] |
| 156 | + }, |
| 157 | + { |
| 158 | + "title": "Creative Works Featured", |
| 159 | + "links": [ |
| 160 | + { |
| 161 | + "icon": "🎨", |
| 162 | + "title": "Townscaper", |
| 163 | + "url": "https://www.townscapergame.com/", |
| 164 | + "description": "Created by Oskar Stålberg, 3D WFC system that creates cute little houses, arches, stairways, bridges and lush backyards." |
| 165 | + }, |
| 166 | + { |
| 167 | + "icon": "🎨", |
| 168 | + "title": "unity-wave-function-collapse", |
| 169 | + "url": "https://selfsame.itch.io/unitywfc", |
| 170 | + "description": "A fork of Wave Function Collapse with tools for the Unity Game engine by @ExUtumno." |
| 171 | + }, |
| 172 | + { |
| 173 | + "icon": "🎨", |
| 174 | + "title": "Super Mario WFC", |
| 175 | + "url": "https://observablehq.com/@makio135/super-mario-wfc", |
| 176 | + "description": "Generating variations of Super Mario Bros worlds with Wave Function Collapse." |
| 177 | + }, |
| 178 | + { |
| 179 | + "icon": "🎨", |
| 180 | + "title": "Zelda WFC", |
| 181 | + "url": "https://observablehq.com/@makio135/zelda-wfc", |
| 182 | + "description": "Generating variations of Zelda maps with Wave Function Collapse." |
| 183 | + }, |
| 184 | + { |
| 185 | + "icon": "🎨", |
| 186 | + "title": "Infinite procedurally generated city", |
| 187 | + "url": "https://marian42.de/article/wfc/", |
| 188 | + "description": "a game where you walk through an infinite city that is procedurally generated as you walk." |
173 | 189 | } |
174 | 190 | ] |
175 | 191 | } |
|
0 commit comments