[I7] An action not quite working correctly.

I feel like I’m about to be run off the forum, asking all these silly questions, but I have another.

Finally starting what will hopefully be the first IF I actually release. I need to create a command that lets a player crouch, then another to stand up. I got it to work. Sort of. Almost. But there’s a few strange things happening, so I need a bit of help.

Here’s the code I have so far:

[code]A person is either crouching or standing. A person is usually standing.
Understand “crouch [something]” as crouching.
Understand “stand [something]” as standing.
Crouching is an action applying to one thing.
Standing is an action applying to one thing.

Check an actor crouching:
if the actor is standing:
Now the actor is crouching;
say “You are crouching.”;
stop the action;
if the actor is crouching:
Now the actor is standing;
say “You are standing.”;
stop the action;

WhatAmI is an action applying to nothing.
Understand “stance” as WhatAmI.

Carry out WhatAmI:
say “You are now[if the player is crouching] crouching.[end if][if the player is standing] standing.”
[/code]

This works well and I can confirm it’s working with the stance command.

One thing that’s slightly annoying is you need to type “crouch self” to make it work. This makes total sense to me based on how the code is written. But is there any way to modify it so as to be able to leave the ‘self’ at the end off? I tried grabbing it before it processed (with “before crouching”) and add on a ‘self’ if it was missing, but I couldn’t get it to compile that way. Using “Crouching is an action applying to the player.” produces a compiler error. I think there’s something I don’t understand here.

It is now 3:30am and I need sleep. So, I’ll check back tomorrow morning. Thanks, everyone, for any help.

(Edited: I had two problems and noticed what was wrong as soon as I posted and fixed one of them. Edited to remove stupidity. It IS 3:30am, in my defense.)

A couple of things jumped out at me when reading this code. Firstly, you have properties with names identical to the action they’re tracking. I’d do that only if everything else worked perfectly, and even then I’d hesitate.

Secondly, an action without a supplemental verb (such as “look” or “jump”) should be defined as “applying to nothing.”

Thirdly, the Check rules are primarily intended to stop nonsensical things from happening and to redirect an action into something more useful. They’re not meant to carry out the actual work of the action (that’s what the Carry Out rules are for), nor to print the result (which is the job of the Report rules).

Given that, here’s how I’d do it.

[code]A person is either crouched or upright. A person is usually upright.

Standing is an action applying to nothing.
Crouching is an action applying to nothing.

Understand the command “stand” as something new.
Understand “stand” as standing.
Understand “crouch” as crouching.

Check standing when the actor is upright: say “You’re already standing.” instead.
Check crouching when the actor is crouched: say “You’re already crouched.” instead.

Carry out standing: now the actor is upright.
Carry out crouching: now the actor is crouched.

Report standing: say “You get back to your feet.”
Report crouching: say “You hunker down.”

The Sorcerer’s Abode is a room. Tim is a man in the Sorcerer’s Abode. [Or so some call him.] The player is Tim.
The description of Tim is “You’re [if upright]standing[otherwise]crouching[end if].”

Test me with “stand/crouch/x me/stand/x me”.[/code]

You’re posting full code and a description of what’s going wrong, you’re mentioning things you tried, and you’re doing it in complete sentences. For bonus credit, you’re not insulting anybody or starting pointless arguments. Your status here is A-OK. :slight_smile:

I like to think that the way the developer part of the forum works is that we all answer questions just up to our own abilities. People like me answer the basic syntax-error stuff, people with a bit more experience answer about the intricacies of things like tables and indexed text, and then if there’s a really esoteric question, an Inform maintainer like emshort or zarf steps in. Without the “silly” questions, the question-economy collapses!

Anyway, I frequently learn things by reading the answers to people’s questions even when they thought they were silly, and it’s not like the forums here are that high-volume. So, no worries.

I for one answer questions beyond my abilities. But yeah, insofar as I know anything about coding in I7 it comes from reading answers on these forums and trying to work out answers to questions people ask on these forums. (And working through the examples in the documentation.) Questions are awesome.

That’s what I tried at first, but it wouldn’t work that way. Not sure what I was doing wrong. I added the “applying to one thing” pretty much out of frustration and, to my surprise, it started working. I figured it was probably wrong, but I was just happy it started working.

Maybe I misread, but in a previous thread I made about actions from a few days ago, someone told me the Carry Out should always be blank and seemed to suggest I should be using Check instead of Carry out. I’ll have to go back and re-read. Might be a mistake on my part, or a special case that I mistook as general advice or something.

Anyway, thanks for the fixed up code!

I think the suggestion was that they should never print anything; in this case, the actual change in the world model happens in the Carry Out phase, but the text gets printed in the Report phase.

Probably you didn’t have the line Understand "stand" as something new.

You need that since the Standard Rules already understand “stand” or “stand up” as exiting and “stand on [something]” as entering.

