Skip to content

#PROCJAM PuzzleScript + Tracery Selecting Predefined Rules

Sun 21st October 2018

In 2017 I started a little project as part of #PROCJAM. The idea was to take Tracery, an engine for randomly generating pieces of text, based on a predefinied grammar for that text, and combine it with PuzzleScript, a markup language for 2D block-based puzzle games, and use Tracery to randomly generate new games in PuzzleScript.

Unfortunately, I didn’t really finish it, partly because I was job hunting and partly because I got a bit distracted by rewriting the parkrun NYD Double Finder. They’re not excuses, just parts of the narrative that make up this description. This year, as PROCJAM begins in 2018, I am enjoying my job as a software developer at Nureva, but have not yet updated the Double Finder for 2018 (I’ll move onto that after PROCJAM). As I have unfinished business with my Tracery-PuzzleScript generator, I am going to pick up where I left off and see how much further I can take it.

Last year I made some progress in investigating the rule structure of PuzzleScript, and put together a really small JavaScript demo using the Tracery library to generate 3 completely random, and because of that, near meaningless, rules! I posted about that last year and the code for that tiny demo is on GitHub.

As a starting point this year, I hope to bring some more meaning and sense to those rules. I think this will require some constraining of the possibility space, which feels like it removes a bit of the pure randomness of procedural generation, but equally I think picking the constraints is part of the art of creating a generator. After all, I already decided to scope this generator down to making block-moving, Sokoban-esque games.

I found in my working directory from last year a text file where I had brainstormed some player-block interactions that make some sort of sense in a block-moving puzzle game, and coded them up in PuzzleScript syntax (see below): push, bump, swap, block, opposite. There were a couple of others that were getting more wacky. There could also be more, so it might be worth me enumerating the possibility space, testing all the possibly rules and see if there are any others that make sense.

Brainstormed types of block-moving interaction:

[ > Player | Crate ] -> [ > Player | > Crate ] (push)
[ > Player | Crate ] -> [ Player | > Crate ] (bump)
[ > Player | Crate ] -> [ Crate | Player ] (swap)
[ > Player | Crate ] -> [ Player | Crate ] (block)
[ < Player | Crate ] -> [ < Player | > Crate ] (opposite)

Based on these potential interactions, I adjusted the Tracery grammar to generate a predefined rule for each type of block in the level (2 currently). My vision here is to generate a bunch of different types of blocks throughout a level, and each type will have a certain type of interaction (push, swap, bump, etc.) creating a puzzle where you have to figure out how to move each block type, then solve the level.

Example generated rules for the two types of block:

[ > Player | Badger ] -> [ Badger | Player ] (swap) 
[ > Player | Crate ] -> [ > Player | > Crate ] (push)

Swap Badger, Push Block

I’m not entirely sure this is where I eventually want to end up. With this approach I’m randomly selecting from predefined mechanics, and placing the blocks that use each of those mechanics in a level. That feels a bit too much like level generation rather than rule/mechanic generation. I guess to an extent it is system generation, as the combination of mechanics will be generated and could make something interesting. I would also like to loop back and see if I can do a bit more in terms of mechanic generation, rather than just selection, after I have a bit of a broader generator.

  1. I imagine the issue with mechanic generation is you don’t know if a mechanic works or is winnable?

    Do you have a system for testing if a particular game is playable? Maybe writing a system to solve games of this type with arbitrary mechanics would be a starting point to generating new mechanics (as then you could test if your combinations work).

    • My plan was to build a level generator in a way that constructs levels that are completable using the generated mechanics. I guess there is still then the open question of whether anything generated is interesting to play… or should I care about that up-front?

      It’s a great question though. It’s got me thinking about what the scope of this actually is. If I can come up with a set of heuristics that determine a playable game, why not build those into the generation algorithm, so it generates them playable from the outset, rather than randomly generate and throw away the ones that do not work.

      It’s also reminded me that part of the inspiration of this challenge was to see if this is possible just within Tracery: can I build a grammar that generates all the bits of a PuzzleScript game. I don’t think Tracery has the expressivity to build a utility function for what it generates, and if it does, it’ll be complicated to write and understand.

      Maybe you’re right. Maybe I should generate with freedom in Tracery+PuzzleScript, then write something outside of that to evaluate what’s generated. Lots to think about, thanks!

Trackbacks & Pingbacks

  1. #PROCJAM PuzzleScript + Tracery Generating A Whole Script | Rikki Rants

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

<span>%d</span> bloggers like this: