YouTube Transcript:
Oskar Stålberg: Landscapes of Hex and Square - Summer School on AI and Games 2023
Skip watching entire videos - get the full transcript, search for keywords, and copy with one click.
Share:
Video Transcript
View:
School several times before um and uh I
think he was in principle interested but
various things happened um pandemics
happened and various things
um yeah so we very very happy to have
Oscar here today um Oscar is not an
academic like some of us um and also not
a research director at the giant
multinational games company um um like
some other of us um um instead I think
he's this year we don't have that many
people from the indis space but I guess
he's our main Indie representative today
so Oscar is famous among other things
for two games um townscaper and bad
north um they are quite different in
various ways but um they are also they
have some similarities in how in the
Reliance on PCG um and we asked osar to
come to talk about what he wanted to
talk about assuming that what he wanted
to talk about
was how to build games around PCG and
PCG matters around it so uh without
right uh yeah so you know how when you
go see a band all the fans just want to hear
hear
the when you go see a band all the fans
just want to hear all the hits and then
the band goes and here's a song from our new
new
album that's what this talk is going to
be uh so this is a new thing I'm working
on it's like a cool little procedural Island
Island
generator uh that generates cool nice
looking islands that I probably
eventually G to put a game on top of uh
but I'm not in a hurry so I'm sort of
taking my time just making them look
beautiful in more ways um so I'll show
you a little bit the stuff I've been
working on before because this is all
kind of I keep building on the same kind
of Technology um this is townscaper it's
the last game I made um it's sort of
it's barely a game even you just sort of
Click you pick colors and
then there's a bunch of algorithms
running underneath that's making sure
that sort of however you build it makes
sense and there's like little details
filling out the space you can do things
like building build green backyards and
whatever making cool like floating
structure stuff like that
um and then before that I made the game
uh bad North here I just have some
random YouTube video of what that game
looks like um the new thing I'm building
is probably going to be a lot more like
bad north than townscaper because um um
townscaper is an is an interactive
generative game right you can keep
building and that kind of limits the
kind of algorithms that you can
Implement right because everything has
to be updated instantly that's one thing
so it has to be fairly fast it's harder
to do Global things like doing a UV
mapping of of the whole world for
example if if it keeps changing all the
time um and also there's like there's
some design restrictions as well because
if you're making something like
townscaper where
um the player has to have a fairly good
idea of sort of what's going to happen
when they do different things I can with
my algorithms play a little bit with
like the shape of tiles and surprise the
the player but if they place a house
block it should look like a block and it
should be a house like I can't turn the
whole thing into a tree unless I figure
out like a very clear way of
communicating to the player why this
happened and not another thing so that
sort of limits the kind of there's a
bunch of architectural features for
example that would fit very well into
townscaper but I haven't figured out
good way of doing um sort of recipes for
the player on how construct to construct
these different things um there's also
after townscaper townscaper is all Urban
environments there's a tiny bit of green
space but it's it's all within the
context of an urban environment uh but I
wanted to get back to doing some more
sort of natural landscapes likeing by
North and I had some new
cool um Technologies and stuff in mind
that I thought would work well um so
we'll sort of go through the generation
process fairly linearly on what happens
when you make one of these levels let's
just make a couple of more just to see
what what kind of it's capable of
um so first of all there's the grid and
sort of as I'm when I mean townscaper
that has a weird grid as well you can
tell it's
not um it's not Square here we got this
big weird hexagonal thing going on uh so
I kind of felt after having introduced
that kind of grid I couldn't go back to
doing normal grids uh so now I'm I'm
stuck with doing weird grids in whatever
projects I make in the future um but you
can see in the middle here the grid is
kind of square right that makes a lot of
sense but then up here at the edges
there's some different things going on
so we can actually overlay what sort of
will be the game tiles so in bad North
you uh no
that's in bad North it's it's a tile
based game but the it's only tile based
for the player so the player tells units
where to go but the units themselves
flow freely across the terrain so it's
kind of an interesting differentiation
in in the abstraction level that the
player is working on and that the the
actually units fighting uh are are
working on and that also means that like
normal tile based games it's super
important which tiles are adjacent and
which aren't adjacent right if you're
doing melee combat on a square grid then
like what happens on the diagonals
that's unclear uh but in a game like
this it doesn't um it doesn't really
matter at all you can have like thin
winding paths going between different
tiles the only important part is that it
should be easy to send units to go
through all the different paths to clear
out if there enemies standing there
because the enemies they don't care
about the tiles at all um but yeah so
bad North was all square that was before
I started doing weird grids uh at all
but townscaper or this thing here which
might become bad North too we'll see uh
has this kind of grid um let's generate
some new ones to see what's going on
yeah so you see there's a bunch of
square sort of squarish things going on
but then there's a bunch of more hex
likee or kind of irregular grid shapes
going on and what's actually happening
if we take a look at there's a the first
thing that happens in the generation is
the base grid being generated and if we
slow down that we should be able
to uh here we see the base grid being
generated so I start with like a a
convex shape I place a bunch of tiles or
a bunch of vertices uh in the shape in a
mostly Square pattern and then I just
fill it out with triangles where it
didn't fit anything so then you get a
nice mix of squares and triangles
triangles
and as we all know that is everyone
familiar with the jeel graph concept no
maybe not um there is uh when you're
doing a hexagon game you might like you
could make all the game tiles be actual
hexagons but hexagons are tricky because
they have six sides and six corners
that's a lot of work what you could do
instead is you could make all your
visual tiles out of the little triangles
combining different like hexagons like
this uh because that's super convenient
because then you can um like within a
like say this is a a medieval town with
a town wall then within this triangle
you can have a wall like that so then
like if you have a triangle that has a
wall like that going outwards and then a
triangle with a wall like that going
inwards and then like one triangle
without wall and then one triangle just
filled with the town that's supposed to
go inside the wall so it's like town
here it's town here then you can create
all the different town shapes you would
want to on a on a hex grid without
having to do a bunch of different things
that you would do if you put it straight
on the hex
hex
um so yeah we got this so we can
actually look at as well what happens if
we do it in a non-mixed
grid um here is just with a square Grid
boring there we go it's a bit unfair of
course because I built the T whole tile
set with the mixed Grid in mind so like
it's not able to do all the kind of
interesting things here uh we can also
do it with uh let's just do one more but
it's faster yeah and then we could do it
with a full uh triangle grid so that's
essentially a hex grid as well that's a
little bit cooler like you get these
interesting it's sort of it's obviously
works better with like Cliff faces for
example they look a lot more natural in
a hex grid but I'd say one um drawback
of the hex grid is it has this very
clear scale to it right if you follow a
a l like in in a civilization for
example if you zoom out you always see
these kind of these lines right this
wave of the hex grid size everywhere um
and that looks like that works at a
certain scale but if you zoom out more
it starts to look very repetitive and
very obvious I mean this is a an issue
with a lot of tile based Solutions
whereas of course squares have a nice
feature of you can actually have like
lines running along the square so like
in a in a the the grid scale doesn't
show as much right you can have straight
lines and in so with this solution with
the mixed grid I get sort of the Best of Both
Both
Worlds uh and some featur so I've
actually chosen um specifically to not
to only allow flat planes on the on the
square tiles because squares kind of
feel more natural and since I'm
displaying this as this kind of um
agricultural landscape with these little
like lines between the different tiles
which are supposed to be game tiles you
play on but they also look like
different fields that makes a lot more
sense on the on the on the Square grid
uh whereas on the on the boundaries it
looks a lot better on the hex grid so
here you get a little bit of Best of Both
Both Worlds
Worlds
um yeah and the other big thing that's
going on apart from the grid of course
um are the is the wave function collapse
that's the same sort of algorithm that
it's also known as well they're probably
slightly different but there's not
there's I maybe should call it model
synthesis which might be the correct uh
name I'm not ex my algorithm is probably
so far a spin-off of both of these that
there it might be called its own thing
but what's going on and this is the
thing I've been working with since uh
bad North and townscaper and a long
while back as well is I'm taking all
these different so these are all my
tiles that I built in Maya and then
export them just as one big triangle
soup mesh without any like naming
conventions or grouping or anything uh
into unity and then I have an import
script that parses these things and like
divides them up into different tiles and
stuff and you can see I've got a lot of
square tiles going on here
and a lot of triangular tiles and then I
even have
some tiles that sort of because I can
have tiles that stretch across multiple
cells so to speak so this house here is
supposed to sit like half on some
squares and half on some triangles uh
that's pretty fun and I can do some more
like I think we have an interesting sort
of sloping feature here that's supposed
to also like fit in a very specific way
with like both squares
triangles um so that's good then I can
get sort of the best of both world most
of the houses and stuff exist on on
squares um whereas most of the Cliff
face features and stuff like that exist
here in the Triangular space uh so what
the wave function collapse algorithm
does for those who do not know is that
it figures out how to create a coherent
uh level from a set of input tiles uh so
this is a demo of the wave function
collapse algorithm I wrote a while back
so you can see it takes these this is
like the smallest possible version of it
that's still a little bit interesting uh
so you have these input tiles here to
the left and they fit together in
specific ways you can see there's like
little bits of text written on the sides
here uh which is like in in this case
this the that's just based on the colors
on like it's sampling on three positions
along the tile Edge and based on the
colors but you would do this differently
depending on how your tile set supposed
to fit together and then the algorithm
just figures out how to fit all these
together in a coherent um environment
and one um the way it does is it starts
with like everything being possible
everywhere and so here you can see like
all of these existing all these modules
existing in all these different slots
and then if you select something that's
supposed to go somewhere so say I want
like this little this little Spire to go
here I click there Bo a bunch of the
possibility space collapsed because a
bunch of things are no longer possible
there's no like overhang in this tile
set so if I put the Spire there then
there has to be air above it and below
it there has to be this one because
that's the only one that fits there but
then below that one there's actually a
couple of different one that fits but
they all in turn have to have dirt uh
below them uh so that's very convenient
like this is a mixed initiative version
where you can you can pick some tiles
and then you can just tell it to solve
the rest and like technically what's
going on is we can make the algorithm
run a little bit slower so if I pick a
Spire once again
uh you see it unfolding and technically
what's going on is when you place a tile
what's happening is removing all the
other tiles because like removing
possibilities is the core of the
algorithm and every time the last tile
with a
specific um profile facing aside so in
this case a specific color for example
is removed then it tells the cell next
door like hey you need to remove
everything that rely on relied on this
one so if there's no longer any Sky
facing the side then all the sky tiles
relying on the sky has to be removed uh
and that's a a recursive function
basically I mean you can implement it as
a recursive function recursive function
or as a as a work list kind of with an
explicit stack as well um and then it
does that until there's nothing more to
collapse all the implications have been
resolved and then you get to make
another Choice uh and in this case like
with this kind of tile set it can't fail
basically always succeeds with more
complex environments or complex tile
sets it has some limitations and it
um yeah let's speed up oh it's fast
whoop There we go so that's the basic of
the wave function collapse algorithm so
my uh I have this big import script that
analyzes all these
um um terrain tiles and you can see on
the edges of them there are little
numbers and those are
basically uh the sort of profiles of
specific sides and they fit together
with other things so this 21 and 20
they're very close to each other because
they're actually mirrors of each other
so they're like calculating indexed
right after each
other um and there's also little these
little faded numbers here there's a zero
there's a one because above here that's
outside whereas below here that's all
inside so those are like reserved
indexes for these specific cases so you
could have a tile that's just like an
empty tile without any mesh that's just
one one one one one everywhere because
it's inside entirely yeah
yeah
um so these are sort of these little
numbers are super key to the algorithm
but I sort of like if you imagine all
the um if you have imagine you have a
you have a a tile that fits inside a
cell like that and then it has like a
shape facing the edge of it there's a
way to sort of create a hash from those
edges facing the side and then um uh
there's a bit of um sort of art to how
you create this hash because you don't
want like mirrored you want to keep
track of mirrored things and yeah um and
then you can index that hash and then
hopefully two shapes that look exactly
the same will end up having the exact
same hash and that's that's good uh you
do I do round my verts quite a bit so
that you don't run into like Precision
issues because like it's all floating
Point coming from Maya
obviously um I also do a bunch of all
the the different triangles in Maya are
marked up with different materials and
I'm using that as tags to sort of apply
metadata to the
triangles um so there are some like
here's a little beach curve here so
these have like a material called uh
grass and these ones have a material
called Beach and then when I analyze the
thing I also check for edges between
different kinds of materials uh they're
also marked up with like um so that I
get these uh so if we have an entire
Square Tile For example we have uh
what's like a big flat plane for example
here we got one of those you see it's
got this cross in the middle cuz these
are marked up with like it's grass but
grass I I call them different colors so
it's like grass yellow grass green grass
teal and then maybe that's grass green
as well and then the borders between
those become the borders between the
tiles in the
game um and then also I if I have
triangles that stretch across multiple
of these sort of underlying grid tiles
these are joined into bigger modules so
this is a big module right you can see
how it's uh it has like triangles that
stretch across both of those and then
you see the yellow outlines like that
it's and you see also that the borders
between these are negative numbers
that's just how I flag that these are
not normal border hashes but these are
like connecting two internal um sort of
sub tiles into one big tile yeah so
that's sort of the tile based part of the
algorithm let's start up the game
again so another thing I have have been really
um so yeah another question is like why
would you go for a like normally when
people do landscape like tile based are
very good for architectural environments
because they they tend to be they
require a lot of um uh specific
authoring but when people do uh oh it's
in the WR there we go uh when people
do um Landscapes they tend to go for
sort of softer algorithms for stuff with
height fields orx based things like that
uh that's really good to get organic
shapes but a benefit of doing tile based
things is you kind of know if you if you
care about things like navigability
where units can go where they can't go
and you won't want to be able to control
that in nice ways like you don't want to
create Pathways that looks like they're
wide enough for a unit to go through but
they can't really because it's a bit too
narrow or Cliff faces that you don't
really know if they're too steep or not
steep enough to um to go up and down um
you don't want that for a game you want
the game world to tell you very clearly
how you're you're able to act upon it
and tiles is a very nice way of
achieving that because then you have
very clear control over what kind of
data goes in and of course tiles are
also good because you can mark up
special things like places where where
props would go or where um Like Houses
mark them up as being houses and where
the door supposed to be and and stuff like
like that
that
um and here we can we can turn on
the and it's easier to do like obviously
like something like this wouldn't work
on on a height field but it's fairly
straightforward to do with with these a
tile based solution here we can mark up
and see the the borders between the
modules that make up these so these are
like the borders between the tiles that
you saw in the last picture and you can
see that they have if we turn on the the
game tiles where you would move units to
if this was bad North you can see that
they are uh they have this this dual
relationship to each other you see the
the black lines and the white lines are
and you also see right now that these
lines are not straight at all they're
kind of wonky uh because that's the next
part I was going to talk about when
in the one thing I wasn't really able to
do in townscaper is I wasn't able to do
slopes right townscaper has it's all
block based so if you have a if if you
have a block like that and a block like
that and a block like that like there's
no I do put in a little bit of like
staircase things going on like this but
sometimes you would want to have a nice
slope like and probably a nice sloping
slope like that and townscaper doesn't
have any of that so that's like one of
the things I really wanted to tackle uh
in this project uh because you you want
those for kind of um yeah to create nice
natural organic environments so what I
did here is I'm actually doing a quite a
lot of postprocessing of the mesh after
it's being assembled so if we turn off
all of that
postprocessing I do that in two steps
that I'll go through uh we do no
deformation and we do um no
relaxation and then we generate this same
same
level there we go you'll see that some
like edges look a lot more Jagged like
here there's like a sharp turn here
where it was basically a smooth straight
line before and if we turn on the uh
module borders you see that now they're
very straight and they conform like very
well to the the base graph lying
underneath um but here also you see this
like this slope here is very clearly
like a flat tile and then a slope tile
and then a flat tile again uh which is
this kind of boring super obviously tile
shapes that I wanted to get away from so
there's actually two things going on
um turn on the cells and then we'll look
at the cell
deformation there's a face that looks
like that
where uh there's essentially two things
going on in this I call it the cell
deformation stage there kind of two
things going on uh one of the things is
that um uh each of
the so if we look at it from above the
cells are trying to achieve this the
shapes that they had in the
um in the the modules that went into
create that actually ended up filling
them and that's interesting because some
of the modules actually have slightly
different like there's triang most of
the triangles are the same shape but
some of them are a little bit wider like
for example to make space for a house in
between two different game tiles where
there wasn't really enough space anyway
um and also like they obviously have to
compromise with their shape to fit
together between the different uh other
grid tiles that they're next to but
after the level's been assembled they
know that there there's actually air
between some of these so you can see
like there's a gap opening up like here
between these two cells that are
actually right next to each other but
there's no mesh connecting them so they
can have a bit more leeway in how they
deform uh and then there's also the if
we look at at this axis
instead we can see
uh uh the whole thing's kind of rising
up a little bit like that and that's
just a way to add a bit of additional
variety to it where um if you would have
if you would have at clean this a little bit
so what's happening if you would have like
like
a uh imagine a t maybe there's a bit of
a stair and then there's like flat but
then there's a sharp wall and it goes
down like that a bit of that kind of
shape what I'm doing is I'm kind of
pulling everything upwards but then it's
kind of clamped down with the other
things next to it but uh uh it's
clamping down more where you can go so
it's kind of tethered where you can go
and not and but not Tethered on just
Cliff faces so what's going to happen to
that shape during the relaxation stage
is like it's going to rise a little bit
here and then the staircase is going to
rise a little bit as well but then it's
going to be able to rise like quite a
lot in this direction and go down like
that and then just like rise a little
bit there so this like uh Cliff face
here actually gets quite a lot larger
and you introduce a new interesting
shape sort of that isn't depending on
like variation in the input tiles that
also means that if you have a completely
flat level it will instead turn into
like something like that which is you
know pretty nice it looks more natural
you get some nice Cur in there stuff
like that
um and then the second thing that's
going on is we can turn on the
relaxation uh so this like a good thing
with doing cell deformation is that it
keeps the cells have a defined volume
and they keep the contents of the cell
very intact because when you do post
processing on a mesh otherwise you might
end up with like generating degenerative
triangles like you might end up flipping
a triangle upside down or something like
that or making something too narrow or
or just like destroying the the
intricate shapes but if you do it on the
cell scale and then just interpolate the
the contents of the cell U it's mostly
intact everything inside the cell but I
still want to do there's still a little
bit too much
um U sort of jaggedness and especially
if you look see if I have any good
example this is and this is sort of an
an issue I really had in townscaper as
well if you look at this hexagonal house
here it's got these really weird like
concave Corners cuz that's just like
comes from the shape of the grid
underneath and I didn't really have a
good way of solving that
um but in this one let's generate a new
one that where it's more apparent yeah
here we should see one of these concave
well but then I do do a bunch of or a
little bit of I I don't dare to do it
too much but postprocessing
postprocessing
um on this let's turn on the
yeah let's do that without the cell
deformation but with the relaxation
instead and then let's slow down
relaxation with M cell deformation so
now this wall here turned out like a
little bit less concave a little bit
smoother and more natural let's run that
process um let's turn on the turn that
and that and that so here we see
the um the wireframe and also the the
some lines are are blacker than others
that's super important they are marked
as hard edges in the import step so
that's like really important information
in the relaxation step that happens now
so if we generate this one more
time we should see this happen slowly
here you see like everything's a little
bit Jagged but then it gets really
nicely smooth out while I'm at it
touching these BS I'm also like pushing
them a little bit outwards along their
normal just to make the shape a little
bit rounder which you know that's a
stylistic choice that's because I want
these really cute sort of roundish uh
Cliff things things going on um so this
smoothing step also means that I can
take like if you look at a if you look
at a cliff face from the side it's like
the bottom is here and then I have a CH
the mesh goes like that but then it goes
straight up and then it goes a little
bit inward like that and here's the like
the borders between the different the
different tiles and here's like the top
of the the hill uh but when I smooth it
out it turns into something like that
instead which is a much nicer thing and
you don't see where the original sort of
borders between the tiles work and of
course this the smoothing step is quite
interesting because it as I said it
cares a lot about where these little
black edges are uh I call it uh
hierarchical smoothing because different
edges and different birds have different
hierarchies so if we just do a a super
simple smoothing where every vert just
gets to pull all the other verts sort of equally
equally
so it looks a little bit crooked and
weird you sort of you're adding more
noise really than you're removing from
from with this moving especially like on
the I mean like a jagged Beach like this
might be fine well here with the sand it
looks a little bit weird like these
triangles here are pulling this vert
outwards it looks very and especially
the like the houses they break down like
almost entirely because they're not
super high poly so they don't have a lot
of sort of um geometric weight I guess
you could tell it
so I'm doing this uh hierarchical smoothing
instead
where it's basically
like um yeah there the only some verts
get to pull other verts and only along
some edges so an a vert that's not
that's not special in any kind of way
like this vert here it's just in the
middle of nothing that one sort of get
that's a normal smoothing function that
that one gets that that one just gets
pulled to the middle of all its
neighbors sort
of whereas
uh like this ver here for example that's
on a hard Edge so it only gets pulled
towards this vert and that
vert so then you get something like uh
if you have like a couple of verts like
that and it's a little bit Jagged but
that's a hard Edge and this one's this
one actually has like more than two hard
edges going out so that's like pinned as
a really hard vert that barely gets
moved at all uh
but then this whole thing will like
these will average towards each other
and they don't care at all about
whatever soft words they're connected to
other directions but those soft words
get pulled like by these things uh and
then there's there's actually multiple
layers to these because I got other
features going on uh so if we turn on
here you'll see that there are some blue
edges and some uh red edges as well and
the red edges those are the the borders
between the game tiles because I want to
smooth those out as well uh so that
they're they become a a lot more legible
and smooth and nice um but they have a
different hierarchy to them so that like
the hard edges are the highest highest
um uh sort of priority and then uh the
blue thing here is different is the
border between two different materials
so it's between the beach and the sand
those are sort of lower priority and
then the red one is the border between
different um uh between different tiles
and those are the lowest priority and
then the ones that don't have any
specialness at all are like super low
priority uh so that means that I can
sort of uh introduce a lot of variation
after I assemble the different tiles and
I have a way to um provide an intention
to my algorithm of how I want to do that
so it matters a lot in Maya what I how I
Mark the different edges like which ones
I Mark as hard and which ones I Mark is
soft and where I have the different
material borders and stuff like that uh
so I retain the sort of the intention of
um yeah while still being able to do a
lot of manipulation after the
fact so that's one thing also when I do
the here's a cool thing as well when I'm
doing the uh wave function collapse
algorithm it's a classic challenge if you
you
do uh any kind of procedural generation
that you want your level to be roughly
playable you want units to be able to go
to different parts in the level so I
have this really rudimentary navigraph
that's part of the an uh the step where
I analyze all the different tiles that
go into the game I analyze which edges
that are outgoing from the tiles are
navigable uh and how you're able to
navigate between these different meshes
right because you you might or edges
because you might have a tile with like
a wall in the middle so you can't go
over the wall but you have to go like
the tile has several navigable separate
graphs in it so when I run the wave
function collapse let's see if it works
to slow that
down you'll see how it starts with some
Naval parts and they're different colors
initially because they're not connected
to each other uh so they're part of like
different navigable islands and then it
grows the um probably turn on the cells
as well yeah it grows the it sort of
collapses the the the possibility space
from the edges of the navigability so it
and and it always tries to extend the
navigability to place new tiles that
makes the player or the units able to go
to new places it doesn't always succeed
but it tries to and it's it's fairly if
you give it the right kind of tile set
it's fairly good at sort of climbing up
to high points and making little nice
interesting stairs and stuff like
that um and it looks the the the the nav
graph you see here looks really
primitive and not very nice because it's
sort of I made it in the smallest way
possible so if you have a square tie
like this that's completely navigable
that means that you can enter through
this Edge that edge that edge that edge
and then I just connect them in the
smallest way possible which is like just
like that so I'm not even connecting
them like this because this connection
is implied by the other connections so
then the whole thing looks like a little
bit messy and ugly but uh uh it serves
the the
purpose and if
I slow this down if I remove the
Slowdown and
I turn on the nav graph and generate
again yeah here you can see as well
there's a little bit of what should be
navigability a little bit red uh thing
here but there's nothing there cuz
what's actually happening is I'm running
the wave function collapse algorithm
Twice first I'm doing it trying to
expand the navigability then when I've
done that I'm like okay which of these
sections were actually were we able to
walk to and then I I save those choices
and then I reset the whole algorithm and
then I Implement only those choices that
you like the tiles that you were able to
go to and then I try and create like
water or air in all the other places uh
so here it ended up then not having a
little bit of sort of snpp of navigable
land but instead just water which is
like sometimes there are Snippets that
show up anyway because of just the
constraints of the tile sets um but
mostly it removes them so that there's
not and that's sort of an aesthetic
Choice as well like you might want to
have some Snippets some islands or
little pieces because you could put like
here's there's there's a couple of them
but you see it it used to be um bigger
but then it shank a little bit and the
reason these one appeared as well is
because this this little sort of river
piece is part of the same tile so it's
navigable on this side but so then it
um and well here you can see there's
quite a lot of navigable area that
wasn't used at all and got replaced by water
water
um yeah so another
thing happening here of course is after
I've made this
um uh made the cool shape of the level
uh I paint it so that it looks like I do
a bunch of procedural texturing which is
also a very nice way of breaking up the
the tiles right so the texture and the
UV Maps don't come directly from the tiles
tiles
um here we can look at we can turn on
what the color texture looks like on this
this
that and the as you probably are able to
see the textures are kind of painted on
like one sort of brush stroke at a time
so if you turn off the text the should
be able to turn off the stamps um there
we go no stamps same
seed yeah so here's without any special
texturing here I'm just sort of priming
it with some base colors going on uh
here you can like see how very low poly
the mesh is for example these lines here
they follow exactly the shape of the
mesh but then like I found um uh very
early on in implementing this system I
found I get a lot
of um I come a long way just adding what
I call Big blotches here
which is basically I just like paint big
uh Big Brush strokes and just sample the
colors and the normals where I paint the
brush strokes but then just paint it on
as a big Square uh because then you get
like if we see the difference between
the um here you have the the wireframe
and then the these lines just deviate
like slightly make it a little bit more
wobbly while largely following the the
wireframe uh so you get a really nice
sort of Base especially for the cliffs I
think that there's a really nice way of
getting like slightly Jagged edges uh
that fit very neatly closely to the um
to the shape of the mesh like another
way to make it look more cliff-like
would be to just add tiling textures and
stuff like that but I don't really like
those kind of solutions because
especially in the stylized style um they
kind of hide the low poly mes mesh
mostly with noise uh they don't contain
contextual information about the shape
of the mesh at that specific point
they're just like a rock noise that goes
on top of it whereas this actually
creates the rock shape out of the um uh
the actual underlying um polygon
shape and then there's a bunch of and
and I plan to go a lot further with this
as well there's of course a bunch of
other like specialized handwritten uh
uh
um paint brushes going on on top so to
create these little Bush things they
should probably have some like uh 3D
shape to them as well but it's a good
start and these sort of lines that run
along the grass and stuff like that so
there there's a lot left to be played
with there as well
um and another thing I do here here's
the normal map for the whole thing and
here's an interesting thing called the
contrast texture uh which is because I
want to have these little lines between
different things I don't know if
anyone's has ever experimented with
doing these kind of handdrawn uh Styles
where you have lines everywhere so
outlines is a fairly solved problem but
lines internal to object is actually a
fairly difficult way to get right if you
just bake them into the texture they
will look like they will have a certain
scale and if you zoom out too much
they'll they'll start to disappear and
when you zoom in they turn large and
blurry um that's why I have this
contrast texture where for each each
Edge uh it has an idea of how much
contrast it wants to have to the edge
next to it so like a hard Edge should
always have some kind of contrast and
the difference between grass and Cliff
should always be that should be an even
higher contrast or like between the the
roof of Tire of a house and the wall of
a house and then I've got this iterative
algorithm which is seeds everything with
a with with a random color and then it
iteratively goes through and see like oh
this Edge should have more contrast so
let's like push these colors away from
each other oh this edge here they should
have less contrast let's pull these
towards each other you run that like 100
iterations or something and then you get
a nice like super colorful map like the
one here and then if you just run like
like Edge detection on that map you get
super nice uh outlines uh with like the
places um
yeah then I got some also some nice like
I voxelize this whole space and make a
three-dimensional distance field as well
uh for lighting and for other things um
if we see there we see that's a
beautiful gorgeous uh texture can anyone
it's a 3D texture sort of but stacked
right so the these are like the
horizontal plane planes and then all the
different the 16 ones are like stacked
vertically uh but the weird colors
because it's actually a distance field
in the alpha Channel but you can barely
see that but the weird colors are the UV
colors of the closest triangle to that
boxal in the distance field because that
means that I can then through that
distance through this texture I can look
up the the
uh the UV mapped Mega texture so I can
run my like lighting calculations I can
go back and forth back and forth between
unruptured texture of those because I
figured if this should run on mobile
which so far I've put all my games on
mobile so I guess this should run on
mobile as well doing this kind of
expensive lighting calculations and
Global illumination it'd be nice if you
could just pre-bake this whole thing
into one Mega texture then like drawing
the whole environment becomes super
cheap uh but then it's also baked into a
big nice light volume here you see that
one um which is like a volume but it's
also with different axes so you got like
the brightest one here is upwards facing
and that the darkest is downward facing
then it's like Left Right positive
negative and you can clearly see the
sort of shape of the uh Island here as
well and there's actually some Shadow
costing going on so I can use that in
the um to do like so the I got fairly
complex Global illumination lighting but
actually rendering that is super simple
I just sample like one place in the uh
in this volumetric texture and um so
then I can light particles grass foliage
units whatever super cheaply I had a
similar solution to bad North but it's
just like a little bit more complicated this
this time
time
um doing all time pretty good yeah so I
think I've uh
I've gone through most of the major
things I wanted to show so I can start moving
moving
to questions and yeah I got a lot of
the stuff here on the computer if you
want to see
here yeah thank you very much um you
know with the texture sorry the vertex
smoothing yeah do you do anything you
you smooth towards the low priority
vertices at all um no the the the higher
priorities or order or what you want to
call them they don't move towards the
lower ones at all um but the yeah but
the lower ones move towards the higher
ones yes yeah um there's a t and the
yeah the ones the ones that have more
than two outgoing hard edes so the ones
like this one uh
those shouldn't be moved At All by the
other ones but I actually move them just
a tiny bit because it it creates a
little bit it depends a bit like I do a
lot of ad hoc stuff like the houses
they're not smoothed at all because
they're created in the correct shape
from the beginning so yeah there's a
bunch of adog stuff like that going on
and like different materials being
treated differently and some are bulging
outward a little bit more and some a
little bit less and stuff like that
much um this is this is a bit out there
but um given that you're at the output
of your uh algorithm is itself kind of a
tile have you considered running this
recursively to create like use this as
like the tile piece and then extend that
into like a its own kind of kind of wave
function collapse into like a set of of Island
Island
tiles I don't think I fully understand
oh sorry given that you can generate
like a like a like a tile yeah uh out
comp comprised of tiles right could you
ostensibly like recurse and generate
like a like a whole a whole archipelago
of these guys oh yeah I mean
theoretically you could uh for sure yeah um
um
yeah but yeah I'm probably not gonna
because uh I like these little really
Coy small environments and it sort of
brings out the most of the tile based
approach as well because if you've got a
very big environment you can spread
things out a lot and you're not you can
sort of but when you're doing a small
Coy environment things need to butt up
against each other and sort of relate to
each other a lot and the handcrafting
you get to do when you do a tile based
system kind of caters to that a lot you
get to like like little details be
leaning on each other and uh stuff like
that um yeah so yeah there's also a
bunch of like there's a lot of technical
things you can get away with when you do
a very constraint environment like this
like like being able to do the lighting
in just one big volume and that's it
like obviously in a big game that
wouldn't have that wouldn't work at all
you would have like a loing system and
like a bigger volume and then a smaller
I mean you probably couldn't use a
that's why use light probes and similar
system but here it's very defined small
space I can just have one big volume
covering everything one big UV map
covering everything one big texture
covering everything so it's like like
you you a lot of the problems become a
lot simpler when you just put everything
this uh so when you're deciding the
tiles uh do you have like a different
texture for each different tile of
combination or do you have like um a
grass tile kind of and a portion of it
is taken by another texture
somehow uh so all the texturing is
happening procedurally after the fact so
there's no texturing going into the
tiles at all and there's no UV map on
the tiles as they are so the whole thing
is UV map as one uh and then the yeah so
there's no the the texture system
basically doesn't know much about the
the tiles at all that at that point that
information has become old and
irrelevant sort of um yeah which is also
why you don't get like the borders
between the the tiles shouldn't be
visible in the I mean there are some
borders visible here but they're
actually not the borders between the the
module tiles that go into the game but
they're the borders between the game
tiles where you would play the game so
they're sort of intentionally placed
there uh so it's like decided after kind
of yeah yeah yeah the texture is
entirely created after the fact yeah
yeah thank
you um really fun talk um I wanted to
ask you I think you mentioned already
the handcrafted tiles but you have all
this Tech going on and then you actually
do these tiles in Maya yeah which is
kind of weird right like you know you
have all this like what is the rationale
why do you do it like like the way
you're doing it is an aesthetic thing or
what other way would I do it you could
just generate them like you could just
generate yeah but no but there's a lot
of thing there's a lot of artistic
consideration that goes into
handcrafting them a lot of them look
like fairly generic in their shapes and
just solve like specific geometrical
problems but there's a lot of things
about like what happens when different
things meet each other like how a
certain little path looks like and and
also big part is like which ones
shouldn't be there there's some awkward
conect that's a big difference between
this and townscaper because down
townscaper that has to solve for every
possible way a person can build but
which actually like negates some of the
benefit of the wave function collapse
algorithm because it's supposed to be
able to figure out what it can do with
it what it's given so here it's like if
I have an awkward shape or if there's a
theoretical awkward shape where two
different things would meet each other
but it looks a little bit weird I can't
solve it in an aesthetical way I just
don't I just don't create that one at
all uh yeah and especially once I like
now I only have a few houses like this
um but they have a little bit of special
shape to them like you see this one has
like a little bit of a path that's sort
of tied to the house this one has a
little bit of a foundation that goes out
like this um like these things you could
you could generate these things kind of
in Houdini or something like that but
then you then you have to write all
those all those aesthetic rules you have
to formulate them into generative
functions uh which is good for some things
things
um but here you can just bake them in
man ually which is good for other it's
much easier to add I I think that
especially shows in townscaper which has
uh because you know in urban
environments it's filled with so many
different kinds of objects and things
that there would be so many rules if you
would generate them uh whereas if you
make them manually it's it's a lot
easier and you can like for everything
you can take into consideration oh does
this look too busy or too detailed or or
maybe good do these complement each
other in a nice way uh so yeah I mean I
think it's in general with procedur generated
generated
things it's very easy that they look too
procedural generated you want to get the
handcrafted artistic aspect in there
somewhere and a bit of that comes from
just writing sort of a artisanal code
lot a lot of hardcoded things on what
goes where and stuff like that uh but
it's good to have some space to do
actual uh sort of manual modeling or
texturing as well
yeah hello uh thank you for the talk um
how how do you go from like yeah you
have many tiles uh how do you decide
which ones you want to make next and
then that whole process of making it
Maya and then importing it through your
custom importer like deciding hard IES and
and
stuff how do you keep track of every
single T you already made and like is it
just like a very arduous process is it
very like no I mean it's a it's a it's a fairly
fairly
um that's a fairly fun and artistic just
thing it's like you imagine this kind of
natural feature and then you try and
make a tile that creates that one or a
Ser usually you make like a tile system
because you want it to be able to appear
in many different ways so like
um um yeah if you have a specific like
little sort of small path then you
usually have several like lower parts of
the path and several possible higher
levels of the path and and stuff like
that so that's usually that's the kind
of work you do at the end of the day
when you're tired and because it's
fairly relaxing and you just build a
bunch of different shapes try them out
see what they look like uh actually a
common thing though is that I make some
really cool shape but that require some
very specific context to show up yes and
then they don't show up for ages uh so I
should probably write a better system to
like ensure that something shows up in a
some way after I've created it so I can
see that does this actually work uh but
sometimes I've made a piece try to make
it show up it doesn't show up and then
just like a couple of days later it's
like oh there it is oh that looks pretty
cool or that looks bad I should remove
that one uh those are like usually for
the the the pieces that solve for really
weird cases require very specific
context to show up yeah a second
question is for the pathing uh is that
also part of the Importer is that yes
it's part of the yes analyzing so it
does uh both all the all the little
triangles depending on their materials
they know if they're pathable or not but
it takes that information so in the the
the game that's probably going to end up
on top of this uh that that information
will be used straight up and it will be
treated as a navish basically uh but the
simplified layer of pathing that you see
um uh here that's that's based on that
but it's it's like creating the the most
abstract representative version of that
uh as possible yeah um yeah so it
ignores the internal pathing within a
tile for example and just sees how it
connects to the borders yeah so Oscar uh
if you can reveal this the game that
sits on top of this yeah uh
so do the players interact with the with
the island as as before or is has
nothing you know the geometry you
generate has nothing to do with a game
well I'm so I'm building it with bad
North in mind okay which was this thing
um which is uh so you in that case you
send little armies around and they move
on the tiles uh yeah yeah this this one
wouldn't a bunch of these systems in
this one wouldn't work in a townscaper
style environment because uh Like This
Global texture for example would be
basically like it would be a I mean you
could probably do something where you
update con yeah uh but it would be
envirment hi Oscar I'm a fan of BOS and
the transcri I love your game very much
uh I want to know when you develop your
uh tools how do you ensure your
functionality will work properly
properly [Music]
[Music]
um I mean I don't have a special I just
try things and see if they work and try
it over and over again uh so like
actually preparing for this talk because
then I needed to like most of these
things I've built as visualizers as I've
developed them but preparing for this
talk I like polished up the
visualizations and uh like tried to slow
down the algorithm in different places
and I discovered a bunch of bugs uh and
things that didn't like especially with
the pathing thing that didn't work out
and all kinds of things so there's a
very good cleansing process in like
going through everything again step by
step and like oh this is supposed to be
working but it's not anymore uh so
there's a lot of that happening because
it's I mean it's probably even worse
with like the new like this is a bit of
a black boxy algorithm as I guess is the
problem with neural net stuff as well
that you don't it's not it's black boxy
in the way that the data is so big and
so abstract that it's very hard to
visualize what's going on uh so like why
do some possibilities get eliminated
from the possibility space uh like so if
there's errors there it's very hard to
it's very hard to catch you usually have
to if you suspect there's something
wrong you usually have to write write
specific visualizations for that thing
but a very important part of my process
is to visualize the algorithms as I'm
writing them and doing this kind of
thing where I deliberately slow down the
algorithm and run it step by step to see
what's actually happening that's a good
way of
catching um uh catching bugs and seeing
if you're doing doing a necessary work
somewhere or like yeah seeing how things
yeah um um H maybe I missed this but how
did you um get inspired to use W
function collapse SL model synthesis for
your game development and do you know of
any prior examples in the game Space
this I know there are some other ones
that do it now I think I was one of the
first ones to do it like properly
especially for train generation I think
uh I actually like I I've been
interested in tile based procedural
generation for a long time and I
um I'd been thinking about like how do I
get sort of features that stretch across
multiple tiles and I've also been
thinking explicitly about like is there
a way to derive constraints from the
ways the tiles look to actually figure
out what's possible to build from them
and I'd been thinking about that and
then I came across a wave function
collapse algorithm of course I don't
know how many of you have seen the like
original implementation of it but that's
doing things on like a pixel art thing
it's not 3D tiles but since I've been
thinking about these this problem I
immediately recognized that oh this
actually this exactly solves the thing
I'm trying to figure out uh so then I
got um like working 3D thing up and
running fairly soon after that and then
I first I tried to do these beautiful
colorful environments Urban environments
like in
townscaper uh I didn't manage to put a
fun game on top of it uh because I
wanted it to be nice peaceful game
peaceful games are hard so then I made a
violent game instead bad North it's easy
to make fun violent games uh but then
after bad North I was going no this time
I'm just going to do the just going to
do the beautiful buildings and I'm not
going to put a game on top of it
whatsoever it's just going to be nice
yeah jump in um so you mentioned the
advantage of pathfinding for for this
particular approach yes do you feel like
you made any um artistic compromises by
that needing to par
or to put it the other way if you had
agents that didn't need that pathf
finding data but could still move around
whatever you generated would you do anything
anything differently
differently um
um
a I don't know I mean because to me
pathf finding is a really aesthetical
thing in of itself right you're really
intrigued if you see an Environ and and
has got little staircases or little
ladders or stuff like that and you start
to imagine how a person would walk
through this space I mean like
townscaper isn't uh it's not constrained
by pathfinding there's sadly nothing
walking around here whatsoever but
they're still like here's a little
ladder going up like this and I Tred to
make it sort of believable so that
there's not too many ladders and not too
few ladders and there's a bunch of
things like that and there's like little
you know here's a ladder going up to the
side of that house and there's little stair
stair
so pathfinding I mean sort of
an making it pathable is sort sort of
aesthetic in and of itself but also I
mean with any kind of game in mind you
that's the pretty core requirement uh
anyway yeah so I've never really thought
what I would do if I didn't have to do
that I think this is a nice example
because it traditional nav mesh if you
were doing that on this and you're
making that deconstruction constantly
it's going to be really hard to rebake
that Nev mesh every time yeah but if you
had a bunch of autonomous agents that
weren't dependent on uh a nav mesh or or
that graph already being there and that
they could just drop and player destroys
or builds whatever with your your your
tool but the agent still naturally
Traverse through that space but also the
thing about a tile-based environment is
you can keep a nav mesh in the tiles you
don't have to you don't have to run a
normal nav mesh algorithm to reconstruct
a huge nav mesh for the whole thing you
can just have little nav mesh Snippets
or just uh like I'm in bad North I I
explicitly made little bits of nav mesh
that sat on top of the tiles like as
meshes uh but in the new project I'm
hoping to just use the mesh as it is and
just cuz it's all already marked up with
different materials and what's navigable
and what's not um yeah so you actually
you you sort of just skip all the
expense the entire expensive nav
Click on any text or timestamp to jump to that moment in the video
Share:
Most transcripts ready in under 5 seconds
One-Click Copy125+ LanguagesSearch ContentJump to Timestamps
Paste YouTube URL
Enter any YouTube video link to get the full transcript
Transcript Extraction Form
Most transcripts ready in under 5 seconds
Get Our Chrome Extension
Get transcripts instantly without leaving YouTube. Install our Chrome extension for one-click access to any video's transcript directly on the watch page.
Works with YouTube, Coursera, Udemy and more educational platforms
Get Instant Transcripts: Just Edit the Domain in Your Address Bar!
YouTube
←
→
↻
https://www.youtube.com/watch?v=UF8uR6Z6KLc
YoutubeToText
←
→
↻
https://youtubetotext.net/watch?v=UF8uR6Z6KLc