Using Inform ATTACK

I have been reading through the Attack module and I can’t work out how to use it at all from reading the manual (which hasn’t been very helpful and the forum search isn’t working for some reason). The only thing I have found out so far is a few specific commands and a couple of examples that don’t seem to be complete as far as I can see.

Could someone to explain how ATTACK works or link me to a full example I can play with? (By the way, does anyone know if it is it possible to knock out someone or defeat them without killing them? :smiley:)

Would this post from a recent thread here be anything like what you want?

That’s defiantly going to be helpful for events and stuff like that, but I was thinking along the lines of specifying that certain weapons (say, fists) can’t outright kill someone in combat and instead reduce another stat called stamina. When stamina is at zero the player or ememy is unconscious instead of dead and will wake up under certain circumstances. Or maybe the opponent can be disarmed and lose that way? Since I’m writing something that is mostly a crime thriller and there aren’t really any random encounters it would help a lot to be able to take people ‘down town’ for interrogation rather than kill them in a fight.

For a crime thriller, I’d personally be inclined to go with a fairly simple combat system, much like in the example I linked to, where you just announce what you want to do (e.g. “shoot robber” or “knock out robber” or “grab robber”, or possibly “point gun at robber” / “threaten robber” or even “handcuff robber”) and the attempt either succeeds or fails (or gives you a message saying that you can’t/won’t even try). Most of the work (besides plotting the actual fight scenes, of course) will be in anticipanting the various commands a player might try and responding to them appropriately.

If you want to, you can still have multi-turn combat in such a system simply by making the first attack fail and giving the player a chance to try again. (“You aim your revolver at the outlaw and fire, but your shot misses as he dives for cover behind a sack of turnips. Maybe you should also find some cover to hide behind.”) However, I’d only suggest doing this in a scripted manner, and only if the pacing of the story demands it.

If you do want a D&D style hit/stamina point based combat system, the Inform Recipe Book has some basic examples (Lanista 1 & 2) in section 7.5: Combat and Death. It shouldn’t be too hard to modify the Lanista 2 example to mark some weapons and/or attacks as nonlethal. You’d probably want to make the “damage type” an action variable, so that your action processing rules can modify it appropriately.

I am very surprised about this. The manual for Inform ATTACK 3 is by the far the most comprehensive piece of documentation I have ever written. Chapter 3 consists of nothing but a single, complete, worked example – if you add all that code together, you’ll have a working game. So I don’t really see why the manual is not helpful to you?

It is very comprehensive and it does spend a long time explaining stuff, it just doesn’t do so in a way that I understand. I copied the attack stuff but it just stops working as soon as I add the first flavour rule. :confused: I tried various tab spacing but it still doesn’t work.

A fatal flavour rule (this is the fatal goblin rule): if the global defender is the goblin: say "[if the global attacker weapon is a mace]With a sweeping blow, [possessive of the global attacker] mace smashes into the goblin's head[otherwise][The global attacker] land[s] a furious blow on the goblin's head [end if], ending its beastly existence. Wow! A kill! You feel powerful.[run paragraph on]"; rule succeeds.

After a colon, always indent another tab.
After a semicolon, either use as many tabs as before or use less, depending on under what conditions you want the phrase to fire.

A fatal flavour rule (this is the fatal goblin rule): if the global defender is the goblin: say "[if the global attacker weapon is a mace]With a sweeping blow, [possessive of the global attacker] mace smashes into the goblin's head[otherwise][The global attacker] land[s] a furious blow on the goblin's head [end if], ending its beastly existence. Wow! A kill! You feel powerful.[run paragraph on]"; rule succeeds.In this case, both the say phrase and the ‘rule succeeds’ fire only if it’s true that the global defender is the goblin.

A fatal flavour rule (this is the fatal goblin rule): if the global defender is the goblin: say "[if the global attacker weapon is a mace]With a sweeping blow, [possessive of the global attacker] mace smashes into the goblin's head[otherwise][The global attacker] land[s] a furious blow on the goblin's head [end if], ending its beastly existence. Wow! A kill! You feel powerful.[run paragraph on]"; rule succeeds.In this case, the say phrase fires only if it’s true that the global defender is the goblin, but the ‘rule succeeds’ will fire whether or not that’s true.

