[I7] Creating Puzzle Pieces, Like in Jigsaw

An interesting question came to me from some teachers investigating various Inform games. They asked me how something like the puzzle piece from Jigsaw could be created in Inform 7.

For those who aren’t aware of what I’m talking about, here’s what that looks like:

Jigsaw.Puzzle.Piece

Anyone have any ideas on that?

This is an interesting question! May I ask for a clarification? Are you interested in how to draw the jigsaw piece from a graphical perspective or are you interested in modeling the mechanics of a jigsaw piece itself so it is possible to create and have interactions with multiple jigsaw pieces? Possibly both? Note: I am not familiar with Jigsaw.

Right now the idea is just around being able to actually draw the puzzle piece as in that screen shot and this is mainly because of varying age groups wherein the puzzle pieces could be used for different aspects of a story, such as shape and pattern recognition.

To be honest, it’s been a very long time since I played Jigsaw so I have to reacquaint myself with how the puzzle pieces were used in that game.

But, again, to clarify, right now the immediate intent is simply figuring out how to draw render something like that.

Jigsaw’s puzzle pieces are just text, with fixed width font formatting. That sort of thing is really easy to produce in pretty much every dev system.

The picture of a puzzle piece is an arrangement of Unicode characters, possibly █ (“Full block,” U+2589), displayed in fixed width so that the spaces in between take up as much space as the █s. Essentially, █s and blank spaces become black and white “pixels.” “Drawing” with text in this way is incredibly inconvenient but it’s SO MUCH FUN. (Well, it’s fun for me. It’s not fun at all for people who play with screen readers, so you gotta keep that in mind.)

Here’s a trivial example. I went into my text editor and drew a beautiful sun with █ characters:

█ █ █ █
█████
███████
█████
███████
█████
█ █ █ █

Whoops! When I paste it into a forum post, the leading spaces get removed, multiple spaces are collapsed, the and spaces are rendered as much more narrow than the boxes. So it looks more like a neat bug than a beautiful sun.

