Folly updates and ParserComp notes

It’s been a while since I posted anything about Folly - a Z-machine with handwritten input. A few notable changes since that post:

  • Folly has been released to Toltec¸ the standard package manager for the reMarkable tablet. This makes it just as easy to install to the tablet as any other homebrew software… which is to say, still a hassle, but less so now. (If you have the tablet and want help installing, feel free to DM!)
  • There’s a new tutorial, written in Inform 7. It doesn’t really make any attempt to teach the user to play IF right now; just runs through some basic mechanics of playing on the tablet.
  • Bronze also ships with Folly out of the box – thanks to Dan Fabulich for the suggestion. (The hint mode runs slowly on the tablet, but the game itself plays quite nicely.)

One rich source of small improvements has been using Folly; in particular, I’ve done my best to play through all the Z-machine comp games from the last few months. I’ve just finished getting through the three from ParserComp 2022… to celebrate, a few brief reviews along with some Folly-specific comments, below.

The Impossible Stairs

An authorized sequel to Åkesson’s Impossible Bottle, which one imagines to be something of a daunting task: because The Impossible Bottle is very good, and because it wrung enough of the juice from its novel mechanic that there wasn’t much left there for a sequel. MathBrush manages this challenge rather elegantly, with a new mechanic that’s similar enough to the original to feel connected but different enough to feel fresh.

Overall, I liked the Impossible Stairs quite a bit: the puzzles are fair, well-implemented, and sometimes pretty clever, and the writing is overall effective. There are brief beats in the story that touch on themes of nostalgia or loss, and I found them affecting and somewhat melancholy without tipping into the sentimental. Compared to The Impossible Bottle, the protagonist isn’t quite as well characterized and the NPCs aren’t quite as lively or deeply implemented… but few games bear comparison on that front, of course.

Format-wise, this is a very classic parser IF, and Folly handles it well. The only awkward moments are the choice-based dialogue, where it would feel much more natural to tap on an option instead of typing a number with the onscreen keyboard, like you can when playing online. Occasionally I’m tempted to try to teach Folly to try and autodetect menus and allow taps to navigate, but I’m not sure I could do it reliably enough to be worth the effort.

Alchemist’s Gold

A short, old-school text adventure.

Alchemist’s Gold is both linear and lightly-implemented; you have few objects to work with at a time, and the game’s not afraid to break the fourth wall or firmly steer you away from fruitless lines of action. Puzzles are presented one at a time, and none of them are particularly difficult. The overall effect is fast and light; it’s an easy game to run through in a single sitting, amusing and uncomplicated.

This games features a maze, and gives you and ASCII map for it. I don’t love ASCII diagrams in IF: they’re almost always less legible than “real” graphics, narratively irrelevant, immersion-breaking, and typographically unpleasant. (Though quite common in the old-school games Alchemist’s Gold is styled after.) They’re also slightly unfortunate for Folly… the ASCII map tends to get split awkwardly between pages, and handwriting long sequences of directions to navigate through can be tedious. Still very playable, though!

This game also evinced a bug in Folly’s get_cursor implementation; will be fixed in the next release.

You Won’t Get Her Back

Another chess-based narrative/puzzle hybrid from Andrew Schultz. This game also uses ASCII diagrams for the chessboard. This is a rare case where the diagram is intimately connected to the story, since the whole idea is threading a narrative through a classic chess puzzle. I certainly enjoyed the experiment.

The use of standard chess notation works well. here… especially in screen-reader mode, where both your commands and the game’s responses are all in the same language. (Unfortunately screen-reader mode is quite buggy, which somewhat reduces the effect.) I enjoyed this game most when I pulled out a physical chessboard to help me worth through some of the positions, though… even with the ASCII I found the board a bit tricky to visualize.

Folly handled this game pretty well – except when trying to input the chess notation. The handwriting recognition is tuned for full english words, and struggles with what looks like random combinations of characters. I ended up falling back to the onscreen keyboard.

10 Likes

I didn’t see your original post about Folly, and I’m well impressed.

-Wade

2 Likes

As soon as I started reading this, I wondered if it would work with my z-code games. Then I found that you’d done a mini-review of ‘Alchemist’s Gold’ and it worked. Whew! What a relief.

1 Like

Yeah! Overall I’ve been pleased how well most games work when thrown into a brand-new interpreter with a very different UI paradigm.

I don’t suppose you happen to know what your game uses the get_cursor opcode for? I’ve been imagining it’s some PunyInform thing – Alchemist’s Gold might be the first game using that system I’ve tried out, and it’s the first time I’ve seen it used in any game.

I just searched the library and @get_cursor is used in the following routine in puny.h:

[ _PrintSpacesOrMoveBack p_col p_string _current_col;
	p_col = (HDR_SCREENWCHARS->0) - p_col;

	@get_cursor cursor_pos;
	_current_col = cursor_pos --> 1;

	if(_current_col > p_col || cursor_pos --> 0 > 1)
		_MoveCursor(1, p_col);
	else
		FastSpaces(p_col - _current_col);

	if(p_string)
		print (string) p_string;
];

