Sunday, March 27, 2011

Dungeon design journal #4: making a monster

Introduction

If you are using Inform ATTACK, how much code does it take to create a monster? Six words.
The boar is a hostile person.
I have spent a considerable time coding up three monsters for my dungeon crawling game. The third one took me about 1600 words, which is a little more than 6. Where does the discrepancy come from?

One of the main design goals of almost any tactical combat game should be to make the enemies as diverse as possible. This is not necessarily easy. Desktop Dungeons, which features only a handful of monsters, has only few good ones. Mostly it is just the "raise one stat, lower another" approach: a monster with a lot of health but little damage, a monster with little health but a lot of damage, a monster with high magic resistance but low health. Dungeon Crawl Stone Soup has many awesome monsters, like hydras and ugly things, but also (certainly on the earlier levels) a lot of monsters that feel more or less identical. And I for one wasn't impressed by the diversity to be found in Dragon Age: Origins.

There is of course such a thing as cosmetic diversity: different sprites or models or descriptions, even if they have no effect on the gameplay, can enhance the game. This is not unimportant. But we want more. We want monsters that force the player to rethink their tactics and their strategy. This means that the monster must interact in an interesting way with one or more tactically important aspects of the game: the items, the skills, the spells, the terrain, the basic combat actions, or whatever else you have. So thinking up a good monster generally starts with thinking about your tactical system.

Let us observe something about the basic ATTACK system of attacking, dodging, parrying and concentrating. In general, dodging and parrying are pretty much no-brainers: if you are attacked, you do whichever of them seems to be the most useful against the current attack. (Parrying a bullet is not going to work.) You could concentrate instead, if you are feeling very brave, but the AI is good enough at deciding when attacking is useful that this is rarely a good idea.

No, the basic tactical decision in ATTACK is that between attacking and concentrating. It might seem that this is a decision between investing in a better future attack (concentrate) or doing some damage now (attack). In general, however, that is not really what you are worrying about. What you are worrying about is your opponent's concentration level, your ability to destroy his investment and his ability to destroy yours: when you deal damage to someone, that person loses his concentration. So suppose your concentration level is 1, and your opponent has just raised his level to 2. If you attack, you might very well miss. If you miss, he can raise his level to the maximum of 3, and you, with no concentration left, will have a hard time disrupting him -- which means that he can unleash a very deadly attack. If instead of attacking him now you concentrate to 2, and he concentrates to 3, you'll have a much better chance to hit him and disrupt his concentration before he can attack you. So concentrating might seem like a good idea.

On the other hand, what if you raise your concentration to 2 and he does not raise his concentration to 3, but attacks you instead? If he hits you, you will lose two turns' worth of investment. That is very bad. So maybe it would after all be preferable to hit him right now and try to disrupt that concentration before it gets any higher. If you hit, you might very well win initiative, and then you'll be the one ahead in the concentration race.

Now there might well be an optimal strategy for ATTACK, but the math is complicated and highly dependent on little changes in the stats and the health the combatants have left. So it does feel like a tactical gambling / bluffing game more than like a math problem to be solved.

Why bring this up? Because an understanding of the basic tactical decisions allows us to think of ways to turn these decisions on their heads, so to speak. In the basic system, a person is most vulnerable when he is maximally concentrated: concentration gives no defence bonus, and if you get hit you lose a big investment. So, for a radically different tactical situation, what about a monster that is least vulnerable when it is maximally concentrated?


Enter the chain golem

The chain golem is a lumbering mass of metal chains that attacks by lashing out at its opponents with some of those chains. When it concentrates, it starts spinning around, whirling its chains through the room. As it concentrates more, it starts spinning faster and faster -- and obviously becomes very unsafe to approach.

In game terms, what happens is this: anyone who tries to attack a concentrated chain golem must first avoid the spinning chains. This becomes more difficult as the spinning increases. Failure leads to a painful collision with the chains, damage, and loss of concentration. So the most likely thing that will happen when you attack a concentration 3 chain golem is this:
The chain golem spins even faster, audibly slashing the air with its whip-like metal appendages.