Example:

A rule: [rule preamble — 0 tabs] do this; [things that should always happen during this rule — 1 tab] do that; [ditto] if this or that: [things that should always be tested during the rule — 1 tab] do this; [thing that should only happen if a test is met — 1 MORE tab than the test itself] otherwise: [if the test above fails, the game jumps to the next 'otherwise' line that has exactly as many tabs as the test itself] do that; [this should only happen if things are 'otherwise', so it needs one tab MORE than the 'otherwise' line] if one thing: [this has only 1 tab, therefore it is always tested] do this thing; if another thing: [if 'another thing' should be tested whenever 'one thing' is true but only then, it needs 1 tab MORE than 'one thing'] do this other thing. [this should only happen if 'another thing' is true, so it needs 1 tab MORE than 'another thing']
In general, the game always reads lines with 1 tab; lines with 2 tabs ‘belongs to’ and ‘are guided by’ (as it were) the previous line with 1 tab; lines with 3 tabs ‘belongs to’ and ‘are guided by’ the previous line with 2 tabs, and so on.

Is this your first Inform 7 project? If so, ATTACK may not be a great tool for you – it is difficult and sophisticated, and you might want to learn Inform 7 without having to learn ATTACK at the same time. (Though of course you are definitely welcome to try!)

It might not be a great thing to start with, but it is just a matter of memorising the rules, like the one above (thanks!). I may come back after I have implemented some more stuff. I kinda have a pile of questions related to the Simple Chat module that have been keeping me from getting further.

0k, sorry about earlier, I’m finding attack a lot easier now but I’m having trouble finding an easy way to add up different statistics and points that the player gets (since I keep score on several diferent things, as well as using the in-built score variable). What I really want to do at the moment is basically add X to Y and print the total as a number in conversation. Should be easy enough but I can’t find the right way to do it. Can anyone help?

let N be 4 + 5;
say “Foo [N in words].”;

Cool, thanks.

By the way, I’m having trouble with this part of the Attack example code. I’m not sure how to indent this part or what it should look like:

[code]Table of Fancy Status
left central right
“[bold type][location of the player][roman type]” “”
“Score: [score]/100”
“You [harm status], and armed with [a random readied weapon enclosed by the player].” “” “”
Rule for constructing the status line:
fill status bar with Table of Fancy Status;
rule succeeds.
To say harm status:
if the numbers boolean is false:
say "are ";
let n be 10 times the health of the player;
now n is n divided by the permanent health of the player;
if n is:
– 10: say “unharmed”;
– 9: say “scratched”;
– 8: say “lightly wounded”;
– 7: say “wounded”;
– 6: say “wounded”;
– 5: say “severely wounded”;
– 4: say “severely wounded”;
– 3: say “[bold type]bleeding copiously[roman type]”;
– 2: say “[bold type]losing limbs[roman type]”;
– otherwise: say “[bold type]dying[roman type]”;
otherwise:
say “are at [health of the player] of [permanent health of the player] health”.

[/code]

Wild guess: could it just be that there needs to be a line of blank space underneath the table? (That is, just before the line that starts with “Rule for constructing…”)

If that’s not the problem, posting the error message you get might help.

“-- otherwise” needs to be at the same level as the other “–” cases.

It’s still doing it when it looks like this:

Table of Fancy Status left central right "[bold type][location of the player][roman type]" "" "Score: [score]" "You [harm status], and armed with [a random readied weapon enclosed by the player]." "" "" Rule for constructing the status line: fill status bar with Table of Fancy Status; rule succeeds. To say harm status: if the numbers boolean is false: say "are "; let n be 10 times the health of the player; now n is n divided by the permanent health of the player; if n is: -- 10: say "unharmed"; -- 9: say "scratched"; -- 8: say "lightly wounded"; -- 7: say "wounded"; -- 6: say "wounded"; -- 5: say "severely wounded"; -- 4: say "severely wounded"; -- 3: say "[bold type]bleeding copiously[roman type]"; -- 2: say "[bold type]losing limbs[roman type]"; -- otherwise: say "[bold type]dying[roman type]"; otherwise: say "are at [health of the player] of [permanent health of the player] health".

