Trouble creating simple attack mechanics

I’m currently trying to make a VERY simple attack mechanic inspired by David Ratliffs “Armed”.
Although the code seems to compile fine i am getting this error:

*** Run-time problem P10: Since yourself is not allowed the property “damage dealt”, it is against the rules to try to use it.

Violence isn’t the answer to this one.

this is triggered by “me” trying to attack “me”, of course i would make a rule against that, but for testing purposes im leaving that out for now. I get the same error when i try to attack “trolls” or other “persons”.

My modified code of Ratliff’s “Armed” is here:

[code]A person has a number called melee. The melee of a person is usually 5.

Understand “Attack [something]” as attacking it. The attacking it action has a number called the damage dealt.

Setting action variables for an actor attacking something (called target):
if the target is a person begin;
now the damage dealt is a random number between 10 and the melee of the actor;
end if.

Carry out an actor attacking something (called the target):
if the target is a person begin;
decrease the present health of the target by the damage dealt;
if the target is not the player begin;
if the target is docile, now the target is hostile;
end if;
end if.

Report attacking something (called the target):
if the target is a person begin;
if the target is dead begin;
say “With some struggle you finally end the life of [the target].” instead;
end if;
say “You attack [The target]([The target][apostrophe]s health: [present health of the target])[line break]”;
end if.

After someone attacking something (called the target):
if the target is the player begin;
if the player is dead begin;
say “[The person asked] attacks you, and you drop to the ground, dead.”;
end the story saying “[We] [have] died.”;
end if;
end if;
continue the action.

Every turn (this is the fighting back rule):
repeat with madman running through people begin;
if madman is hostile begin;
if madman can see the player begin;
try madman attacking the player;
end if;
end if;
if madman is dead, now madman is docile;
end repeat.
[/code]

*edit: The forum post seems to ignore Tabs, so i dont really know how to show that :confused:

Paste the code into the forum edit box, then select it and click the Code button at the top of the edit area.

Okay, seems to be showing the code correctly now. Thanks! :smiley:

I don’t immediately see what is wrong, but what happens when you change:

The attacking it action has a number called the damage dealt.

into:

Damage dealt is a number that varies.

Then remove the “Setting action variables” rule entirely, and add the line

now the damage dealt is a random number between 10 and the melee of the actor;

to the carry out rule, after the first -if statement.

Perhaps this has nothing to do with your error, but it seems to me unnecessarily complicated to use action variables here when you can just use a single global variable instead, and maybe it is tripping you up somewhere.

tried to do as you said;

[code]Understand “Attack [something]” as attacking it. The attacking it action has a number called the damage dealt that varies.

[Setting action variables for an actor attacking something (called target):
if the target is a person begin;
now the damage dealt is a random number between 10 and the melee of the actor;
end if.]

Carry out an actor attacking something (called the target):
if the target is a person begin;
now the damage dealt is a random number between 10 and the melee of the actor;
decrease the present health of the target by the damage dealt;
if the target is not the player begin;
if the target is docile, now the target is hostile;
end if;
end if.

Report attacking something (called the target):
if the target is a person begin;
if the target is dead begin;
say “With some struggle you finally end the life of [the target].” instead;
end if;
say “You attack [The target]([The target][apostrophe]s health: [present health of the target])[line break]”;
end if.

After someone attacking something (called the target):
if the target is the player begin;
if the player is dead begin;
say “[The person asked] attacks you, and you drop to the ground, dead.”;
end the story saying “[We] [have] died.”;
end if;
end if;
continue the action.

Every turn (this is the fighting back rule):
repeat with madman running through people begin;
if madman is hostile begin;
if madman can see the player begin;
try madman attacking the player;
end if;
end if;
if madman is dead, now madman is docile;
end repeat.[/code]

I got an error if i tried to understand attacking as something else without specifying at something else (action as).
But this code gave me a new error, which might be the root of the issue, since i really dont understand why it doesn’t understand it.

[code]Problem. You wrote ‘now the damage dealt is a random number between 10 and the melee of the actor’ : but this is a phrase which I don’t recognise, possibly because it is one you meant to define but never got round to, or because the wording is wrong (see the Phrasebook section of the Index to check). Alternatively, it may be that the text immediately previous to this was a definition whose ending, normally a full stop, is missing?

I was trying to match this phrase:

now (damage dealt is a random number between 10 and the melee of the actor - a phrase)

But I didn’t recognise ‘damage dealt is a random number between 10 and the melee of the actor’.
[/code]

Have you defined melee? Could you post that part of the code?

Your mileage might vary on this one, but I modified the code a bit. I couldn’t get the “carry out a person attacking” rule to work – got the same “Violence is not the answer” standard message each time. This code works, but it’s heavily modified from your source. You could probably use this as a base to get the results you want, though. Also, I added some junk at the beginning to get this to compile, and I’m including that. I also commented out the attack rule at the beginning.

I also added a zombie to fight. That is, Rob Zombie. Haven’t been able to beat him, though. Tied once – got him when he got me. So, 1 draw. I didn’t add a melee to either actor, so changing those variables will effect the outcomes.

test room is a room. the player is in test room.

a person can be hostile. a person can be dead. a person can be docile.
a person has a number called present health.

the player is a person. The present health of the player is 100.

Rob Zombie is a person. Rob Zombie is in test room. The present health of Rob Zombie is 100. Rob Zombie is docile. 

A person has a number called melee. The melee of a person is usually 5.

[Understand "Attack [something]" as attacking it. The attacking it action has a number called the damage dealt.]