I will use the forum’s option for preformatted text (put a line that says ``` on the top and bottom) to present it in fixed-width text:

█ █ █ █
 █████
███████
 █████ 
███████
 █████
█ █ █ █

The forum’s option for preformatted text has a built-in setting for line spacing that is stretching out my sun vertically. But you can see how if those lines were squished together, it’d look like a beautiful sun.

The same stuff happens when I try to display the sun in Inform 7. If I make a rule that says

say "█ █ █ █[line break] █████[line break]███████[line break] █████ [line break]███████[line break] █████[line break]█ █ █ █[line break]"

the spaces don’t display correctly and I get that neat bug. If I include [fixed letter spacing], as in

say "[fixed letter spacing]█ █ █ █[line break] █████[line break]███████[line break] █████ [line break]███████[line break] █████[line break]█ █ █ █[variable letter spacing]";

the space characters are fine, but the lines are still spaced out too far.

Jigsaw doesn’t have this problem! So there’s some other step to take to make those puzzle pieces look nice—I think it’s accomplished at the Inform 6 level. I don’t know.

I do know a dumb workaround, but it only works for browser interpreters. (This is how I made Unicode QR codes in Ryan Veeder’s Authentic Fly Fishing.) First, Include Glulx Text Effects by Emily Short. This lets you style text as [first special style].

You also want to Release along with an interpreter.

Then, replace your references to [fixed letter spacing] with [first special style], as in:

say "[first special style]█ █ █ █[line break] █████[line break]███████[line break] █████ [line break]███████[line break] █████[line break]█ █ █ █[variable letter spacing]";

(We still use [variable letter spacing] at the end to return to normal-style text.)

When you compile this game in the Inform 7 IDE, the beautiful sun will come out looking like that neat bug again. And when you open up the HTML page with the Quixe interpreter, it’ll still look like a neat bug!

But you can change the properties of the “first special style” by changing glkote.css, which is in the Interpreter directory of the Release folder. At the bottom of glkote.css you’ll see:

.Style_user1 {
}

.Style_user2 {
}

These classes contain the properties of text that you refer to in Inform 7 as [first special style] and [second special style]. You can change some of their properties in Inform 7 (see the Glulx Text Effects documentation), but you can change all of their properties here. We want to add fixed-widthness, but we also want to change the line-height.

You can see elsewhere in glkote.css that line-height is normally set to 1.4, which spaces things out nicely for comfortable reading. Intuitively the correct line-height for lines being perfectly flush with each other should be 1, but after playing with it for a while I think it looks best at 1.15.

So make it say:

.Style_user1 {
    font-family: "courier new", monospace;
    display: block;
    line-height: 1.15;
}

Save glkote.css, reload that Quixe interpreter—and at long last we get to see a beautiful sun, just as the artist saw it in his mind’s eye:

Screen Shot 2020-02-26 at 10.18.04 AM

4 Likes

The slightly tricky part (if I recall correctly) is that Jigsaw prints spaces in a fixed-width font, setting some of them to the “inverse” text style. The Z-machine supports this. However, not all systems will support text coloring or inverting in a completely portable way.

A modern alternative would be to print Unicode character-graphics symbols in a fixed-width font.

    ██ ██
    █████
      █████
    █████
    ██ ██

They won’t join up as nicely, but they should work on any modern interpreter regardless of color scheme.

EDIT: I see Ryan posted the same thing, with code, faster. :)

3 Likes

Ah, thank you for the info. I figured this was not necessarily as easy to reproduce given my initial attempts. This definitely gives me something substantive to play around with so I’m deeply appreciative of the effort here.

I’ve been thinking about this stuff for a long time, so partly to amuse myself I’ve made an example of a tiny jigsaw puzzle with source code to look at. The code isn’t commented, so the crucial step of modifying glkote.css is not made obvious, but it might still be useful or at least interesting.

2 Likes

Absolutely fantastic! Thank you for the effort here. This is much more than just helpful; this actually gets me entirely past my roadblock so I can start playing around and showing examples.

1 Like

Aw, shucks!

If you use fixed letter spacing and reverse mode formatting then many interpreters will make sure that the line spacing is correct for ASCII art like this. If you use unicode like U+2589 then there’s no guarantee of that - it’s not a pattern interpreters will know about. If the spacing is important, go for the classic method of fixed spacing and reverse mode.

When you say this, what does that mean in the context of Inform 7? If I explained it this way to my teaching group, they would probably look up “reverse mode” or maybe “reverse text” in the Inform 7 search – and would find nothing at all that seems relevant.

Newer people approaching this won’t know what the “classic method” is, particularly if it’s not articulated anywhere, which is what I’m struggling with.

1 Like

I believe what they’re saying is “reverse” as in if you normally have a black text on a white screen, reverse will swap the two so that it’s white text on a black screen. If you have it as fixed width and do an empty space, it’ll make a black square (because it’s empty text on a black background) that every interpreter will render correctly regardless of your font or unicode support.

https://i7el.herokuapp.com/extensions/basic-screen-effects-by-emily-short

If you search for “reverse” on the page that I linked, you’ll see some examples done with text. While the examples are not trying to make ascii art, the result should be the same.

I’d say the opposite, actually. Fixed letter spacing should include fixed width for block characters. You might not get fixed-width display of emoji, ligatures, or Asian alphabets. But block characters are well-established in Unicode and rendering engines will deal with them correctly.

(It’s practically guaranteed that the IF interpreter will not be doing the font rendering itself. It will outsource that to some OS-level text rendering API. Or browser-level if the interpreter is written in Javascript.)

So Unicode is the generally safe path. Relying on inverse mode is only going to work on the Z-machine, and maybe not there depending on how the interpreter deals with theme preferences.

1 Like

I meant just in terms of line spacing. Remember when we worked at making the Jigsaw pieces work in Lectrote? That was possible only because it was using fixed width formatting across line breaks. If it had used block unicode characters in proportional width font then I don’t think we would’ve written anything to try to detect the blocks and change the line spacing. Yes there may be some exotic characters which display engines could have trouble showing in fixed width, but exotic unicode is always a risk. (I think most CJK characters should be safe, but it depends on the engine and font etc.)

Reverse mode is also available for Glk/Glulx, either through Style_user1/2, or through this extension, which at this moment is supported only in Gargoyle and Windows Glk (though also the WIP Quixe update I shared with you earlier Jeff, though I can’t remember if I fixed the line spacing issue yet or not, I think I didn’t actually, sorry):

Of course these days in Glulx you can also just use images. That might be the most reliable!

There are fixed-width unicode characters even in proportional width fonts. The emoji. Particularly White and Black Large Squares.

:black_large_square::white_large_square::black_large_square::white_large_square::black_large_square::white_large_square::black_large_square:
:white_large_square::black_large_square::black_large_square::black_large_square::black_large_square::black_large_square::white_large_square:
:black_large_square::black_large_square::black_large_square::black_large_square::black_large_square::black_large_square::black_large_square:
:white_large_square::black_large_square::black_large_square::black_large_square::black_large_square::black_large_square::white_large_square:
:black_large_square::black_large_square::black_large_square::black_large_square::black_large_square::black_large_square::black_large_square:
:white_large_square::black_large_square::black_large_square::black_large_square::black_large_square::black_large_square::white_large_square:
:black_large_square::white_large_square::black_large_square::white_large_square::black_large_square::white_large_square::black_large_square:

I heard it’s very popular on Twitter and the like.

1 Like

These would look a lot nicer if they were actually rendered as black and white squares, rather than light grey squares and black squares with rounded corners. But I guess that depends on the font?