Like this it says:

With a space before the rule bit it says:

By the way, I’m having problems with tweaks to rules for health potions, can you tell me what I’m doing wrong here as it says I’m using both kinds of scripting:

A minor health potion is a kind of thing. Instead of drinking a minor health potion: If the health of the player equal to the permanent health of the player: say, "You are at full health already.". otherwise: heal the player for 6 health; say "You drink the health potion, [if the healed amount is 0]but you were already at full health[otherwise if the health of the player is less than the permanent health of the player]partially restoring your health[otherwise]restoring your health[end if]."; if the combat state of the player is at-React: now the player is adrinking.

It’s possible that you use normal spaces and line breaks between the table entries where you really need tab stops:

Table of Fancy Status left [tab]central [tab]right "[bold type][location of the player][roman type]" [tab]"" [tab]"Score: [score]" "You [harm status], and armed with [a random readied weapon enclosed by the player]." [tab]"" [tab]""Above I have marked the blank spaces that should be tab characters. You shouldn’t actually write ‘[tab]’ in your code, of course, just use the tab key to make a blank space between the entries rather than the space bar.

The error message is not very helpful in this case. The problem is that you use a full stop instead of a semicolon before ‘otherwise:’. And there are a few other syntactical misses – Inform generally wants mere ‘is’ rather than ‘is equal to’, and it won’t understand the comma after ‘say’. Try this:

Instead of drinking a minor health potion: If the health of the player is[!] [equal to] the permanent health of the player: say[,] "You are at full health already."[.];[!] otherwise: heal the player for 6 health; say "You drink the health potion, [if the healed amount is 0]but you were already at full health[otherwise if the health of the player is less than the permanent health of the player]partially restoring your health[otherwise]restoring your health[end if]."; if the combat state of the player is at-React: now the player is adrinking.

Where did you copy that code from? If you copied it from the PDF file, the quotation marks might be wrong – try substituting a new " sign everywhere where there are quotation marks in the table.

I copied it from the PDF originally. It seems to have lined all the quote marks now, but it tells me that it thinks it should be a ‘definition of a phrase’. It also says “but the punctuation here ‘:’ makes me think this should be a definition of a phrase and it doesn’t begin as it should, with either” even though there isn’t a ‘:’ on the first line

Table of Fancy Status left central right "[bold type][location of the player][roman type]" "" "Score: [score]" "You [harm status], and armed with [a random readied weapon enclosed by the player]." "" "" Rule for constructing the status line: fill status bar with Table of Fancy Status; rule succeeds. To say harm status: if the numbers boolean is false: say "are "; let n be 10 times the health of the player; now n is n divided by the permanent health of the player; if n is: -- 10: say "unharmed"; -- 9: say "scratched"; -- 8: say "lightly wounded"; -- 7: say "wounded"; -- 6: say "wounded"; -- 5: say "severely wounded"; -- 4: say "severely wounded"; -- 3: say "[bold type]bleeding copiously[roman type]"; -- 2: say "[bold type]losing limbs[roman type]"; -- otherwise: say "[bold type]dying[roman type]"; otherwise: say "are at [health of the player] of [permanent health of the player] health".

I also tried your alterations to the script for the health potion but unfortunately it is still saying that the if at-react line is awry and I am a bit stuck. When I copied it over I deleted all the tab spacing and redid it.

Instead of drinking a minor health potion: If the health of the player is the permanent health of the player: say, "You are at full health already.".; otherwise: heal the player for 6 health; say, "You drink the health potion, [if the healed amount is 0]but you were already at full health[otherwise if the health of the player is less than the permanent health of the player]partially restoring your health[otherwise]restoring your health[end if]."; if the combat state of the player is at-React: now the player is adrinking.

It’s probably because you don’t have enough space between the table and the rules. You should have at least one empty space after the table (and for your own sanity, between rules as well).

You have two spaces before the last “say”, there’s an extra full stop on line 3 and you shouldn’t have commas after the says.