When you tell Inform to understand “stand” as something new, it forgets these earlier definitions, and you are suddenly free to have it understand “stand” as standing. (Note that it will now have forgotten the commands “stand up” and “stand on [something]” as well as mere “stand”; but if you want them you can simply add them anew. Only make sure you do so AFTER the line about understanding “stand” as something new, or that line will eat the preceding understand statements about “stand” in your source text as well as those in the Standard Rules.)

I have another question related to crouching. Rather than start a new topic, I figured I’d add it here. This is more of a “I can’t find the syntax I need” problem than me not knowing what to do.

I added two lines to determine if it’s possible to crouch behind something and hide. It looks like this:

An object is either hideable or nothideable. An object is usually nothideable. A person is either hidden or visible. A person is usually visible.

It sounds awful (“nothideable”?), but I couldn’t think of anything better.

I’m trying to figure out the correct syntax to carry out something like this:

Carry out crouching: if the room the actor is in contains a hideable object: say "You are now hiding behind [object]." now the actor is hidden. otherwise now the actor is crouched.

Standing would just be modified to remove hidden, and I’m pretty sure I can handle that on my own. My problem is, I cannot find any way to scan the current room for objects with the hideable flag. I suppose I could write a “instead of crouching:” for every room with a hideable object, but that seems like a terrible option. Also, I’m making an assumption if you’re hidden, you’re crouched which is why I didn’t explicitly set that in the first If clause.

I was also thinking I could just make a separate “hide” command where you have to specify what object you want to hide behind (thus making scanning the room irrelevant) but I think I’d prefer it to be automatic for my game. I think it’d be better to not have to guess. eg, to not have to have this happen in a game:

Someone is coming! You need to hide!

hide behind desk
You can’t hide unless you’re crouching.
crouch
You are now crouching.
hide behind desk
You can’t hide there.
hide behind box
You can’t hide there.
quit
Are you sure? Y

So, is there a way to scan a room? I’ve spent some time searching both the documentation and a syntax guide I found online and haven’t come up with anything.

Thanks again!

I think instead of “the room the actor is in” you want “the location of the actor”; one thing to note is that if you are on a supporter or in a container, you are not considered to be “in” the room. And your rule is written only to cover the player crouching – you don’t want the message “You are now hiding behind” to appear when someone else hides. Assuming no one else will crouch, that’s fine, but then you don’t need to mention the actor at all; “the location” is the room that encloses the player.

Also, the containment relation only applies to, well, containers. See 13.3. Rooms don’t contain anything. So you don’t want “contains.” What you actually want is “encloses.” Both “the location” and “encloses” are documented in 3.25.

So you can start:

If the location encloses a hideable object:

But your [object] token isn’t going to work. You want it to back-refer to the hideable object, but Inform don’t do that – and in fact there’s no guarantee that there’s only one hideable object anyway! So for that part you need something like this:

Carry out crouching: if the location encloses a hideable object: say "You are now hiding behind [a random hideable object enclosed by the location]."; now the actor is hidden; otherwise: now the actor is crouched.

Inform often forces you to say “A random blah blah blah” when, like the Highlander, there can only be one; you’ll see formulas like “A random person incorporating the nose” when no nose is part of more than one person. Because Inform doesn’t know that about noses. But in this case it’s not just Inform’s quirkery.

By the way, you didn’t seem to be modeling which object the player was crouching behind. I’m assuming you don’t need to model that, and that e.g. hideable objects can’t be destroyed and every hideable object is fixed in place (it would be embarrassing to have the player hide behind something she was carrying). There’s also some possible combination about enterable supporters and containers; if the player can crouch behind the desk while standing on the bed, that’s bad. You could check on that by adding something that checks if the player is not in the location and moves her to the location (remember, if she’s on a supporter, she’s not in the location). But that’s another complication. You might want to test what I wrote and see if it compiles – I’m not sure I didn’t overlook something. (NB I also cleaned up the punctuation at the end of the lines.)

UPDATE: Also, Inform 7 already uses “visible” to mean something; I’m not sure if it’d lead to trouble, but you might want to change that to e.g. “exposed.”

Yes, it worked fine. Thanks!

I did have to modify some of my code a bit (specifically the Check crouching: and Check upright: since the commands do more than set crouching and upright now.) but it was all fine. I did it with no problems at all on my own. (For once. hah.)

But thanks again for helping.

You don’t necessarily have to define the opposite of an adjective. The opposite can then be referred to as “not (adjective)”. It’s also better to refer to game world objects as “things” instead of “objects” unless you have a reason to use the object class (all things are objects, but not all objects are things).

A thing can be hideable. A thing is usually not hideable.

Another way to do this is to name the object:

Carry out crouching: if the location encloses a hideable object (called the hideout): say "You are now hiding behind [the hideout].";
It doesn’t really matter in this case but if there are more than one hideable objects in the location the conditional might pick a different object than the say phrase. In a more complex rule that might cause problems.

I’d be inclined to write these as

A thing can be concealing. A thing is usually not concealing. A person is either concealed or exposed. A person is usually exposed.

assuming that you want to have an explicit opposite for ‘concealed’. If you don’t care, I’d go with

A person can be concealed. A person is usually not concealed. .