Act> attack golem
The chain golem lashes out with a heavy iron chain, trying to stop the attack.

You attempt to duck under the whirling chains. You roll 5 + 5 (dexterity score) = 10 against a target number of 12, failing the dexterity check. One of the chains catches you with a loud smack, dealing 6 damage and breaking your concentration.

Rolling 2 - 2 (defender parrying) + 4 (tension) = 4, you do not overcome the chain golem's defence rating of 8.

Several of the wildly spinning chains lash out at you.

React>
Which is not an enviable position to be in. Indeed, you will have to rethink the way you approach this particular creature. Stopping it before it can get up to full speed is essential. If it does get up to full speed, it might be smarter to let it attack you then to try to break its concentration. Best of all would be to get an ability that allows you to damage someone (and thus break that person's concentration) without actually attacking that person -- and one of the other monsters I have made does grant you such an ability, although it is never guaranteed to work. So killing that (level 1) monster before attacking the (level 2) chain golem could be a good idea. Only, you'll lose any level 1 ability when you kill a level 2 monster and gain the corresponding level 2 ability, but not the other way around... so perhaps you might want to wait with killing that level 1 monsters. Decisions, decisions.

Overall, the tactics needed to defeat the chain golem are probably less interesting than those needed to defeat a basic monster: that is, it would be more fun to play in a world with only standard ATTACK monsters than to play in a world with only chain golems. But of course, that is not the point: the point is tactical diversity. And I think the chain golem certainly provides that.


Making things interesting

That is all very well, but we want our monsters to be even more interesting, and combat even more intense. So I have given the chain golem a special ability: once in a while, it will attempt to wrap one of its chains around your weapon, yank it out of your hand and send it flying across the room. While not necessarily leading to new tactics -- unless you have another good weapon, you should probably try to retrieve it -- it does spice things up a bit, and increases the unpredictability of the combat. Furthermore, it allows us to have the chain golem interact with its environment in interesting ways: at some later point in time, I intend to write a "when something is randomly thrown through a room" rulebook that could be invoked by the chain golem's disarm ability as well as other events in the dungeon; and that will allow the current location to intervene and have an effect on what happens. If the chain golem protects the narrow bridge over the lake of lava, you might want to consider fighting it without using your favourite weapon!

Another good future addition would be a probability for the randomly thrown weapon to hit and damage a third person in the location. Even if it only came up once in every several hundred games, the chain golem accidentally killing its own ally would be great.

In order to have such 'emergent' events, you need to write relatively general rulebooks that can be called by different events. If the chain golem is the only thing that can send an object flying, writing an entire rulebook for this eventuality is probably not worth it. But if it can happen more often -- well, then it obviously is. (The player throwing objects at an enemy? Certainly a possible action to be considered.)


Rewarding the player

Once the player has defeated a monster, he absorbs its soul. This gives a general stats increase, but also grants the player a passive or active power. In the case of the power of the chains, the player gets the ability to "lash". This is to attack the enemy as a reaction: i.e., to attempt to disrupt the enemy's attack by counterattacking, something that is usually not possible in ATTACK, and which everyone will love to be able to do.

Writing all of that, with the required prose, takes about 1600 words. Not too bad, actually, since I'm thankfully experiencing that everything I try to do fits into ATTACK very neatly (perhaps because I think like myself, but let's assume for my sake that it is because ATTACK is well-designed). The entire carry out rules for lashing are:
Carry out lashing:
    choose a blank row in the Table of Stored Combat actions;
    now the Combat Speed entry is a random number between 8 and 14;
    now the Combat Action entry is the action of the actor attacking the provoker of the actor;
    say "You will attempt to strike swiftly, before you are hit.".
In basic ATTACK that Table of Stored Combat actions only ever contains one action, and the fact that actions have a combat speed never makes a difference. But I put it in in case people wanted to write something like the lash action (or even more complicated things, involving more people and/or actions). Thank you, former me!

(In case you wonder: actions with a lower combat speed get carried out earlier; attacking has a standard speed of 10; so lashing has a 2.5 / 7 = 36% chance of happening before the attack.)


