How to make procedural puzzles

I’d like to share what I did in my game to procedurally generate puzzles. The cool thing is that this technique is quite general, so it may work for your games as well. If you’d like to, you can play “You! Are the monster” before reading on.

In my case I generate a “whodunit” type puzzle. There are four people and they say things about where they were, what they wore, and who they saw. Sometimes it’s vague, like “I saw someone tall at the bar”. The bad guy is a monster, of course, and they can lie but no one else does.

We can’t just generate those statements entirely at random, because some puzzles may end up unsolvable. So here’s what I do instead.

I start with only a few statements – one per person. I pick those at random. Then, I try to solve the puzzle (more on this later). If there is more than one person who could be the monster, then I add more statements. If instead no one can possibly be the monster, I start over. This eventually leads to finding a solvable puzzle.

Then I trim it down, removing statements that are not necessary to the puzzle being solvable. This results in a puzzle that is hopefully fun to solve.

One thing I only realized after the compo deadline is that this technique sometimes generates trivial puzzles, where the monster says things that contradict themselves. I fixed this is the post-compo version.

Now, you may ask, how do I solve the puzzle? I use brute force. Each randomly-generated statement is not only a bit of text, but also a bit of code that can check if what it says is true. I cycle through every possible choice for who is the monster, and then look for a combination of choices (people,location,color) such that every non-monster person tells the truth. If I find one then it means that that particular monster can be a solution. There can be either zero, one, or more solutions. I stop as soon as I find two since I know that’s not a puzzle I’ll want to keep. So a good puzzle has exactly one solution: if I remove the monster, then there exists a scenario that means everyone else tells the truth. If I pick anyone else as the monster then the remaining statements (including the actual monster’s) don’t go together – there is no scenario where they can all be true at the same time.

Surprisingly enough, this generation is fast enough that I can run it at the client as you load the page, and I didn’t even feel the need to put up an animated spinner or other “please wait” indicator. For more complicated problems, though, this may become necessary.

So there you go! With this simple technique you too can generate procedural puzzles to add to your game. Let me know what you think in the comments!

Comments

randoman
30. Aug 2015 · 05:30 UTC
I love finding new techniques in puzzle design, that was a very interesting approach. I haven’t played it yet but I’ll be sure to check your game and see this in action!
panda
30. Aug 2015 · 06:10 UTC
Thanks, @randoman!
30. Aug 2015 · 12:26 UTC
This is a really cool approach. It seems like at heart it could just be boiled down to a linear algebra problem, and so optimised a lot. Could be an interesting project…