The _PrintSpacesOrMoveBack routine is used numerous times when updating the status line. @fredrik can explain more.

3 Likes

The Inform 6 standard library uses a loop to fill the status line with spaces (to erase any remains of the previous contents of the status line), then prints the new status line information. This causes the statusline to flicker on and off as it’s updated on slower platforms, and it’s very inefficient.

PunyInform prints the room name, checks where the cursor is, prints the required number of spaces to get to where it wants to print “Score”, prints “Score: 123”, checks again where the cursor is, prints spaces, prints “Moves: 123”, checks the cursor position and prints spaces to the end.

If at any point the cursor is found to be to the right of where the routine wants to print the next item, no spaces are printed but the cursor is moved back instead. This can happen if the room name is very long.

Additionally, the PunyInform status line adapts to different screen sizes and tries to make the most out of any screen size, and it has several other optimizations for speed.

Note: I also realize that none of this matters when running games on a modern computer. It does matter on 8-bit computers.

2 Likes

I thought it was basically required because in old console interpreters the old status line would just scroll out of view as more was printed in the main window. But I haven’t actually looked at how they operated so maybe that’s not true.

On interpreters which just let the statusline scroll off the screen, the top line of text from the main text window (called the lower window in the Z-machine) will occupy the top line. On an interpreter where the top line doesn’t scroll off the screen, the previous contents of the status line will be present. In either case, this text needs to be overwritten so none of it remains. The standard library and the PunyInform library both accomplish this, but in different ways.

Thanks for the review! I hope you have a chance to play other games, as there are some good ones. I wasn’t aware of Folly, but it looks like ParserComp was a natural fit for testing it.

And I realized on reading this that reviewers who feel “hey, I can only stick to one format, should I bother?” – well, they should. I wouldn’t have felt left out if someone had reviewed only the ADRIFT games.

Also, thanks for the bug report at GitHub! I wasn’t sure where best to reach you on this, but I appreciate it, and I encourage it from reviewers and judges in general.

If you have preferences how to be credited, let me know via whatever’s most convenient for you. (PM, Github, etc.)

Thanks – this makes sense! Naively I figured that you’d know the length of text you were printing and thus wouldn’t have to read it back… but now that I think about it, it sounds much more annoying to figure that out in advance than just printing and checking.

1 Like

It is possible to figure that out in advance, but only in Z-machine versions 3 and up (when output stream 3 was introduced), and also it takes more work than just asking the terp where the cursor is—you have to print the text to a buffer and then ask how many characters were written to that buffer, instead of using a single @get_cursor opcode.

Z-machine strings are compressed in a way that means the game can’t examine them easily at run-time, and also they’re often actually routines that stitch together many pieces of compressed text, so the only way to get the length is to print it and then see how much was printed.

3 Likes

Certainly! And yep, a few others, all delightful, though I do tend to start with the Z-machine set. (Aside from helping me test my thing, the e-ink means I can play in the evening without ruining my sleep.) ParserComp’s definitely been a great source, but every major comp seems to have a couple Z-machine games… dwarfed by Glulx nowadays of course.

Glad! I’m sometimes hesitant to post reviews, partly for this reason and partly because I’m playing through the games in a format the author did not intend, so it’s not necessarily representative of the typical experience. But I guess the diversity of interpreters and hardware is not a new issue…

No trouble! And no need to credit, though if you choose to whatever format you normally use is fine.

2 Likes

I’m not sure if output streams were added to version 3 by Infocom or by the people working on the modern-day Z-machine standard, but I can say for sure that not all Infocom version 3 interpreters support it, so we decided never to rely on it in PunyInform (Some of PunyInform’s users want to release their games for as many 8-bit platforms as possible, and in many cases the only interpreter available is an old Infocom interpreter).

As for this particular case, as you say, reading the cursor position is typically a lot cheaper than printing the room name twice.

1 Like

Huh, good to know! I’d figured the Standard attributed it to version 3 because it was used in existing version 3 files, but I have no idea where/when it actually showed up (except that I’m pretty sure Trinity, in version 4, used it for centering text and sizing quote boxes).

1 Like

I’m glad to give credit–I’m still thrilled by the novelty of receiving bug reports at GitHub for a game during the comp. I’ve had comments on itch, but when it’s on GitHub it’s that much more efficient!

Also, you helped me track down a bug that only happened at random. It involved a fault in the repetition detection code that had a low chance of happening during black’s (quasi-random) final move. But when I did verification-testing, an odd error was thrown that didn’t seem related to the change I made.

If the enemy rook fled to d4 after promotion, it could mistakenly trigger the “hey, you repeated!” code, because the way I tracked states was based on your king’s position and the rook’s. It did not take into account pawn moves in between. But this slipped through, because it was rare for the enemy rook to flee to d4! So when I mapped the board position to a 16-bit number, I set the high bit iff your pawn promoted

1 Like