Additional things

Three monsters, two rooms, a couple of items: its not exactly going quickly, but we're getting there. I might put out an early alpha release when I have seven monsters and enough rooms to put them in, for those who are curious.

There was some talk in the previous thread about whether I should just disable saving or include my Permadeath extension. I'm certainly willing to do the latter if people prefer that. (Erik, I don't think your idea of autosave and autorestore will work, because you cannot force someone to overwrite their old save when they die, and I don't think the game can save without help from the user? Permadeath solves the problem in a somewhat more complicated manner.)

I'm finding that writing this game, and thinking about it, is both pretty exhausting and pretty fun.

Thursday, March 24, 2011

Dungeon design journal #3: design philosophy

With the basic system in place, the times has now come to think about content. In fact, I have already coded up two rooms -- one of which is the Entrance Hall, which doesn't do an awful lot. But before I dive into content creation, I should spell out my design philosophy, both to make it explicit for myself, and to get some early feedback.


Thematic background

The thematic background of the game will be sword & sorcery: gritty and violent fantasy that takes place in crumbling civilizations built on the ruins of even older empires. It is a world where wizard don't throw around fireballs and other flashy weapons of mass destructions, but cast curses that trap the soul or rot the body -- curses they have learned in a search for forbidden knowledge that left them more demon than human. It is a world where horrific monsters threaten mankind everywhere, but where no elves, dwarfs, orcs, trolls, faeries, or any of the other "races" of Fantasyland have ever been seen. It is a world where priests are not holy men who turn undead, but cruel butchers who sacrifice men to appease evil ancient gods. It is a world full of the wildest decadence and the deepest despair. It is, most of all and appropriately for a rogue-like game, a world where life is very cheap indeed.

High fantasy and character death have always been an uneasy union. If you are in the business of "wish fulfillment", as the Dragon Age developer on the PAX panel described his own job, you need a world where the player feels heroic, in control, and epically successful. If you're making a rogue-like, you do not.

Sword & sorcery is not an overused genre in computer games. There is a Conan MMORPG (which I have not played, and in fact, I have read almost no Howard), but as far as I can see that is about it. On the other hand, it does allow almost as wide a variety of locations, events and creatures as the degenerate "high" or "epic" fantasy that is overused in computer games.

In the end, given that I'm writing a random dungeon crawl, none of this is too important -- but I like having a vague thematic idea to work with.


Design philosophy

Core design goals. The core design goals of the game are tension, tactical depth, variation, and absence of grinding. The player should be on the edge of his seat all the time, because danger lurks everywhere; success must be a matter of making the right decisions; randomisation should be used to generate a large variety of tactical situations; and increased survival chance should never be a matter of taking more time.
Note that "grinding" is not just a term for things like killing thousands of identical zero-threat monsters, or doing a hundred Mephisto-runs in a game without permanent death in order to get that piece of armour you need. It also encompasses things like the "we rest until healed" and "I search for traps" mechanics of D&D, where slowing down the game session to do a risk-free activity is always the tactically optimal option.
Length. As stated in a previous post, I am envisaging a game that takes place in a small dungeon (say 10-15 rooms) and takes only a short time (say 10-30 minutes). This means that there can be more danger (every monster in Crawl or NetHack cannot be dangerous because of the length of the games), and it removes a lot of opportunities for grinding. However, an external file will be used to track how many games have been won, and new features for the dungeon will be unlocked as the player wins more games.

Fairness. Fairness is not a core design goal for this game. This is a game meant to be played in fifteen minutes. If a lightning elemental was randomly generated in the Tesla coil room (not an actual example from my game!) and no electricity resistance can be found -- tough luck, but you lose only a few minutes worth of play and can simply start again.

What I do want to minimise is "unfairness" that is "unfun": a game that kills you arbitrarily or leaves you optionless in the beginning. Even perfect play may lead to death, but reasonable play should never leave the player without a chance.

