Adding a Scratch Message to a Room

Hi there,

I am working on my first IF using Inform 7, a conversion of an old text adventure I programmed ages ago in Pascal. I’ve got pretty much everything working except for “scratch message”. I wanted people to be able to solve the mazes more easily by being able to scratch a message on the ground - if they have a gauntlet. And obviously if there is a message already scratched on the ground, then it will be displayed when the location is described. (Ideally, if there is already a message on the ground, you would not be able to add another one. But I was going to wait until I had the rest of it working first…)

This was what I tried, but it didn’t work. Any ideas how to do this?

[code]A room has some text called the message.
For printing a locale paragraph about a room
(this is the mention messages if they are present rule):
if the room has a message
begin;
say “Someone has scratched ‘[message of the location]’ on the floor here.”
continue the activity;
end if.

After reading a command:
if player’s command matches the regular expression “scratch .*”
begin;
if the player carries the gauntlet
begin;
let T be indexed text;
let T be the player’s command;
replace the regular expression "scratch " in T with “”;
say “You scratch ‘[T]’ on the floor.[paragraph break]”;
now the message of the location is [T];
otherwise;
say “Your fingernails have recently been chewed, so you make no mark on the floor.[paragraph break]”;
end if;
stop the action;
end if.[/code]

Sincerely,
Ben.

It needed to be an indexed text, you were missing a semi-colon, and you’d bracketed something what didn’t want bracketing. This should do the trick, and prevent writing messages when you’ve already written messages:

[code]A room has some indexed text called the message.

Before printing the locale description of a room
(this is the mention messages if they are present rule):
if the message of the location is not “”
begin;
say “Someone has scratched ‘[message of the location]’ on the floor here.”;
continue the activity;
end if.

After reading a command:
if player’s command matches the regular expression “scratch .*”
begin;
if the player wears the gauntlet
begin;
if the message of the location is not “”, say “You’ve already scratched a message here.” instead;
let T be indexed text;
let T be the player’s command;
replace the regular expression "scratch " in T with “”;
say “You scratch ‘[T]’ on the floor.[paragraph break]”;
now the message of the location is T;
otherwise;
say “Your fingernails have recently been chewed, so you make no mark on the floor.[paragraph break]”;
end if;
stop the action;
end if.[/code]

Please don’t parse a command manually unless you absolutely have to, and in this case you really don’t need to do so. A regular action will work just fine.

[code]A room has some indexed text called the message.

Scratching is an action applying to one topic.
Understand “scratch [text]” as scratching.

Check scratching when the player is not carrying the gauntlet:
say “Your fingernails have recently been chewed, so you make no mark on the floor.” instead.

Carry out scratching:
now the message of the location is topic understood.

Report scratching:
say “You scratch ‘[topic understood]’ on the floor.”[/code]

Don’t circumvent the parser unless you have to. Creating new actions might seem difficult, but it is much more robust than trying to achieve an effect by intercepting a command (as you have with your after reading a command rule). You do need to use indexed text if you want the player to be able to type anything. Try this:

[code]A room has some indexed text called the message.

Before printing the locale description of a room
(this is the mention messages if they are present rule):
if the message of the location is not “”
begin;
say “Someone has scratched ‘[message of the location]’ on the floor here.”;
continue the activity;
end if.

Scratching is an action applying to one topic and requiring light.
Understand “scratch [text]” as scratching.

Check scratching (this is the can’t add new messages rule):
unless the message of the location is empty:
say “There’s already a message here. It reads: ‘[message of the location]’.” instead.

Carry out scratching (this is the default scratching rule):
let T be some indexed text;
now T is the topic understood;
now the message of the location is T.

Report scratching (this is the default report scratching rule):
say “You scratch ‘[message of the location]’ into the floor.”.

The Lab is a room. “This is the lab.”

test me with “scratch blah / l / scratch blah”.[/code]
Adding the bit about the gauntlet is as simple as adding another check rule.

Edited to add: Juhana, does that count as a tie? :slight_smile:

Great minds etc :slight_smile:

You could also try this.

[code]A room has some indexed text called the message.

The Testing Room is a Room. The description of the testing room is “This is the description of the room[if the message of the location is not empty].[paragraph break]Someone has scratched ‘[message of the testing room]’ on the floor here[end if].”.

The gauntlet is in the testing room.

Scratching is an action applying to one topic. Understand “Scratch [text]” as scratching.

Check scratching:
if the player is not carrying the gauntlet, say “Your fingernails have recently been chewed, so you make no mark on the floor.” instead.

Carry out scratching:
now the message of the location is topic understood.

Report scratching:
say “You scratch ‘[topic understood]’ on the floor.”.

Test me with “scratch something / take gauntlet / scratch something / l”.[/code]

Which is simpler and easier to understand than adding a printing the locale description of a room rule, especially for those new to inform 7.

Wow, thanks to everyone who replied! And so quickly! I now have it working beautifully, essentially following Skinny Mike’s code with an additional check for the gauntlet.

Thanks so much!

One additional question though. With the additional code (and I was finding this even before with my own very poor code) my project will no longer compile as a z5 file. It has to be z8. And yet my project is hardly very large. The source text is just over 10,000 words, there are 127 rooms and 44 things. It’s not really a problem, but any idea why that happens?

Sincerely,
Ben.

It’s normal. The standard library takes almost the entire space allowed for z5, and frankly I’m surprised that you managed to fit 10,000 words to it. The z8 limits are somewhere around 50,000 words.

Good to know!

I don’t think counting words is a useful metric; a few assemblies can create a massive number of things and rooms, but requiring a very small source file, for instance.

Edge cases are a different thing, but I’m pretty confident that the top of the bell curve is somewhere around 50k words. This is assuming that you’re not purposely doing something that would consume a lot of resources.