You might note that my to do list is progressing very slowly - at least the public face of that list (Unangband development, blogging) has virtually stalled. I've got two very good reasons, plus I'm back working full time with a long commute.
I've mentioned previously that my OS X laptop was running Tiger. No longer, I've upgraded to Leopard - anything newer felt a little risky.
Given the amount of software I now have access to, it feels like a new machine. So I've taken advantage of being able to run Steam natively, and started playing some games in the comfort of the living room.
As a result: I've beaten Mom's Heart in the Binding of Isaac. The Book of Shadows and Virus together feels like cheating - even more so when I had every stat at maximum. Isaac, however, is one of those games which you need at least one ability which fulfils that requirement in order to get anywhere.
Unfortunately, you won't be able to follow my progress, as the OS X version of Isaac doesn't support achievements. This is probably a good thing, as I
Next on the list is fixing a bug which has made the current Angband competition featuring Unangband a lot less interesting than it should be.
Sunday, 12 February 2012
To do list
Posted by
Andrew Doull
at
21:33
1 comments
Labels: development updates, links, the binding of isaac
Tuesday, 27 December 2011
A small example of why programmers can't do UI design
The quiver is a user interface feature in later versions of Angband which allows you to carry multiple stacks of ammunition more easily, without having to dedicate one inventory slot to each different type of ammunition. As a part of this, it automatically assigns a number key to each stack, so you can select the first stack by pressing 0, the second stack by pressing 1 and so on...
Wait a sec.
The first stack by pressing 0?
Well, as it turns out, the quiver was designed by programmers, not UI designers. The problem here is that the character encoding used is ASCII, which assigns character codes for the numeric keys from 0 to 9, not from 1 to 0. So the elegant programming solution is to figure out the character code by subtracting the value for 0 from the actual number typed in to determine which number is used. This 'elegant' solution puts 0 first. Not only that, but for various reasons (e.g. array indexes) programmers are used to counting from 0.
This is despite the fact that every single person involved in the design of the quiver, the various reimplementations across multiple variants, and pretty much every single person who has played using the quiver has the number keys running across the top of their keyboard in the order 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.
Posted by
Andrew Doull
at
07:18
4
comments
Labels: development updates, user interface
Monday, 26 December 2011
Holidays
If you're going to release a new version of your game, don't do it just before you go on holiday.
I've seen at least 2 roguelikes fall into this trap this year...
(Oh, and Merry Xmas).
Posted by
Andrew Doull
at
20:02
3
comments
Labels: development updates
Friday, 23 December 2011
Help wanted (svn2git)
berlios.de is shutting down at the end of the year, which means I need to migrate to alternative hosting like github.
Unfortunately, I don't have a computer with an OS capable of running git* (I've got Vista, and OSX 10.4), which means I can't run svn2git to convert the repository across. So I was wondering if anyone wants to volunteer to do the conversion to save me having to spend a day or two downloading then building a virtual Linux box then going through the package shuffle. From my brief understanding of git, I believe I can then clone your git repository (put it on github) and make the clone the 'official' version.
Warning: Unangband's SVN repository is 'quite large'. The Github online SVN conversion tool notes that the conversion process may time out for large repositories. When I've attempted to use this tool, it appears to take too long (at least an hour) simply trying to get the list of subversion authors.
* I'm using egit which is the Eclipse implementation running on top of jgit. If anyone has done a jgit based svn2git conversion, please let me know.
[Edit: Thanks for the quick responses. I've got someone running an svn2git conversion now...]
Posted by
Andrew Doull
at
10:59
13
comments
Labels: development updates, help wanted, unangband
Friday, 30 September 2011
Teaser
Ah... the early days of a project. Given I'm learning the language I'm implementing in at the same time, I'm really happy with the amount of progress I'm making (Thanks [insert-really-cool-library-here]
Posted by
Andrew Doull
at
07:55
6
comments
Labels: development updates
Thursday, 29 September 2011
Javascript.notEqual(highLevelLanguage)
So, array comparison.
Why is there no standard function for this in Javascript?
Posted by
Andrew Doull
at
07:28
10
comments
Labels: development updates
Monday, 19 September 2011
ARRrrrrrP
Hmm... I didn't realize the ARRP (Annual Roguelike Release Party) this year fell on Sunday the 18th, which was yesterday in this time zone.
However, I'm going to celebrate the International Talk like a Pirate day (September 19th) by releasing a new version of Unangband some time later today.
So happy ARRrrrrrP day instead.
Posted by
Andrew Doull
at
16:13
0
comments
Labels: development updates
Friday, 9 September 2011
Annual Roguelike Release Party
I'm putting a cunning plan in place to attempt to have a version of Unangband ready for the 2011 Annual Roguelike Release Party.[1]
A cunning plan which is in serious threat of being derailed by this (scroll down for review). You have 3 days to convince me not to buy it...
[1] I cannot promise the new version won't eat your computer however.
Posted by
Andrew Doull
at
20:23
4
comments
Labels: development updates, links, the unday papers
Wednesday, 13 July 2011
All fired up: part two
jdunson brings up a really interesting point in the original All Fired Up post:
Something like an "Aura of Flame" might well be a multiplier; "Increases all flame damage by +200%". Some cases might provide base damage as well, some not.I had been thinking along similar lines about a number of related effects. Now I have a flexible way of representing multiple scalars (pvals) on an object in Unangband, I'm inspired to immediately extend the types of bonuses that can be represented.
I've already included context specific combat bonuses: to-hit, damage, number of blows/shots, damage multipliers, range; for melee, ranged weapons, throwing, traps, unarmed combat. This addresses the design problem I outlined in Throwabow: if you throw a bow with a high damage bonus, do you inflict the extra damage?
(Aside: I can immediately see from the above, that I need to include context specific damage dice and sides).
What other interesting bonuses are there?
jdunson's 'boost all fire damage by 200%' suggestion is actually more complicated than it initially appears, because of the number of different ways fire damage can occur - as I outline in Different Ways of Killing. There's weapons, spells, magic items (rods, staffs, wands), thrown oil and fiery potions. Do I also boost damage from a flask of oil (or another fire damage source) set in a trap? Does the bonus boost allies fire damage (which in Unangband is treated as equivalent to damage from the player)?
And for effects, such as spells, which persist over time, does the damage boost still apply if the item is removed?
For those bothered by my repeated mention of Team Fortress 2, the way damage effects apply there is another excellent example of unintended consequences of any of the above decisions. At the moment, TF2 has an example of a damage nerf (the Detonator) which is a secondary weapon which only does +35% damage against burning opponents, unlike the weapon it is based on (the Flaregun) which does +200% damage in the same situation. However, if you switch away from the Detonator before the projectile hits, the game no longer applies the nerf, and so you get the full +200% bonus. TF2's history of bug fixes is littered with this kind of interaction (damage bonuses against aerial opponents if they are merely standing on stairs and so on).
So I believe I'm better off by focusing on the context of the damage bonus, and then designing weapons which list the possible related contexts. To take an example: I could add boosts to casting spells by increasing the effective level of the player casting the spells, the effective level of the player when learning spells (which makes more spells available), the failure rate of spells and the casting cost of spells. In addition to a general boost, I could also add spell book specific boosts. A sword of fire would then list each of the above boosts which regards to the fire spell books, along with the relative minimum and maximum values; and when randomly generating a sword of fire item, specific values are chosen.
This does become a problem for the player to compare weapons - which is already a major issue, but hopefully the bonuses are going to be concrete enough to make a comparison (Do I want to be able to cast fireballs, or get an extra +x1 damage multiplier?).
Posted by
Andrew Doull
at
10:59
5
comments
Labels: development updates, game design, unangband
Friday, 8 July 2011
All fired up
A character is wielding a flaming sword (x3 fire damage), flaming gauntlets (x3 fire damage) and enchanted with an aura of fire (x3 fire damage).
Should he be doing:
1) x27 fire damage
2) x7 fire damage
3) +600% fire damage
4) x3 fire damage
This is an important decision that I have to make in the next version of Unangband, and it's vexing me, so I'd like your advice.
Option 1 is clearly overpowered, but one way of thinking about the problem. Options 2 and 3 are two different ways of explaining the same approach: x3 fire damage is short hand for 3 times damage against creatures not immune to fire, which could also be seen as +200% fire damage.
Option 2 is the less intuitive (how does x3 + x3 + x3 equal x7?) but option 3, which rewrites the original problem as "A character is wielding a flaming sword (+200% fire damage), flaming gauntlets (+200% fire damage) and enchanted with an aura of fire (+200% fire damage)." invites the player to think about weapons which might be +150% fire damage, or +87% fire damage. I'm designing Civilisation Revolution, not Civilisation with a V in it, so I like to work with nice whole numbers, not messy fractions.
Option 4 is the vanilla, balanced, safe option, so I have to ignore it.
Thoughts?
Posted by
Andrew Doull
at
17:18
30
comments
Labels: development updates, unangband
Saturday, 18 June 2011
Just like a dirty, cheating player
One of the biggest challenges in Unangband when fighting some of the higher level uniques is their tendency to teleport away then heal themselves up. This extends fights because it forces the player to track the unique down again and continue - and is doubly challenging if the monster also has the ability to recover the mana points that they used up in the process of escaping. What can result is extend stalemates, where the player is unable to damage the unique quickly enough to kill them before they escape again.
There are plenty of opportunities to break these stalemates: deadly traps, cross-fire from other monsters that may be involved in the fight; but these mostly rely on the monster AI not being smart enough to recognise and avoid these additional threats.
The player is equally capable of using teleports and heals, and has the additional ability to flee up or down the stairs at any point (I've considered allowing uniques to do the same) to effectively reset the level. Teleportation can be a risky escape mechanism, because the destination may be more deadly than the current location, and healing may be overwhelmed by more damage the following turn and permadeath ensures that the player is punished for pushing their luck too far. But monster teleportation and healing is less risky, because the unique is in the position of having overall control of the level: there is no other faction he could teleport into which would threaten him, and the player usually lacks the means of ramping up damage even further (because otherwise he'd already be using it).
Allowing the player to summon monsters is one significant way of addressing this, but not every player is a spell caster capable of doing this. Letting warriors and thieves recruit armies or assassins is another possibility, but outside the scope of the game in the short term: and very much against the fiction of Angband which is a one-sided battle where you are the 'weaker' side. Druids are also capable of using spells to 'prepare the ground' and make part of the dungeon far more dangerous for other monsters. And other roguelikes offer anchor magic of various kinds which prevent both the player and nearby monsters teleporting to escape.
A trap that some Angband variants fall into is offering various abilities to drain monster mana, which since mana inevitably is converted into hit points by monsters which can heal, means that these items are effectively doing large amounts of damage - usually much larger than any other attack is capable of.
I think I have the balance of the above mix right for spell casters in Angband, but I'm welcome to more feedback. I'm more worried about whether I've missed anyway of balancing these abilities. I'd love to hear your ideas on other ways to fix this.
And for the record, I've always loved enemies turning around and using healing magics - Tenchu being the first game where an enemy ninja quaffed a potion just like I had been doing - because it makes you realise on many levels just how cheap, portable, instant, heal all magic can be.
Posted by
Andrew Doull
at
10:47
6
comments
Labels: development updates, unangband
Friday, 17 December 2010
"Sometimes it pays to stay in bed on Monday, rather than spending the rest of the week debugging Monday's code."
Of the Top 50 Programming quotes of all time, the above is the one that is the most true for me.
Unfortunately, this year appears to have been one long Monday...
Posted by
Andrew Doull
at
12:45
0
comments
Labels: development updates, links
Tuesday, 28 September 2010
Design ratios
Just a quick comment about user interface design and game programming after reading various comments on Unangband UI, Dwarf Fortress vs. Minecraft and Civilisation V.
I find that you need to spend about 3 to 5 times the amount of time and/or effort on explaining the features of the game, as implementing the features in the first place. This includes user interface design and documentation and is probably an underestimate for games in general, because I design most of the documentation to be generated rather than hand written.
Posted by
Andrew Doull
at
17:21
2
comments
Labels: development updates
Sunday, 19 September 2010
Designing a Magic System Redux - Part Three (Magic Items)
You are encouraged to read parts one and two of this article series, and are strongly encouraged to read the original Designing a Magic System series of articles if you have not already done so. This article also incorporates most of the text from another blog post which you may want to refer to the comments of.
I've been working on adding items with multiple 'pvals' to Unangband, and this is probably the most wide ranging set of changes I've made to the code since I began developing.
In Angband-speak, a pval is the value associated with a particular magic item flag: the +3 in a ring of Strength +3. Angband and many variants only allow you to have one numeric value per item, which was also historically overloaded with additional meanings such as the number of charges a wand would have. I've separated out that meaning (there is now a separate charge value) - and I'm now in the process of allowing items with multiple different numeric values e.g. a ring of Strength (+3) and Size (+7).
I'm not the first variant to have done this: so I'm taking an approach similar to Sangband, where the pvals are represented by a small numeric array of values, and then the flags to which pvals can apply become a bit array. So you end up with a situation where you might have pval[1] which is +3, and pval_flag[1] which is Strength, which in combination mean Strength +3.
The alternative is to have an integer array equal to the size of the possible different flags: the example here would be pval[STRENGTH_INDEX]=3. This obviously uses up a lot more memory and storage for each item, but with modern computers, the performance impact would be negligible. I've chosen the Sangband approach as much as a design constraint as a technical constraint - I have a hunch that people will have problems comparing two items which have more than 7-10 different discrete numeric values.
I have made a decision which increases the amount of code I've had to alter but should make it simpler long term, by also making item abilities such as to-hit bonus and to-damage bonus, weight and armour class, included in the pval framework I'm developing. To make this clearer, I've retitled them avals, short for ability values. An item now has abilities, associated with avals and which vary over an integer range, and flags, which are either on or off.
One possible abuse of the ability to use Angband items in multiple ways is the ability to throw ammunition instead of shooting it from a bow or crossbow. Ammunition is light, which means you can carry a lot of it, and throwing it is 'abusive' because the damage bonus that is applied to firing ammunition is also applied to thrown ammunition, without penalty. This is exacerbated in Unangband because the damage bonus was until the latest version counted twice for thrown weapons and not multiplied by missile launchers, which meant that throwing an arrow (+9,+9) may be more effective than firing it from a longbow.
The damage bonus in this example is insensitive to it's context - it is applied equally when the item is thrown, set in a trap, or fired from a missile weapon. And if you think the ammunition example could in some way be construed as sensible, consider that the damage bonus a bow applies to arrows fired from it, would also be applied if you threw the bow instead.
At the moment, I'm changing this: damage bonuses will be able to be context sensitive - a weapon that adds damage while fighting, won't necessarily benefit shooting, but may, for example, benefit being used in a trap.
I have the flexibility to allow missile weapons with incredibly good trap damage but no shooting damage bonus, but it is unlikely that a player would ever choose such a weapon over a missile weapon with superior shooting damage and no benefit in traps. Whereas if the weapon was multi-functional, it is more possible the player will attempt to take advantage of 'free' additional functionality at some point. I can do either approach with the approximately same level of cleanliness in the code: it is a data design issue, rather than code overhead cost.
There is a separate but related question about worn vs. wielded items. If a sword improves your ability to fight with it, does it also improve your ability to fight with another weapon if you hold it in your off-hand or even just strap it to your body? In particular, if you get one more blow per round with it, do you get that blow if it would be from another weapon?
On consideration, there are two related ways of thinking about magic items: firstly, how the abilities (avals) accumulate if the character is using multiple items which have this ability, and secondly whether the player inherits the power (ability, flag) of the magic item at all.
The simplest example is weight: if a character picks up two objects, both of which have weight, how is the character's overall encumbrance affected? This example is seemingly straight forward: the weight of the two objects is added together to give the total encumbrance.
But what if we measured encumbrance as the sum of weight, plus volume, plus length, which may be a more realistic way to model how difficult it is an item to carry? It may be possible to stack the two items side by side, so that the length of the total isn't the sum of the longest axis of each of them. So even this simple example can be complicated through extrapolation.
Then there is the problem of accumulating numeric values. +3 to hit, and +6 to hit is seemingly straight forward (+9 to hit), but how does one item which gives 50% resistance to fire, add to another item which gives 33% resistance to fire? Should it be additive, so that the player gets 83% resistance to fire? Or multiplicative, so that the player gets 66% resistance (1- (1-.5) * (1-.33))? I am a big fan of geometrical progression for resistances - because they provide a big impact initially which tapers off, but is still useful when added together. In the most straight forward geometrical progression scheme, level 1 resistance gives 50% resistance (1/2), level 2 gives 66% resistance (2/3), level 3 gives 75% resistance (3/4) and so on.
This also depends how you model fire damage to start with. What does 50 hp fire damage actually mean? Is 100 hp fire damage twice as hot? In which case, if you are modeling resistance to fire damage as ability to tolerate a temperature range, someone with 50 resistance may be able to ignore 50 hp completely, but take 50 hp damage from a 100 hp attack.
Specific versus damage bonuses are another tricky component to balance. In Angband, weapons have the ability to slay particular types of monsters for double, triple or higher damage, or branded with an element which does additional damage from fire, cold and so on. The Angband approach is to use the highest multiplier, rather than add the multipliers together. This is simplifies the creature design process as the designer is free to create a creature which is a hybrid of e.g. dragon and undead, without having to worry about this creature taking more damage from the weapon which is effective against both dragons and undead than against creatures which are just either dragon or undead.
The same applies to brands, even though we could model a weapon with multiple brands as doing both extra extra fire damage (which creatures immune to fire ignore) and extra cold damage (which creatures immune to cold ignore). If we treat this weapon as doing extra damage from each element, instead of picking the highest multiplier, creatures which are neither immune to cold or fire would take both sets of damage, which would make weapons with multiple brands much more effective than weapons with multiple slays.
But should this 'highest multiplier' approach be used across multiple items where e.g. a character could have a weapon with a fire brand, and also a ring which imparts a fire brand to the weapon. If yes, then there is no benefit to specialising in fire-based equipment, while there are plenty of draw backs. If no, and the multipliers add together, you have to balance for the maximum per item multiplier is multiplied by the number of possible items that the player can gain benefit from at the same time. Be sure to come up with a good reason for being unable to wear a ring on each finger and toe, and pierced through any available flap of skin.
With the inheritance question, it is clear some abilities are straight forward: they should be applied to the player if the item is equipped (fire resistance), or only apply to the object in question (proof against destruction by fire). It is specifically the 'use the item in question to perform a task' abilities which are not so clear. Take the ability to increase the amount of damage the player does.
As I highlighted earlier, it makes no sense to have the bow's damage bonus apply to the weapon when throwing it. So to address this, damage gets separated into 'damage while shooting', 'damage while setting traps' and so on. These are simple enough to apply to the player: or are they?
The dual wield problem, when a character is using a sword in his primary hand, and a dagger in his secondary, show that this is not necessarily straight forward. Does the dagger's 'damage while fighting' apply to attacks with the sword? In all likelihood, not (If you disagree, replace damage with fire brand. Does the dagger's fire brand also brand blows from the sword?). So we have to consider 'damage while fighting' as a specific property of the item, which we add at the time the item is used, as opposed to inherited by the player.
But this means that the same item ability is used in two different ways: an amulet of 'damage while fighting' is inherited by the player, but a dagger of 'damage while fighting' is only applied when we use the dagger. In which case, it may be simpler for some items to have a straight 'damage bonus', which is used whenever the item is being used, but not inherited by the player at all, whereas other items have a specific 'damage while shooting' bonus, which applies only when the item is being fired.
(I'm going to complicate this by also having rings apply some abilities only to items wielded in the hand they are worn on. This will be the left-hand for shooting and secondary weapons, and the right-hand for primary weapons.)
In the part five, I'll look at how Unangband evaluates the relative power of magic items, taking into account the inheritance or non-inheritance of various flags while keeping the above issues in mind.
But first, in part four, I'll take another look at skill acquisition.
Posted by
Andrew Doull
at
10:55
5
comments
Labels: articles, development updates, magic
Friday, 10 September 2010
Iso-Unangband
Despite my attempts to dissuade him, Hajo appears to be insisting on doing an isometric graphics version of Unangband. This will be a much improved version of the experimental Windows code I had previously included. You can follow the thread at angband.oook.cz.
Posted by
Andrew Doull
at
14:27
0
comments
Labels: development updates, isometric, unangband
Tuesday, 10 August 2010
Designing a Magic System Redux - Part Two (Status Effects continued)
You should read part one of this article, and are strongly encouraged to read the original Designing a Magic System series of articles if you have not already done so.
There is an asymmetry in the design of status effects in Angband: they differ (sometimes significantly) in implementation between the player and monsters. But I've aspired in Unangband to reduce the asymmetry between the two where possible so I'll begin discussing the impact status effects they have on the player and briefly note into the differences between the player and the monster at the end of the article.
There is also a difference between the original Angband, and Unangband implementation of status effects, where Unangband has more possible states, but compensates by weakening the impact of the original Angband effects. The primary approach I've taken is to make it harder to add additional time to a status effect once the player is already affected by it - to avoid continuous locks. I've also modified the effect where noted below with the intention of making it easier for the player to continue to act when partially impaired without requiring they immediately reach for a reset of the effect.
Blindness was the example I looked at in the first part of this article: a player who is blind has a significant penalty to hit when attacking and cannot read scrolls or cast spells - presumably being unable to read the words from the spell book. In addition, the player stops getting screen updates - so that they are not able to see the current location of enemies or changes in surrounding terrain. My intention in Unangband is to weaken the blindness effect slightly, so that you can cast a spell once, from memory, while you are blind, before forgetting it. This is a shout out to my AD&D 2nd edition roots, as well as a way of allowing the player to sneak around in the dark and still cast spells.
Amnesia in Angband has been changed to a timed effect, based on Unangband's implementation, so that you suffer a penalty to your chance to cast spells. Unangband also prevents you from activating artifacts and other items - it makes you temporarily forget you have identified them - and when blind, will stop you from casting spells at all. (At the moment Unangband stops you from casting at all while merely amnesiac, but I'm changing to closer match Angband in the next version).
Confusion in Angband prevents you from spell casting, as well as causing you to move and shoot in a random direction instead of the intended direction. I weakened this effect in Unangband so that you can cast spells while confused - because the random target selection effect when combined with the ability to hurt yourself with spells makes for an interesting risk vs. reward trade off - and also made confusion only having a percentage chance of taking effect which increases as you become more confused.
Fear prevents you from fighting monsters in melee - you refuse to attack anything that you bump into. This is meant to encourage the player to flee, but it instead merely forces you to switch to missile weapons or spells, which there is no penalty to use even at point blank range. To compensate for this, I'm adding an additional terror effect, which acts as an 'overflow' to fear. Once you become sufficiently afraid, any fear will overflow into the terror status. While you are terrified, you cannot use any ability which requires aiming - including spells, missile or thrown weapons. You are still able to use other abilities, amongst them the various teleport effects you should be considering to escape with.
I've taken advantage of multiple meanings, to provide an alternative overflow from fear: that of petrification. Petrification status prevents you from moving (although you may teleport still), and has no other effect - although most direct petrification attacks are highly damaging as well. It is possible in Unangband to become petrified with fear, in the same way that terror overflows - and the two different types of overflow are exclusive: you'll either become terrified or petrified if you are made highly afraid, not both.
Paralyzation is the most uninteresting status effect: you simply cannot do anything while paralyzed, and so it is incredibly hard to balance and puts the player at the highest risk of getting a lock. Unangband has a second, more interesting variation: stasis - which paralyzes you, but also makes you invulnerable to damage, which is a side effect of time attacks. Stun deserves mention here because it incrementally penalizes you to the point of knocking you out, an identical result as paralyzation, but the initial penalty is very slight. Both paralyzation and stun are less interesting than the status effects I've already mentioned, because you either perfectly resistant or are in incredible danger should you encounter a monster (or worse group of monsters) which inflict this effect, with very little margin in between. To mitigate paralyzation, I use the slow effect as an intermediate step, with you being slowed before you are paralyzed the majority of the time.
Using the above combination of effects, you can chart the impact on the player's abilities as follows:You might be tempted to add, for example, a Nausea effect to the above chart, which prevents you from using potions. But I'd discourage this: potions are best kept as the get out clause reset for any effect. It is still possible to partially incapacitate yourself through bloating by stuffing yourself with food and drink, for which a potion of Salt Water is a useful antidote.
You'll also notice Daze in the chart, which I haven't provided an explanation for yet. Daze will be new to Unangband in the next release: it prevents the caster from casting spells on himself and is the direct inverse of Terror, but for only spell casting and (perhaps) magical devices. Daze is interesting because it forces you to use spell attacks which are hampered, or my preferred terminology, made more interesting by blindness and confusion. To complement this, both Confusion and Blindness overflow into Daze, and there is no direct way of a player being dazed by an attack.
Of the effects in the above chart, only petrification, fear, blindness and amnesia of themselves totally incapacitate some ability of the player. The remainder only incapacitate in combination, or as a result of another status effect being repeatedly applied to the point where it 'overflows' into a more dangerous status (Terror and Daze cannot be directly applied to the player). The idea here is the player should get some opportunity to use a reset to avoid incapacitation, with a large margin of error before the more dangerous state occurs.
There are in fact 32 status effects which can negatively effect you in Unangband: of those I've not mentioned, the remainder are either debuffs (stat modifiers), change the rules monsters use to track you (aggravation, stench) or damage over time effects (poison, cuts) and so don't need result in the complete incapacitation which causes a lock. There a Soaked effect which prevents you from lighting fires or reloading firearms, and a Berserk effect which allows you to voluntarily give up missile and magic attacks in return for improved melee, healing and immunity to fear but both of these will have minor impact compared to those I've discussed in depth.
There are two exceptions: Sleep and Hallucination.
Sleep is one of those spells from AD&D which I cast into the same problematic category as Magic Missile. It was a 1st level spell which either fails or immediately and completely incapacitates with no in between. Sure, you can increase the level casting requirements and have the victim wake when attacked instead of being able to deliver a coup-de-gras, but the ability to completely disable an opponent and escape means the spell has to be made effectively useless against any opponent you'd want to use it against. Sleep works great in a role playing game which is strong on the capture and interrogate dynamic: not so for computer games.
Angband sidesteps Sleep effects against the player completely in favour of paralyzation, which is less a solution and more a tactic acknowledgment of the scope of the problem. Unangband separates them: and gives the player a cool down before falling asleep, which you can cleverly use to damage yourself to stay awake. Should you keep damaging yourself for the duration of the sleep spell, you'll avoid the effect completely.
Hallucination is a fun trick with ASCII graphics, but has little functional difference, and a lot of overlap with the confusion effect. Unangband already has enough restrictions on spell casting to make it worthwhile having hallucination stop spell use as well. But the Nightmare on Elm St of sleep started to get me thinking about what hallucination should do.
Sorcerers in Unangband don't have the range of options that the other major spell casting classes do. I've tried to remedy this by letting them make magical traps, but this both lessens the utility of actual trap setting, and requires enough horrendous hackery that I'm forced to reconsider. Sorcerers can shape change, and charm, and like druids have a minor in summoning spells, but I've come to realize that status effects should be the sorcerer's forte. But blinding and confusing and dazing monsters leaves two problems for me to wrestle with: firstly ensuring that the time required to get a lock on a monster is approximately the same as killing it, and making clear the victory conditions for doing so.
I will be reusing the surrender code to allow monsters to gracefully give up to the sorcerer: but it is more difficult to decide when this should occur. With hit points, we have a clear definition: when the monster is near death. With status effects, I have to define more clearly how to get a lock.
Take the following chart:
This is the status effects I've described previously, excluding effects that disable all a monster's abilities, with arrows used to indicate where one status effect overflows to another, and where abilities accumulate together to provide a 'higher level' result. I've added one additional overflow: confusion also can also overflow to hallucination - which will be important later.
If a monster is both frightened and petrified, it is considered in a melee attack lock. It cannot provide any kind of melee threat to the player, and if it is only capable of melee, it provides no further threat to the player until it recovers from either effect. Similarly, terror provides a ranged attack lock by itself, where ranged attacks are either shooting or breath weapons, and either amnesia and blindness, or terror and dazed effects provide a spell casting lock. A monster will surrender if it has all its abilities (melee, ranged, spell casting) locked for sufficient time and it has no allies in line of sight which are also not incapacitated. If a monster doesn't have one set of abilities it is is easier to lock.
In this way, aiming for a status lock is a broad attack in that you have to apply multiple different effects to a single monster for it to be defeated, whereas damaging attacks are deep in that once you find the vulnerability, you repeatedly exploit it with the same attack.
Also note that if the monster is immune to a particular status effect it is also harder to get into a lock: for instance monsters which are immune to fear cannot be melee or ranged locked unless it is possible to directly apply petrification or terror. Ideally there should be multiple paths to achieve each lock, so that a monster which is immune to a single type of status lock can still be affected by applying another combination of status effects. I am tempted to make the hallucination effect also prevent ranged attacks - another alternative would be to make confusion plus blindness effectively act as a ranged attack lock, because a blind and confused monster is unlikely to be able to use any ranged attack effectively.
But even if I make hallucination prevent ranged attacks, it still feels like the unwanted step child of status effects. Luckily, I've come up with a fevered dream of a solution that should give Sorcerer's yet another way of attacking monsters with status effects.
What is missing from Unangband is the ability to create illusions - something a Sorcerer class should excel at. There's a number of ways to implement illusions: you can have monsters which disappear when attacked, mirror images of the Sorcerer which disappear when attacked... all in all, a little ineffectual.
But what if you allowed illusions to cause real damage while the target was affected by particular status effects: I'm thinking specifically of while sleeping. That way you could have illusions interact with real monster resistances so that if you tried to burn a monster with illusory fire which is normally immune to that effect, it notices and wakes up, whereas you could damage it while asleep and have it remain asleep if it succumbs to the illusion. The incentive here is for the Sorcerer to attack monsters as they asleep, but have to periodically force them back to sleep as they are awoken by the illusory effects you cast at them. Pure damage could be represented by the Sorcerer's existing mental attack abilities, which would cause double damage to sleeping monsters whereas the various illusory elemental attacks would require the illusionist play by the same rules as regular spell casters.
And in this scheme, the hallucinating status effect would similarly allow you to affect monsters with illusions while they are awake. The advantage to hallucination is the sleep effect has a time delay before the monster succumbs, whereas hallucinations take effect instantly.
This is followed by part three which looks at magic items in more detail.
Posted by
Andrew Doull
at
21:20
8
comments
Labels: angband, articles, development updates, game design, unangband
Sunday, 8 August 2010
Design A Magic System Redux - Part One (Status Effects)
In the original Designing a Magic System series of articles, I briefly looked at status effects as a way of separately out various incapacitation effects from hit points. Antoine's suggestion of an Enchanter class in Angband has forced me to take a closer look: both to justify my intuition that an Enchanter class would be inherently uninteresting, and set myself the challenge of trying to make this class, or the Sorcerer equivalent in Unangband, an interesting play style. Luckily I'm in the midst of implementing a whole host of new status effects in Unangband, so I'll be able to benefit from this design exercise as well as give you some insight into the decisions I've made.
My original thesis in Designing a Magic System was hit points are a good design compromise between a tug of war between two sides, which could result in games which never resulted in a victory condition, and incapacitating damage which would result in a negative feedback loop where the player could lose the game without being dead.
In this model, status effects become an idealized way of representing various types of incapacitation without being directly linked to hit points. Status effects are almost always timed, to allow the ability limited by the status effect to recover naturally should the player survive long enough, and can be recovered from using a variety of resets. It is important when designing status effects that it is not possible to get a lock on the player, but you can intentionally design traps, which are best suited to multi-player games, to allow a player to get a significant advantage by applying a lock, but at increased risk should the opponent predict that they are attempting this technique.
(If you are not familiar with locks and traps, I recommend that you refer to the original articles).
The canonical example of a status effect is the interrupt - this interrupts whatever the other player is doing and forces them to start again. If the interrupt takes less time than whichever action the other player is attempting, you can keep your opponent constantly interrupted - and if you start your interrupt action before they do, you can get a lock on the other player by interrupting their attempts to interrupt you. If the game has an action which takes less time than an interrupt, but does much less damage than the standard action, you can create a trap: the other player may attempt a standard attack for a lot of damage, but be at risk of your interrupts, or use the weak attack to avoid being interrupted, which exposes them to your standard attack. The trap in this example is only interesting if the other player is a human opponent: because it forces you to build a model of what the other player is thinking - in effect, to second guess them.
The interrupt as a status effect can be problematic for two reasons: the interrupt can be constantly applied if the duration of the interrupt is longer than the time required to apply it, and if there is no way the opponent can get a win if you choose to always interrupt. I've referred to both of these as locks, but these are actually different but related behaviours. (Note in this example, the duration of the interrupt is actually the duration of whichever action your opponent was attempting, plus the duration the interrupt prevents further activity for.)
Even if you are careful to ensure the interrupt action takes longer than the time it interrupts the other player, if you team up with other players, it may be possible to get a lock on a single player through judicious timing of interrupts. (Or conversely, multiple enemies could get a lock on you).
But imagine an interrupt which only affects some of the possible actions the other player could choose. An example in Angband is blindness. Blindness has a partial effect on the player's melee and shooting skills, completely prevents spell casting and reading scrolls, but has no impact on the player's ability to quaff potions, or use rods, staffs or wands. As a designer, you can minimise the risk of constant blindness by designing items which can reset the blindness effect and ensuring that they are usable via a action which blindness does not prevent - as a player, you can minimize the risk by ensuring that you carry these items. The counter-example to be avoided: a helmet of blindness which can only be removed by reading a scroll of remove curse. This would give the player into permanent blindness once they accidentally wear this item - not catastrophic, but a significant impact on the overall game.
(For the Unangband equivalents, you could extend this table to include all the possible status effects to get a feel for what different types of partial incapacitation could do.)
By using partially incapacitating status effects, and allowing resets, we can side step the risk of unintentional locks because the player can always reset themselves out of a lock, or choose an action which is unaffected by the lock that allows them to progress towards winning. (Using rods, staffs and wands are permitted while blind for this very reason).
There is still the risk of cumulative locks as follows: imagine there are some number of partially incapacitating effects, each of which affects the player's ability to do certain things, but when some of these effects are applied together the player is totally incapacitated. You can design your way out of this problem by ensuring that there is always something the player can do - but I think there is a more interesting alternative.
I've been using the term path to victory somewhat loosely: but let's be more rigorous about it. The path to victory is the total distance (number of actions or time) that the player needs to win the game. The shortest path to victory is the player doing the optimal action at every point and the opponent picking the most suboptimal action: the game is unbalanced if both the player and opponent choose their most optimal action and either is guaranteed victory. Unbalanced games are fine against multiple opponents (Angband being a classic example of this).
For this argument, assume the path to victory is always progressed by doing damage to the opponent's hit points. In this instance, the most logical way to win is by using your most damaging attack. A counter strategy to this is to use status effects against you which prevent you using your most optimally damaging attack, and force you to use a more suboptimal attack. Ideally the first status effect to apply would be the one that causes the most difference between the two: but it may also make sense to use a status effect which lasts longer and gives your opponent a bigger window for counter attack.
The path to victory is blocked completely if the opponent is able to use a combination of attacks which prevent you doing any damage at all to them. We call this a lock.
The above is pretty self-explanatory and you can see various techniques for reducing the risk of a lock (always allow a damaging attack and a reset to be available, reduce the duration of the combined status effects so that the time to implement them all exceeds that figure etc).
Here's my theory: the risk of a lock becomes a non-issue, when the distance to achieve a lock (time or actions) is the same as the length of your path to victory. That is, if the effort required to get a lock on an opponent equals or exceeds the effort required for to win against that opponent, from a design point of view you don't have to worry about the risk of a lock being applied. In essence, getting the lock is just as difficult as winning.
(In fact, you can have a more generous margin, because it may not be initially clear whether direct damage or a lock is the correct approach to take.)
Antoine's Enchanter (and Unangband's Sorcerer) then becomes a class which can lock opponents through a combination of status effects with about as much effort as another magic using class would take to kill them.
And in part two, I'll look at which status effects that Unangband has to support this.
Posted by
Andrew Doull
at
12:51
2
comments
Labels: articles, development updates, game design, magic, unangband
RIP
For a variety of reasons, I am tempted to add the 'towel wrapped around head' character state.
Posted by
Andrew Doull
at
11:59
2
comments
Labels: development updates, unangband
Friday, 23 July 2010
Throwabow
One possible abuse of the ability to use Angband items in multiple ways is the ability to throw ammunition instead of shooting it from a bow or crossbow. Ammunition is light, which means you can carry a lot of it, and throwing it is 'abusive' because the damage bonus that is applied to firing ammunition is also applied to thrown ammunition, without penalty. This is exacerbated in Unangband because the damage bonus was until the latest version counted twice for thrown weapons and not multiplied by missile launchers, which meant that throwing an arrow (+9,+9) may be more effective than firing it from a longbow.
The damage bonus in this example is insensitive to it's context - it is applied equally when the item is thrown, set in a trap, or fired from a missile weapon*. And if you think the ammunition example could in some way be construed as sensible, consider that the damage bonus a bow applies to arrows fired from it, would also be applied if you threw the bow instead.
At the moment, I'm changing this: damage bonuses will be able to be context sensitive - a weapon that adds damage while fighting, won't necessarily benefit throwing or setting in a trap.
But the question I have is should I enforce this change? This is not quite Warren Spector's proximity mine climbing emergence, but it is an interesting and unintended consequence of a design that may be worth keeping.
I have the flexibility to allow missile weapons with incredibly good trap damage but no shooting damage bonus, but it is unlikely that a player would ever choose such a weapon over a missile weapon with superior shooting damage and no benefit in traps. Whereas if the weapon was multi-functional, it is more possible the player will attempt to take advantage of 'free' additional functionality at some point. I can do either approach with the approximately same level of cleanliness in the code: it is a data design issue, rather than code overhead cost.
It'd be interesting to hear your thoughts.
* There is a separate but related question about worn vs. wielded items. If a sword improves your ability to fight with it, does it also improve your ability to fight with another weapon if you hold it in your off-hand or even just strap it to your body? In particular, if you get one more blow per round with it, do you get that blow if it would be from another weapon?
Posted by
Andrew Doull
at
21:38
3
comments
Labels: development updates, unangband
Monday, 19 July 2010
A big commitment
If it looks like things are quiet on the Unangband development front it is because I'm feeling my way through a ridiculously big chunk of code that I probably should have committed part of already.
Unfortunately, it is mostly back end stuff which you'll see very little of in the actual game: redesigning how timed effects work, allowing items to have multiple pvals (called avals), adding approximately 96 additional item flags which are all pretty much already used in game. The pay off will be flexibility to implement everything I've implemented already. Which is how most redesign work ends up 'helping' what you do.
This sort of thing ends up happening when you code on the train without 3G access.
Posted by
Andrew Doull
at
21:01
2
comments
Labels: development updates, unangband