Hostile environment. I want the whole dungeon to feel hostile and dangerous. Not just the monsters, everything, including empty rooms and treasures. Partly through description, partly by actually making everything potentially dangerous. Also, we will not hold the player's hand. If she types "jump in lava" or "eat poison", the game will oblige her. None of the "That wouldn't be very smart." stuff.

Trade-offs will play a major role in the game. The basic combat actions already offer the player a tactical trade-off (you can concentrate to do more damage later... but you might be hit in the meantime). Using finite resources ("scrolls" and "potions" in many rogue-likes and RPGs) is always trade-off between greater chance of survival now versus greater chance of survival later. And I'd like permanent items to adhere to this philosophy as well: no "sword that is better than your current sword", but a "sword that is mostly better than your current sword, except". An important kind of trade-off is the temptation: offering the player a prize that can only be obtained by braving an optional danger. Rogue-likes often work this way. "I can run away from that ogre, but if I kill it instead, I would get enough XP to level up...". Many deaths are a result of giving in to temptation -- but many victories are as well. It is also thematically appropriate: the temptation of great riches is often a prime motivation of sword & sorcery characters, and it often leads to their untimely demise.

Surprise. I would like the game to contain a lot of surprising features that will keep even experienced players interested.


That is the theory. Now for the implementation. Comments are very welcome.

Tuesday, March 22, 2011

Dungeon design journal #2: further dungeon generation

After getting the basics of randomly generating the dungeon map in place, I spent some time cleaning up the code. This is a necessary step in any larger project: whatever you have written after several hours of obsessed coding may work, but it is almost certainly not pretty. Cleaning up the code can be as easy an rearranging it and adding headings, but more commonly also involves separation (any part of a routine that might come in useful elsewhere should be written as a stand-alone routine) and rewriting (of code that is either ugly or not as general as it could be).

One thing I tried to do this time is reducing the number of global variables I used -- using local variables for local properties is neater and less prone to strange bugs later. However, I don't think you can send local variables to rulebooks. You cannot, for instance, write "consider the monster scoring rules for (guy - a monster) at (place - a location)" and then use "guy" and "place" as local variables within all the monster scoring rules, like you can do for a routine. So you have to use global variables to send information to a rulebook -- right?

I also implemented a check on the generated map to see whether it is not too narrow in the beginning: we don't want the player to be stuck on a linear path at the start of the game which might be blocked by an obstacle he or she cannot overcome. I'm certainly not striving for total fairness, but some fairness is good; and we want the player to be able to make decisions.

My basic design idea at the moment is that there are five levels of monsters, levels 1 to 5. Every dungeon contains two monsters of levels 1 and 2, and one monster of each of the other levels. Killing the level 5 monster ends the game. (Obviously, the exact numbers can all be changed during play testing.)

When you kill a monster, your character absorbs its soul, which will heal you and grant you a set of powers specific to that monster. These powers will in general include simple statistics increases, but also more specific and fun abilities or resistances, and they will be more powerful when the level of the monster is higher. However, absorbing a level n soul will immediately destroy all level n and lower powers you already have. So if you have a level 2 power and kill a level 3 monster, you lose the level 2 power; but if you then kill another level 2 monster, you will gain its power without losing the level 3 power.

This should be tactically interesting because it generates a basic risk-reward problem: killing a higher level monster is easier when you have already absorbed the souls of lower level monsters; but you can only keep the souls of the lower level monsters for the next fight if you first kill the higher level monster. E.g., before taking on the final monster, you would ideally kill a level 4, 3, 2 and 1 monster in that order. But killing the level 4 monster without the help of having absorbed a level 3 soul is going to be quite difficult. Add to this the fact that different souls will help you more or less against specific monsters, and the player might face some hard tactical decisions even when he is just trying to decide in what order to defeat his enemies.

Of course, we'll need to see how it works out in practice.


By the way, I tried to think of a way to generate a name from this basic mechanic. Soulstealer and Souldrinker sounded too much like bad Michael Moorcock fan-fic, so I have gone a slightly more mystical route: the current working title is The Breaking of the Vessels.

