PuzzleScript Rules

I was watching ThinkyCon, a conference on making puzzle games, and many designers mentioned that they use PuzzleScript to prototype their ideas. PuzzleScript is a puzzle design environment created by increpare, the designer behind Stephen’s Sausage Roll and many other puzzle games.

PuzzleScript is a marvel of economic design. A single text file specifies, all the graphics, levels, sound effects, and all the rules of the puzzle. It uses a custom system to concisely express rules. So concise that the rules of Sokoban can be expressed in a single line.

This efficiency comes because rules are expressed as find-replace rules. That makes it a grammar replacement system, which I last discussed when looking at Ludoscope and Unexplored. But it has many pragmatic features geared toward puzzle design, which I’ll explore in this article.

Continue reading

Trainright

A still from Steamboat Willie

There’s been a lot of clamour about generative AI for images, like Midjourney or Stable Diffusion. It’s killing creating jobs or whole industries; it’s illegally using copyrighted data for training purposes; it’s eroding the nature of art itself. I’m sure there are many out there who would be happy to see an outright ban on AI image generators and the like.

On the other hand, it’s undeniable that this is a valuable technology. Not just for the corporations making them, but of benefit to the world. Sure, every artist unpaid is someone else’s money saved, but also as the costs of art fall, that democratises everything around art. A friend of mine made personalised Christmas card this year, a small joy of the world that simply would not have occurred before. I co-wrote a custom murder mystery with ChatGPT in barely longer time than it took to play. The lowering skills bar for indie comics and games is something I hope leads to a profusion of new original things, much as digital art and games engines have spurred it in the past.

How can we resolve these things, to have our cake and eat it? Well, society has faced this problem before and has found a solution that, though imperfect, has endured for centuries.

Continue reading

Defining Chess Piece Moves using Regular Expressions

Suppose you wanted to code a simple chess game. One key bit of game logic is to describe what are legal moves for each piece. There’s only 6 types of piece (pawn, knight, bishop, rook, queen, king) so this isn’t exactly a hard task. You can write rules such as:

def canRookMove(from, to):
  # Ignores questions about colliding with other pieces
  return (from.x == to.x or from.y == to.y) and from is not to

But these days, I’ve been thinking a lot about grids, and the above approach just doesn’t generalize. What if you wanted to play chess on a stranger grid?

Three player chess (CC BY 2.0, source)

What would it mean to play chess on the grid above, or a hexagonal grid, and so on? You’d have to write a whole new set of rules, and they could get very complicated depending on the grid in question. What I want is a language that describes how pieces move, which generalizes to any board. And I think I’ve found it, using regular expressions.

Continue reading

Using Unity’s TextGenerator.verts

TextGenerator.verts is meant to give the position information of every character in a given string. This is useful in Unity if you need to align something with exactly where some particular text is occuring, if for some reason you are not already using TextMeshPro.

Older Unity versions created 4 verts for every character, which made life easy. But now many non-rendering characters don’t have verts generated for them, and the relationship between verts and characters is undocumented. I’ve reverse engineered it, as best as I can tell:

int? GetVertForPosition(int position, string text, TextGenerator textGenerator)
{
    var c = 0;
    var vert = 0;
    for (var i = 0; i < position; i++)
    {
        if (textGenerator.characters.Count <= c)
            return null;
        if (!char.IsWhiteSpace(text[i]) && textGenerator.characters[c].charWidth > 0)
            vert += 4;
        if (text[i] != '\n')
            c++;
    }
    return vert;
}

New Discord Server

Let’s face it, running your own WordPress blog is a sign you are woefully out of date. I can see plenty of readers, but never hear from them.

So I’ve created a Discord server. Feel free to log on and ask me support questions about my projects, suggest new article ideas, or just to hang out.

Don’t worry, the blog isn’t going anwhere. I think the jump might kill me if I leaped fully into the 21st century.