0 votes
asked by (120 points)

Hello!

I'm still fairly new to using Twine, so excuse any fumbles I may have.

I'm making a little RPG game (I'm bored to death at work) and I've run into a small roadblock.

What I want to do:
Have a monster (or even the PC) deal a random amount of damage (per hit or per encounter).  I'd also like to have the monster give a random amount of exp (but I'm thinking whatever ends up working with the damage would also work for the exp).

What I've got:
I'm using (datamap:) to load all the monster's information in it so it's easily accessible, which looks something like this:

(set: $wolf to (datamap: "id", "wolf", "type", "animal", "health", 3, "damage", 2, "exp", 3, "loot", (a: "nothing", "wolf pelt")))

The code above has fixed damage and exp reward, how would I change it so that when the monster does damage, it can select from a range (ie. 1 - 3)?

My "combat" passage looks like this:

(set: $monster to $wolf)
(if: (either: 0, 1) is 0)[
	The (print: $monster's id) [hits] you!
	
	Your armor shields you for (print: $pc_armor's defense) point(if: $pc_armor's defense < 1)[s] of damage!

	You suffer (print: $monster's damage) damage.
	
	(set: $hp to $hp - ($monster's damage - $pc_armor's defense))[
		(if: (($monster's damage) - ($pc_armor's defense)) < 1)[
		(set: $monster's damage to 0)
		]
	]
	(if: $hp is < 1)[You suffered a fatal wound and died!
		[[Restart Your Journey?|1]]
		]
	(else:)[You have $hp/$max_hp health.
		[[(either: "Swing", "Slash")|2 - Fight]]
		]
	]
(else:)[ You hit the (print: $monster's id) for (print: $pc_weapon's damage)! 
	(set: ($monster's health) = ($monster's health) - ($pc_weapon's damage))  
  (if: ($monster's health) < 1)[
  	(set: $monster_kill to $monster_kill + 1)
	The [[(print: $monster's id) is dead|2 - Loot]]! ]  
  (else:)[    
    Its health is (print: $monster's health).
    [[(either: "Swing", "Slash")|2 - Fight]] 
    [[Return to Town|2 - Town]] ]
	]

Apologies if it looks like a hot mess and sub-optimal (code-wise).

I've tried to add in numbers to an array within the datamap, but it returns an error every time I attempt to access it (specifically with (either: (...$monster's damage))).

Any help would be much appreciated!

1 Answer

0 votes
answered by (127k points)

specifically with (either: (...$monster's damage)

If you want a random number then you should be using the (random:) macro.

How you implement the damage functionality depends on a couple of things:

1. Is the range of the damage (the minimum and maximum values) consistent for the particular monster?

eg. Does your wolf always do between 1 and 3 points (inclusive) of damage?

If the so then:

1a. If the minimum value is always 1 for all monsters, then you can do something like the following:

(set: _max to $wolf's damage)
(set: _damage to (random: 1, _max))

1b. If the minimum value can be different for each monster, then you will need to replace your single damage property with two new properties that track the minimum and maximum damage a monster can do. So assuming the two replacement properties are named damageMin and damageMax then you could do something like the following.

(set: _min to $wolf's damageMin)
(set: _max to $wolf's damageMax)
(set: _damage to (random: _min, _max))


2. If the either of the minimum or maximum values of the monster's damage range is also to be randomly determined, then that is a whole different kettle of fish. You would need to track the lower and upper ranges of both/either of the minimum and maximum values, which could result in you needing 4 properties to do so.

eg. if the same wolf one time does between 1 and 3 (inclusive) and another time between 3 and 8 (inclusive) then you would need to track that the minimum value has a range of 1-3 and the maximum value has a range of 3-8.

There is a 3rd option which is to store the 'TwineCode' required to determine the amount of damage within the damage property, I would advise against this because you would need to evaluate (execute) that 'TwineCode' each time you needed to determine the damage done, and such evaluations are expensive in both time & resources.

WARNING: All of the above code examples were written from memory and have not been tested, so while they should work as is they may contain syntax errors.

commented by (120 points)

Much appreciated!

I might be a slight (or maybe more than slight) idiot, but I haven't encountered/practiced the use of underscores yet.

1b would be what I'm looking for--

I understand that I'll have to add in "damageMin" and "damageMax" to the datamap.

I'm also understanding (hopefully correctly) that I'll be adding the new code to the combat passage in the "if monster hits" hook, however, since we're now setting "_damage" as the dealt damage instead of pulling from "$monster's damage", would I just change every iteration of "$monster's damage" to "_damage"?

I've tried doing that, which I'm guess is wildly incorrect as syntax errors are lighting up the page like the 4th of July.

Thank you for your time!

Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...