Arcturus - a new programming language & compiler for the Z-machine

Excellent? Maybe. I’ve found that has docs get longer and systems get more complex it produces stuff significantly less good than I’d write myself.

thanks @andrewj and @fredrik!

Fredrik is right, and cheap_scenery does more than the EXAMINE-only summary suggests: an entry’s routine acts as a before routine and can react to anything. I used PunyInform to create some of my most successful games, no criticism of it from me.

grains don’t differ in the purpose but in the layer. cheap scenery in Puny is an extension you wire up: a property array of word pairs and string-or-routine entries, with conventions like SceneryReply, ID constants, and a parse_name escape hatch when the word-pair model gets tight. It works well, but it rides on Inform property arrays, and a Z-machine property tops out at 64 bytes of data (the extension itself warns when a room’s array crosses that).

In Arcturus this is grammar and not a pattern. Basically one line inside the room: verbs, words, response.

grains
    examine, touch "dunes" or "sand" say "Fine, pale sand, still holding the day's heat."

Any number of alternate words, inline bodies with real statements (blocks) when a string isn’t enough, no format conventions, no property ceiling (the compiler builds its own table), and words reuse freely across rooms because a word points at a chain of owners and scope decides.

But this is something you can only do when you own the compiler, which Fredrik of course doesn’t since PunyInform compiles against the Inform 6 compiler.

I think we should move the community’s radar to the more unique features where I am still certain they don’t have a sibling on other Z-machine languages like auto-scoring and intelligent containers. :smiley:

2 Likes

It did work well for me I have to say, but what annoyed me was that Claude did things in a very different tone and sometimes made easy statements in the docs quite verbose. So I ended up doing the majority myself.

I will say though, regardless of my own experience, if you give it enough context as reference, it may be able to produce a decent starting point.

1 Like

Man, this looks neat, great job! I love the idea, and I’m curious how you implemented the languages in your language itself, since it’s very similar to what I’m wanting to do in my language. I’ll have to check it out when I get a chance.

Yeah, in my experience with AI docs so far, it tends to easily get good coverage but it’s annoying the way it talks and it has a hard time understanding a good, relevant level of detail in description and explanation. It doesn’t seem to have a good idea of what is important to cover in a given context.

1 Like

The source is well documented on GitHub, and ping me anytime if you have questions. I’m always happy to help! :right_facing_fist::left_facing_fist:

1 Like

This fits with the general ZIL philosophy, which is that all action routines are stacks of verb-check cases.

1 Like

He’s published the Python source. You can always ask Claude if the source code is hard to follow or Python is not in your wheelhouse yet.

As an interpreter author and Glk implementation maintainer, I’d be more inclined to look into support if Blorb is a supported container format. That code already exists. Adding a new format would require more new code that effectively duplicates what is already the standard IF container format.

2 Likes

Thanks Andrew! That’s a lovely bit of lineage. In the PSEUDO model the words share one routine that sorts out the verbs itself, the ZIL stack-of-verb-checks you mention. Grains move exactly that sorting into the declaration: each line names its verbs up front, so the “routine” disappears and the compiler does the dispatch. Same old good idea, with the verb-check stack absorbed into grammar. Forty years of convergent evolution on pseudo scenery; I find that rather comforting. :slight_smile:

I direct Claude to show facts, examples, and minimalist text. This prevents the word salad you’d otherwise see. And then I edit and add my own content.

To make sure I understand what you mean by “intelligent containers” correctly: this is the feature where a closed container still lists any items it contains which have been seen by the player? I have some reservations about this: what if you have an item like an ice cube or fairy gold that disappears after a certain amount of time? Then despite the player not seeing it disappear, they know it’s gone because the container no longer lists it among its remembered contents.

Also, how much work would it be to add TAKE ALL and DROP ALL?

1 Like

@cas @Draconis Good news: Blorb is in. The Arcturus image tool arcimg now optionally writes .blorb and .zblorb. The mapping was trivial because the concepts were already aligned: an arc_image picture id is simply the Blorb resource number, Pict 8 is picture 8, so the master PNGs are carried verbatim.

So for an implementing interpreter the whole job is the story-file protocol from the interpreter book: set the capability bit if you can draw, honor the one extension opcode, render the band above the text, and pull Pict N from the Blorb you already know how to read. Nothing else is required reading; the .arcres zip and the .arc retro containers are for my own interpreters d, and you never need to touch either.

And my own modern interpreter Actaea now reads Blorb too now, both shapes, because a shared standard should be shared from both ends. Chris, I’d be glad to help you land it, and the test assets are in the repo. Just let me know if you have questions.

2 Likes

Fantastic! It shouldn’t be too hard to make a future version of Dialog emit this instruction on interpreters that support the extension.

I know I’m focusing overmuch on the new opcode over the new language, but I unfortunately won’t have the opportunity to dig much into the language until after IFComp.

1 Like

Amazing! That’s why I kept it a plain extension opcode plus a capability flag: the interpreter book (docs/08 in the repo) is written to be implemented regardless of the language used. If a Dialog backend wants to emit it, I’m glad to help and happy to firm up anything in the spec if needed!

And no apology needed for looking at the opcode first, that it’s separable from the language is the point. The language will still be here after IFComp, no worries! I am pretty sure you are going to like it.

1 Like

I’d suggest a separate topic it it is going to be semi standardised. Using one of Z6’s header flags is a pretty safe option, though perhaps in Blorb output there could be some extra indication outside the zcode that the extension will be used. The opcode could also be moved to a lower one rather than using a PUA code.

2 Likes

Success! Looks like the next Gargoyle release will have support for Arcturus images:

2 Likes

On the blorb: I could add a small custom chunk in the Blorb alongside the RIdx and the resources, and every existing Blorb interpreter ignores it harmlessly.

What I’d put in it, minimal and actually useful:

Chunk type: 'ARCI'   (self-identifying, uses arc_image)
Payload:    1 byte   extension version (1)
            1 byte   band mode (9 or 12 - Infocom Arthur style [9] or DAAD style [12])

The mode is the valuable part. It tells an interpreter the band geometry, 72 or 96 pixels / scale factor, before a single opcode executes, which is exactly what a layout-driven interpreter like Parchment needs.

Is something like this what you had in mind @Dannii?

Oh wow. That was fast @cas! Amazing. Having this supported in a flagship interpreter like Gargoyle is a big value add for the community. Thank you very much Chris!

1 Like

It won’t affect whether I support it in Bocfel at all, but I’d love for this custom chunk to be mandatory if you’re using a Blorb file with a game that uses arc_image. As in, if you don’t have that chunk, you’re not guaranteed graphics. It’d simplify things for me a bit to know, up front, if your game wants to use this opcode.

But if you prefer for it to be optional, that’s fine: I’ve already got code in place to handle it.

1 Like

That’s a valid reason Chris. I am going to add it.