[Setting action variables for an actor attacking something (called target):
if the target is a person begin;
now the damage dealt is a random number between 10 and the melee of the actor;
end if.]

[Attack function. Used "Instead" to go around standard rules.]
Instead of attacking something:
	Let target be the noun;
	Let damage be 0;
	Now damage is a random number between 10 and the melee of the actor;
	if the target is a person:
		decrease the present health of the target by damage;
		say "The [present health] of [target] is decreased by [damage]!";
		if the target is not the player:
			if the target is docile, now the target is hostile;

[Enemy attack rule. I would add something to "every turn" to make it fire only when needed.]
Every turn:
	Let damage be 0;
	repeat with madman running through people:
		if madman is hostile:
			if madman can see the player:
				Now damage is a random number between 10 and the melee of the actor;
				decrease the present health of the player by damage;
				say "Your [present health of the player] decreased by [damage] as [madman] attacks!";

[Change status with present health. Used <= 0 in case damage went below 0, which it usually will.]
Every turn:
	If the present health of the player <= 0:
		say "You died.";
		end the story;
	Repeat with p running through hostile persons:
		If the present health of p <= 0:
			say "[p] died.";
			Now p is dead;

Your problem the second time was that you were still defining damage dealt as an action variable. To do a global, you say “damage dealt is a number that varies” without anything else.

But in this case I would say an action variable is the better choice. Imagine something like this.

Before attacking someone in the presence of Alonzo the Swift when the noun is not Alonzo (this is the attack of opportunity rule): say "As you step forward to attack, Alonzo slashes at you again!" try Alonzo attacking the player.

Now you have another attacking action starting before the first one finishes. If you use an action variable, the damage for each attack will be kept separate. But if you use a single global for damage, the damage from Alonzo’s attack overwrites the player’s, which could be bad (perhaps Alonzo is very fast but doesn’t do much damage, while the player is a mighty glacier).

To debug your initial problem, try turning on rules tracing (just type “rules”) before trying to attack yourself. That’ll show you which rule caused the problem, which will help narrow it down.

@craftian
your version seems to work just fine, which only makes me more confused as to why mine doesn’t.

@Draconis
turned on rules, all rules seem to apply correctly, here it is;

[code][Rule “redirect to GEP line input rule” applies.]
[Rule “ordinary checking for content rule” applies.]
[Rule “declare everything initially unmentioned rule” applies.]
[Rule “Setting action variables for an actor attacking something ( called target )” applies.]

*** Run-time problem P10: Since yourself is not allowed the property “damage dealt”, it is against the rules to try to use it.

[Rule “announce items from multiple object lists rule” applies.]
[Rule “set pronouns from items from multiple object lists rule” applies.]
[Rule “before stage rule” applies.]
[Rule “respect the dead rule” applies.]
[Rule “instead stage rule” applies.]
[Rule “investigate player’s awareness before action rule” applies.]
[Rule “player aware of his own actions rule” applies.]
[Rule “check stage rule” applies.]
[Rule “block attacking rule” applies.]
Violence isn’t the answer to this one.

[Rule “A first turn sequence rule” applies.]
[Rule “every turn stage rule” applies.]
[Rule “Every turn” applies.]
[Rule “fighting back rule” applies.]
[Rule “A last turn sequence rule” applies.]
[Rule “notify score changes rule” applies.]

[/code]

how can it say that something is against the rules, but then say that it is correctly applied?

“applies” just means that the rule’s conditions are satisfied and therefore it will execute.

The problem with your orginal code is the line

The attacking it action has a number called the damage dealt.

The formal name of the action is “the attacking action”. The compiler didn’t recognize “attacking it”, and therefore created a spurious offstage object called “the attacking it action”.

Yes, it’s somewhat inconsistent that you have to refer to “the unlocking it with action” but then “the attacking action” (with no “it”.)

You can also leave out the line “Understand “Attack [something]” as attacking it.” The standard rules already define that verb. (The compiler correctly recognized the action there, but the result was just a double definition of the “ATTACK” verb.)

Write instead

The attacking action has a number called the damage dealt.

when i modify it the way you suggested, i get the standard response of “Violence is not the answer”. Even when i dont leave out the “understand “attack [something]” as attacking”.

That’s because of the “block attacking rule”, which by default prevents any attempts to attack something at the Check stage. You can remove it like this.

The block attacking rule is not listed in any rulebook.

I re-wrote your three main functions in a syntax I understand. I ran into the same problems you were having, including the “violence is not the answer” standard rule, with the original code. For some reason, this:

Carry out an actor attacking something (called the target):

is not overruling the standard rules, where:

Instead of attacking something:

does. I’m not sure why. Maybe Inform isn’t catching that the player is the actor in the rule. Using “instead” always seem to work to overrule the standard rules, so I use it – instead – of wrangling with the standard rules when I want them to be good and be quiet.

Also, this:

*** Run-time problem P10: Since yourself is not allowed the property “damage dealt”, it is against the rules to try to use it.

I changed the “damage dealt” global variable to “damage”, instantiated it each time in the attack function as a temporary variable (since it’s not required as a global variable, as it’s used and thrown away every time) and that worked. It’s an easier variable to write, and compiled.

The rule that prints the “violence is not the answer” response in the standard rules is a check rule. The order of action rulebooks is instead -> check -> carry out, so the check rule stops the action before the carry out rule is reached, and similarly the instead rule stops the action before the check rule is reached.

Okay guys! it’s finally working when i stated that the block attack rule should be ignored.

Thank you all very much, this really helped me understand the language alot better! :smiley: