Inform 6.43

No, it’s not redundant.

Remember that until GRAMMAR_META_FLAG was added, the action table didn’t have flags. Flags could only be applied to dict words. In your example above, the dict word 'Load' has the META flag, and the old library will assume that every command starting with that verb word is a meta action.

With GRAMMAR_META_FLAG set, you can test whether an action is meta rather than relying on dict word flags:

if (action <= #highest_meta_action_number) {
  ! this is a meta action.
}

Ah, my bad.

When you set the GRAMMAR_META_FLAG, a line like Verb meta ‘save´ * -> Save; marks the verb as meta, and marks the action as meta. An old library will still use the meta-flag on the verb. A new library will detect that GRAMMAR_META_FLAG is set, and care about meta-flags on actions but ignore meta-flags on verbs.

Correct!

Except that a new library could observe both conventions (the dict word test and the action number test). That’s up to the library designer.

It makes sense that Puny would throw out the dict word test to save a few bytes of code.

But if the library defines say Verb meta ‘save’ *-> Save; and then the game author defines GRAMMAR_META_FLAG and does:

Extend 'save'
  * 'energy' -> SaveEnergy;

[ SaveEnergySub;
	print "You stay very still.";
];

The ‘save’ dictionary word will now have the meta flag, and so will the ##Save action, but not the ##SaveEnergy action.

If the library reacts to the meta flag on the dictionary word in this scenario, both actions will be considered meta.

If we change the grammar in the game file to:

Extend 'save' replace
	* -> Save meta
	* 'energy' -> SaveEnergy;

… we get exactly the same result.

Instead of drawing from my admittedly bad memory, I just tried this out:

Extend 'save' replace
	* -> Save meta
	* 'energy' -> SaveEnergy;

[ SaveEnergySub;
	print "You stay very still.";
];

[Initialise word_data;
	print "^^And so the story begins...^^";
	if(##Save <= #highest_meta_action_number)
		print "Save action is meta!^";
	else
		print "Save action is not meta!^";
	if(##SaveEnergy <= #highest_meta_action_number)
		print "SaveEnergy action is meta!^";
	else
		print "SaveEnergy action is not meta!^";
	word_data = ('save' + DICT_BYTES_FOR_WORD) -> 0;
	if(word_data & 2)
		print "'save' is meta!^";
	else
		print "'save' is not meta!^";

];

And this produces:

And so the story begins...

Save action is meta!
SaveEnergy action is not meta!
’save’ is meta!

Well, that is true.

Should we consider that a bug? We could say that if you apply (old-style) meta to a verb, then any Extend of that verb should inherit the meta-ness for all of its actions.

To me, it’s fine as it is. It just means the library needs to either check meta-ness on the dictionary level or the action level, but not both.

And it’s great that game authors can now easily add actions to a library-defined verb that don’t have to have the same meta-ness.

I’d just make sure to document the way it works, well.

When thinking of different ways to do this, I just keep finding corner-cases and behaviours that would make it hard or unintuitive to work with, no matter how you do it. The current design is among the best options, I think.

I have no idea how hard it would be, but clearing the meta-flag on all dictionary words when the GRAMMAR_META_FLAG is active would perhaps save some confusion. I’m not sure it’s worth a new compiler release immediately, and if we start to live with the 6.43 compiler, we’ll learn not to care about the dictionary-word-level flag when using GRAMMAR_META_FLAG:

Okay.

It would be easy, but then setting the flag when compiling an old game immediately breaks the game. I don’t think that’s desirable.

True.

Let’s leave it as it is now.

Could we have a constant for $GRAMMAR_META_FLAG like $GRAMMAR_VERSION has Grammar__Version?
It is up to the game creator to define $GRAMMAR_META_FLAG in the header of their game code, but I would need it for the default definition of certain verbs in the library.

You mean, a constant which the game can define to set that compiler option?

That adds a lot of complexity. Changing compiler options in mid-compile is a huge hassle.

That said, this particular option may be handleable in the same way as Grammar__Version. And I see the value for this case (an option which is required for a library’s Grammar.h file to work). I’ll review the code and see if it’s practical.

It seemed to me that $GRAMMAR_META_FLAG was more useful for the library developer who implements most of the verb grammar than for the game creator. But since it has to be defined in the game header, I can’t define it and use it for the library.

I don’t know if I’m clear.

Is it already predictable when the macOS-version on ‘homebrew’ will be updated to 6.43?

I don’t know who set that up.

This is actually a bit tricky! Right now, if you set the $GRAMMAR_META_FLAG option, the I6 constant GRAMMAR_META_FLAG is defined – as zero. If you don’t set the option, the I6 constant is not defined.

Thus, PunyLib has sections marked

#Ifdef GRAMMAR_META_FLAG;
!...code...
#Endif;

When I originally saw your request, I said “Oh, we’ll just use GRAMMAR_META_FLAG as its own option constant.” But that’s not going to work.

I suppose, for consistency, it should be called Grammar_Meta__Value? So you’d write

Constant Grammar_Meta__Value = 1;

…and that would make GRAMMAR_META_FLAG magically appear? Or set it to 0, and then GRAMMAR_META_FLAG would magically disappear? Hacky! But possibly the least hacky option.

The question also arises for $DICT_TRUNCATE_FLAG, which is more useful to library developers when rebuilding the display of truncated verbs than to game developers. These options could have been set by default with version 3 of the grammar.