Over the last few years I’ve talked to a lot of people about procedural generation. Researchers who are interested in pushing boundaries. Developers who just wish the damn thing would work. Newcomers who wish there were better ways to get started. There are a lot of complicated problems, barriers and frustrations surrounding procedural generation (or generative software in general) and there are no easy solutions to any of them, but hopefully projects like Tracery, Cheap Bots Done Quick, PROCJAM and The PCG Book are helping towards some of them. Today I’d like to tell you about something I hope will also help solve some of these problems – a tool to help people understand, poke, tweak, improve and explore procedural generators, called Danesh.
Before I go on, I just want to state the obvious: I’m not under the illusion that I’ve solved any big problems in procedural generation with Danesh and I’m still learning a lot – this is just the first of hopefully many posts about the tool I’m making and the research work it’s going to allow me to do. But Danesh is now in a position where I can show some basic functionality and begin to explain my plans – which means you can let me know what you think and help shape the work I do! Alright, that’s the caveat out of the way.
Danesh is a plugin built into Unity (I’m still learning how to make them look nice, so the screenshot is a bit grey). It lets you load in a generator (either a sample one that comes with Danesh, one you wrote your own, or one you found online) simply by adding a couple of lines of code to the file. After you’ve loaded a generator in you can generate content and view it in Danesh, and fiddle with sliders for the parameters the generator has. You can keep generating and tweaking, and save configurations of the generator that you think are particularly interesting or cool.
This is the kind of thing that we already do with procedural generators when we make games – we see what output they produce and we think about whether we like it or not. Maybe we generate ten or a hundred outputs to see if it’s consistent or if there’s a wide variation. Then we tweak the numbers a bit until it looks okay. What else can we do?
Connecting Output To Input
One of the things that’s really hard to do when you’re making a generator is understanding how your code affects what comes out the other end. Is this spaceship I’m looking at an extreme case? If I change this number will it make all the spaceships better, or will a rare 5% of them be even worse? The parameters a generator has are like the input to the generator, but it’s really hard to imagine how they affect the output sometimes (even worse if the parameters affect each other in some way).
So, another thing Danesh can do is tell you things about the output of the generator. Danesh comes with some metrics for maps, and you can write your own, too. A metric is a bit of code that takes some generated content and calculates a number about it. Maybe it’s the ratio of petals to stamen on a generated flower. Maybe it’s the percentage of the colour wheel used in a picture. Maybe it’s the average value of a treasure chest in a dungeon. When you hit the ‘Generate’ button, Danesh runs all of these metrics on the output and gives you a report. This helps you see that, for instance, when I iterate the map generator more, the levels become more open because the rooms become bigger. We’re hoping to provide lots of metrics and help people write their own too – more on that in another post.
There’ll be more about expressive range in an upcoming blog post!
Understanding The Expressive Space
Of all the possible worlds you can imagine made of 3D blocks, Minecraft’s world generator only ever produces a certain kind of world. You can imagine worlds entirely made of oceans, or worlds with floating spherical planets in the sky, or worlds where mountains grow downwards out of the clouds. Minecraft doesn’t make these worlds because it’s designed to make a particular kind of place. You might hear researchers talk about the ‘possibility space’ or the ‘generative space’ or the ‘expressive space’ of a generator – that ‘space’ is like a big bag of every possible thing imaginable (in Minecraft’s case, every possible world made of 3D cubes).
Most generators just take a tiny handful from the big bag of possibilities, but how do you know which handful your generator is taking? Danesh can help show you by looking at hundreds or thousands of outputs from your generator, and measuring the metrics for each one. It averages out the results and plots them on a histogram. This is called an Expressive Range Analysis and it was first proposed by Gillian Smith and Jim Whitehead in a great paper you can read here. Expressive range analysis is complicated and needs its own blog post, but it’s really powerful. It might reveal that your dungeon generator never, ever produces a map with a secret treasure room next to a trap. It might tell you that although most of your world maps are well-connected, 10% of them leave the player stranded on an island. It can reveal lots of cool information about what changes you could make to the generator and what effect it might have.
Getting Help To Change Things
The last thing I want to mention before I end this introductory post is that Danesh isn’t just about being a passive tool that helps you do things – it’s not Photoshop for Procedural Generation. Danesh can actually go out and change your generator to improve it or tweak it in a way that you like. Suppose you sit around for half an hour changing parameters trying to stop your world generator from producing craggy messy island chains, desperately trying to get nice smooth continents forming. It’s infuriating you because every parameter change has wildly unpredictable results.
So instead, you write a metric that describes the average size of a landmass. Then you tell Danesh that you want to maximise this metric – you want landmasses that are as big as possible on average, but you don’t care what parameters it changes to get it. Danesh can then go away and run thousands of generative tests, changing parameters and examining the output, trying to find the result you want. It may or may not succeed; it might even come out with something you didn’t expect. It’s really cool and powerful and I’ve barely started working on it to get it being as useful as possible.
Changing parameters to the generator and testing them out.
As you can probably tell, Danesh is a bit complicated and needs some good writeup. I’m planning some more blog posts diving into certain concepts in more detail, and some video tutorials that show the tool working. There’s also the small matter of actually launching the tool! This is all coming up in the next month or so. I’m hoping that Danesh will be able to be used for all sorts of things – not just for developers looking to optimise their software, but for newcomers who want to tinker and experiment without writing code, and for researchers looking to do experiments and maybe add their own extensions to Danesh to include their research. There are a ton of cool research questions wrapped up here that I want to pursue too.
Danesh is a big ugly mess of grey and complicated terms at the moment, but I am hopeful it’ll turn into something really useful, even if it takes a while. Since Unity is lacking good procedural tools right now, maybe we’ll even manage to contribute something useful to the platform! But for now, I’d love to hear what you think about the idea and what you’d like from a procedural generation tool like Danesh. If you’d be interested in helping me test the software sometime you can drop an email to generate at gamesbyangelina.org. Thanks for reading!