Now a vague theme of mysticism gives me some basis for creating a set of locations, mechanics, monsters, and so forth, with a coherent feel; but I'm not sure it's going to be the easiest or most successful route. If anyone has a better idea, I'd love to hear about it. At all costs do I want to avoid the "throw in every fantasy trope you can think of"-feel that can be found in so many rogue-likes: I want something more coherent. Also, preferably not too clich├ęd. I'm very open to suggestions -- my head has been so preoccupied with the mechanical side of things that the fictional side has not yet received a lot of thought.


Getting back to the actual work, I implemented a system to distribute monsters across the map. Basically what I'm doing is that I sort the rooms by their distance from the Entrance Hall, and then put the strongest monsters farthest away. This ensures that all rooms are reachable (nothing can be beyond the final monster), and that the player can always get to the weaker monsters before he has to defeat the stronger ones -- although it is very possible that he could take on the stronger ones early on, because the maps resulting from my generation algorithm have a lot of branches.

There are, of course, also easy ways to specify that certain rooms cannot contain monsters; or that certain monsters are more likely to be found in certain rooms.

Finally, I put in a basic framework for "treasure" generation, but I think that's something I'd like to mostly leave to more specific code. I then wrapped everything into an extension and added ATTACK to my source code.

So at this point I have a game in which you get to walk through a random dungeon and fight the stock ATTACK monster under different names. Not quite awesome, from a gameplay perspective, but a good basis for further development.

Monday, March 21, 2011

Dungeon design journal #1: random dungeon generation

Would it enhance my productivity if I start a public design journal for my projects? That is one question I'm willing to answer by performing an experiment, and the other question is: will anyone be interested in reading these posts, or will they just clutter up Planet IF? The second is the more important one.

I am torn between two desires. On the one hand, I want to write a showcase for the ATTACK extension that is just good dungeon crawling fun. On the other hand, I want to write a piece that is important in terms of story or character or, well, anything artistic. I first considered some far-fetched ways of putting them together. I then told myself sternly that I had to make a choice. I have finally decided to just do both at the same time. Fail-proof strategy right? Anyway, here is the first design journal for what is going to be the unapologetically tactical game -- which I haven't named yet, so I'll call it Dungeon for now.

The basic idea was given to me by playing Desktop Dungeons: a small randomly generated adventure which should be playable in, say, 30 minutes (and certainly comes with permanent death and without undo); but winning the adventure will unlock new features that will be used the next time you play the game, while losing it will probably do nothing. So I am envisaging a game where as you win more games, more rooms, items, monsters and abilities will be added to the pool that is used for random generation, constantly expanding the tactical possibilities and depth of the game. (I would use an external file to keep track of what has been unlocked.)

Obviously, the framework for a combat system is already available: ATTACK. But I also need a framework for random dungeon generation. Once these two are in place, writing the game will "just" be a matter of adding content.

So, random dungeon generation! It seemed logical to start with generating the actual lay-out of the rooms first, and add everything else (including "doors") later. So I have spent today implementing an algorithm that creates a dungeon by:

  1. Putting a room called "Entrance Hall" at location (0,0,0). This room is now "placed".
  2. Choosing a random "placed" room, and trying to put a random "unplaced" room in one of the six cardinal directions (n,s,w,e,u,d). Create a two-way passage between the two rooms.
  3. Repeating step 2 until enough rooms have been placed.
  4. Checking whether there are pairs of adjacent rooms without a connection, and randomly making or not making a connection between them.

Steps 1-3 create a three-dimensional branch starting from Entrance Hall, and step 4 makes circular connections possible.

Now this is all very well, but we want more control over the lay-out of the dungeon. For instance, it would make no sense for a basement to be above ground level. We might want to group thematically related rooms together. And perhaps some rooms need to be dead ends, or passages between at least (or exactly) two other rooms. And so on. We need random generation, but we also want to be able to easily impose structure.

