OK, you provided two different modes as examples – each has its own set of hassles. The “using two keys at once” approach seemed more interesting and perhaps slightly friendlier to new players, so here’s an example using that.
"Two Keys"
A key is a kind of thing.
The player carries a key called a red key. The player carries a key called a yellow key. The player carries a key called a blue key.
The player carries an edible thing called a watermelon.
Foyer is a room.
A two-lock door is a kind of door. A two-lock door has a list of keys called matching key set.
A closed locked two-lock door called an orange door is east of Foyer. The description of the orange door is "This sliding door has not one but two keyholes." The matching key set of the orange door is {red key, yellow key}.
Prize Room is east of the orange door.
Unlocking it dually with is an action applying to two things. Understand "unlock [something] with [things preferably held]" as unlocking it dually with.
The announce items from multiple object lists rule does nothing when current action is unlocking something dually with.
To slide is a verb.
Suppress further keys is a truth state that varies. Multi-key spacing adjustment made is a truth state that varies.
Before reading a command:
now suppress further keys is false;
now multi-key spacing adjustment made is false.
Check unlocking it dually with:
if the number of entries in the multiple object list is less than two:
now suppress further keys is true;
say "It looks like you need to use two keys at once on this door." instead;
if the number of entries in the multiple object list is greater than two:
now suppress further keys is true;
say "That's more keys than there are keyholes." instead.
Check unlocking it dually with:
repeat with checked item running through multiple object list:
if checked item is not a key:
now suppress further keys is true;
say "[The checked item] can't be used as a key!" instead.
Check unlocking it dually with:
repeat with alleged key running through multiple object list:
if alleged key is not listed in the matching key set of the noun:
now suppress further keys is true;
say "[The alleged key] doesn't seem to fit into either keyhole." instead.
Check unlocking it dually with when suppress further keys is true:
unless multi-key spacing adjustment made is true:
now multi-key spacing adjustment made is true;
say "[conditional paragraph break]";
stop the action.
Carry out unlocking it dually with:
now the noun is unlocked;
now the noun is open;
now suppress further keys is true.
Report unlocking it dually with:
say "The [multiple object list] [slide] smoothly into the keyholes, and a double twist unlocks [the noun]. It swings open."
Check unlocking a two-lock door (called stubborn door) with a key (called attempted key):
if the attempted key is listed in the matching key set of the stubborn door:
say "[The attempted key] fits into one of the keyholes and turns easily, but the door only opens halfway, leaving a gap too small for you to wriggle through. As you remove the key, [the stubborn door] closes again." instead;
otherwise:
say "You try [the attempted key] on both keyholes, but it doesn't seem to fit either." instead.
Every turn when the player is in Prize Room:
end the story saying "Well, that was educational."
test me with "open door / unlock door with blue key / unlock door with red key / open door / unlock door with yellow key / open door / unlock orange door with blue key and watermelon / open door / unlock orange door with red key and blue key / open door / unlock orange door with red key and yellow key / open door / e"
There’s probably more work to do handling situations that were not thought out for the example above, but this should get you started. Also, there are some niceties (like names for rules) that are left out, and that you should probably add.
Some of the rules are a little odd-looking because of some fighting that needs to be done with the parser about how to handle a multiple object list. This approach is a bit crude, but it looks OK to the player. Someone smarter than me might be able to show how to rewire handling of actions repeated across a multiple-object list more elegantly. Matt W’s extension “Action on Groups” might also be useful, but I’m not familiar with how it works.
Allowing use of individual keys sequentially would require a totally different approach, potentially involving modeling individual locks. Getting both methods to work in the same game would involve gutting the example above to ensure that the same lock logic is used regardless of the player’s chosen approach.