If there is one thing I have learned from writing ATTACK, it is that if you have open-ended design ideas ("I'm not sure what kinds of structure I might want to impose"), you should immediately build a system that is as general as possible. So I created three rulebooks:
  • The placement possible rules ask whether a certain room could be placed at the location currently under consideration. (The cellar, for instance, will say no if the z-coordinate of the location is not negative. It must be below street level.)
  • The placement scoring rules check how likely it is for a room to be placed at the location currently under consideration. (This can be used to make thematically related rooms more likely to be next to each other, for instance. I'm currently only using it to make the underground rooms more likely -- than other rooms -- to appear under ground.)
  • The additional placement rules run after a room has been placed, and can be used to implement further restrictions on the map. (The chasm, for instance, makes sure that it is always placed in a straight line between exactly two rooms -- serving as a barrier between them, except that I have not implemented any barrier. If the drawing room or the quartering room is placed, the other is immediately placed next to it. Okay, that is a pretty bad joke, but this is just a testing prototype.)
It all seems to work fine. One of the great joys of writing IF is the joy of programming: tackling a problem, and then seeing it work. I could generate stuff like this for the rest of the evening:
* down of Entrance Hall (0, 0, 0) is Kitchen (0, 0, -1).
* east of Entrance Hall (0, 0, 0) is Ballroom (0, 1, 0).
* west of Entrance Hall (0, 0, 0) is Quartering Room (0, -1, 0).
* Placed Drawing Room south of Quartering Room.
* east of Ballroom (0, 1, 0) is Alchemical Laboratory (0, 2, 0).
* down of Kitchen (0, 0, -1) is Basement (0, 0, -2).
* south of Alchemical Laboratory (0, 2, 0) is Chasm (-1, 2, 0).
* south of Chasm (-1, 2, 0) is Dark Shrine (-2, 2, 0).
* up of Dark Shrine (-2, 2, 0) is Chapel (-2, 2, 1).
* east of Basement (0, 0, -2) is Crypt (0, 1, -2).
* down of Ballroom (0, 1, 0) is Cellar (0, 1, -1).
* Adding connection between Entrance Hall and Ballroom.
* Adding connection between Entrance Hall and Quartering Room.
* Adding connection between Ballroom and Entrance Hall.
* Adding connection between Alchemical Laboratory and Ballroom.
* Adding connection between Chasm and Alchemical Laboratory.
* Adding connection between Drawing Room and Quartering Room.

Well, maybe not the rest of the evening, but it still so much fun to watch the  machine you have created run and work.

(The reader may notice that all connections added in this example already existed. This is because "if A is mapped north of B" compiles, but "if A is mapped way of B" apparently does not, even where "way" is a direction that varies. Which means I cannot easily test whether a connection already exists. Not a big problem right now, because there is nothing wrong with remapping things that are already mapped. But if someone knows how to formulate this if-statement in a way that does compile, that would be great.)

I also like this little command I put in to make exploration easier:
>explore
You have not yet explored:
 - the down exit of the Library (which lies north from here)
 - the south exit of the Chapel (where you currently are)
Although I know it will become a pain to rewrite it when I add locked doors, monsters, chasms, or anything else that might make going somewhere in a straight line not the most feasible thing. Also, I suspect that the command currently assumes total knowledge of the map. But there is an extension by Emily Short that I think I can change to suit my needs.

Tuesday, March 01, 2011

IF Theory Reader: "Crimes against Mimesis" by Roger S. G. Sorolla

So, after a decade the IF Theory Reader has finally appeared. Great news, obviously; but, as the editor (Kevin Jackson-Mead) warns us, it may "not necessarily represent the state of the art in interactive fiction theory". IF ten years ago was different from IF today. Which is not to say that we cannot learn anything from these essays, of course, only that we have to approach them with a certain caution. (As well as with a certain laughter and a certain step of the dance, as always.)

The first article in the reader is the famous Crimes against Mimesis, by Roger Sorolla. For the greatest part, it reads as a discussion of what was wrong with old-school adventure games:
  1. Objects that make no sense in the fictional context, but are just there to enable the player to solve puzzles.
  2. Different literary genres mixed together without rhyme or reason.
  3. Puzzles that have no connection with the fiction -- especially gratuitous mazes, riddles, and so on.
  4. The lock-and-key syndrome, where the whole world is ordered by a one-on-one correspondence between movable objects and puzzles to be solved.
  5. Shallow NPCs that are obviously just a puzzle that talks.
  6. Charaterisation of the PC.
I will come back to the sixth point in a minute; but the other five are basically things that we have solved. As puzzle solving has become less important, problems 1, 3 and 4 have become less prominent. Expectations for coherency of story and responsiveness of NPCs have soared, which has taken care of 2 and 5. In other words, it seems as if Sorolla's complaints were widely shared among the community, and the medium has been developed to the point where you cannot get away with committing any of these crimes.

Sorolla's proposed solutions to the lock-and-key problem bear additional scrutiny. He suggest that we (a) have solutions require more than one object; (b) have objects be necessary for more than one problem; (c) make sure that problems have more than one solution; and (d) incorporate irrelevant objects and problems. This is good advice. But it is also advice that doesn't address the real problem, which is the whole "here is a problem, now go and find the right object"-design of puzzles. Let's look at the nominees for the "best individual puzzle" XYZZY of this year (mostly free of spoilers):
I didn't manage to get the lighter from Kai, so I cannot comment on that puzzle. What I want to point out is that the other puzzles all solve the lock-and-key problem, but not by creating more complex relations between objects and solutions. They break free of the entire design strategy that led to the lock-and-key problem by testing the player's understanding of the game world. This is especially clear in the case of The Warbler's Nest, where the decision is everything and the execution is nothing. Oxygen requires us to grasp the physical and political situation on the ship, and our own role in that situation; the execution is not trivial, but it is not the main puzzle. The 12:54 to Asgard has one million objects, but repairing the roof is more a test of daring than a real puzzle. Saving Dr. Ephart requires some object manipulation, but far more important is figuring out how the plot of One Eye Open works. And Aotearoa gives us an elegant puzzle which only requires us to understand an NPC, and literally leaves it up to us which object we want to manipulate. The solution to the lock-and-key problem, then, is not having more complex locks and keys; it is dispensing with locks and keys (as central elements of the puzzle) altogether.

In this context, it is also worth commenting on Roger Sorolla's claim that one way to solve the problem is to have 'false' solutions, as long as these are well-clued; and that:
[a] good example of a well-clued “wrong” alternative solution would be feeding a hungry swine with a rare string of pearls that’s needed later on, when the beast will just as gladly wolf down a handful of acorns.
A contemporary reader would be very dismayed to find out that the rare string of pearls she had fed to the swine was needed later on in the story! As our tolerance for unwinnable situations has decreased, so has our perception not just of what fair game design is, but also of what counts as a clue.

The most interesting part of the piece, in my opinion, is that about the player character. Some of Sorolla's discussion is about the relative virtues of the everyman and the strongly characterised protagonist; surprisingly, he weighs in on the side of the everyman, because this helps "identification".
Such a protagonist would be experienced more as a “he” or “she” than as an “I,” robbing the second-person narrative of its potency, and character identification would suffer at the expense of character definition.
The idea here seems to be that IF gains strength from the player identifying with the PC; and that such identification becomes problematic when the PC is evidently not the player. I doubt this is the case in general; but there is probably some truth here. Perhaps the important thing for identification is that the player's decision equal the protagonist's decisions? We identify with whatever the character may be as long as what we decide is what the character decides. (This theory receives support from the fact that in games like LASH and Fail-Safe, we identify with the 'commander', even though he/she is only a very small part of the fiction.)

Sorolla also makes a distinction between the "Game Protagonist" and the "Story Protagonist". It is the former who walks into a full kitchen and notices that only the cab opener is "relevant" and should be taken in order to solve problems later; it is the latter who walks into the kitchen worried sick about the fate of her crazy uncle Zarf who mysteriously disappeared last week. On the one hand, this is a distinction we have been making less important by having less puzzles and having better integration of puzzles and story; on the other hand, it is a distinction we silently accept as a gameplay convention. Perhaps we mentally filter out some of the interaction with a work of IF as "not really part of the story", for instance, most inventory management?

Not all of it is relevant anymore, but Crimes against Mimesis remains an interesting article.