As I review bug reports for the Inform6 Standard Library, I have one that complains that WEAR
and DISROBE
do not allow for the player to wear or doff multiple items at once. Is there a historical reason for this? Is it a good idea to allow for actions like WEAR ALL
, WEAR HAT AND COAT
and TAKE OFF HAT AND COAT
?
Wearing and disrobing dress is one entry point into the dark realm of creeping featurism⌠(I read it on DM4 or CoA, donât remember now which) so, generally, moderation in implementing wearing was (intentionally ?) encouraged.
But one puzzle I fondly remember is one about perfectly disguising as uniformed deliverymanâŚ
OTOH, Iâm toying with a concept I call âmoonmist dressâ, that is, choosing a dress instead of a favorite colour at start (pls donât start a mimesis debate on MoonmistâŚ)
Best regards from Italy,
dott. Piergiorgio.
Usually complicated clothing and undressing mechanics only figure in for adult games, and most of those authors are familiar with creating their own systems with overlapping clothing layers and specifically exposed and unexposed anatomy. There is a very complicated layered clothing example in the documentation that usually serves as the template.
Most non-AIF usually either disregards physical clothing completely, assuming the player is dressed appropriately through the entire game and only wearing special items like the âamulet of invisibilityâ or âthe ring of confidenceâ, or often will implement complete outfits, say if a player has to dress differently for work or social activities.
Personally I think clothing mechanics can be very tedious in games that arenât about making a fashion statement as gameplay. When Iâve done it I have made UNDRESS or DISROBE mean âtake off everythingâ in sequence, and TAKE OFF [GARMENT] do it piecemeal. Usually itâs easier to implement full outfits as one garment instead of separate trousers, underwear, undershirt, blouse, skirt, left shoe, right shoe, left sock, etc.
I recommend making it easy as possible for the player if youâre doing an adult game or an implementation of The Devil Wears Prada and clothing combinations are essential to the plot!
Itâs worth noting that the only verbs in the standard library that accept plurals are TAKE, DROP, PUT, and REMOVE (in the obscure sense of âremove treasures from caseâ.)
I donât remember if the the DM4 discusses the reasoning behind this. But Iâd say it comes down to multiple actions being inherently a bit fragile. Itâs hard enough to plan your game logic when only one thing can happen in a turn; multi-object actions require extra planning, plus (really) some extra logic to decide when to interrupt the sequence of actions. Inform doesnât really give the author enough support to make this routine. So the library takes the safe route and keeps everything singular except for the few actions needed for routine inventory juggling.
I looked up, and is in ch. III para 11:
ⲠA risk of providing clothing for the player is that itâs hard to resist the lure of realism. A tweed jacket would add some colour to âRuinsâ. But if a jacket, why not plus-four trousers, an old pair of army boots and a hat with a mosquito net? And if trousers, why not underwear? What are the consequences if the player strips off? Too much of this kind of realism can throw a game off balance, so: no tweed.
Best regards from Italy,
dott. Piergiorgio.
The standard library made some very poor choices in the early days and most of us have been devising workarounds for this ever since. In the case of clothing, the property name itself was a bad choice. It should have been wearable
, as not everything that can be worn is clothing
. For example, you can wear a ring and a backpack, but these are not clothing.
I suspect that the lack of support for WEAR ALL and REMOVE ALL is because of the layering that sometimes comes into play with clothing as aluded to in @Piergiorgio_d_erricoâs quote from the DM4. To take the simple example of a shirt and a jacket, if you start topless, you can wear the shirt or the jacket and you can put the jacket on over the shirt, but you canât put the shirt on over the jacket. The author currently has a choice on how to handle this:
- You can allow it regardless, even though it doesnât make sense in real life.
- You can do an implicit removal of the jacket, then wear the shirt and tell the player â(first removing the jacket)â.
- You can tell the player that the shirt wonât fit over the jacket.
When doing a (hypothetical) WEAR ALL or REMOVE ALL, you have no control over the order in which clothing items are worn or removed. If the author has before rules to account for the 2nd or 3rd cases above, you could get a response like this:
>WEAR ALL
Jerry can: You can't wear that.
Jacket: You put on the jacket.
Shirt: (first removing the jacket)
You put on the shirt.
And youâre left with an unworn jacket.
There will be cases where the sequence is important to the game and may be part of a puzzle, so I think, in this case, it is better to keep it simple unless youâre prepared to build some smarts into the library.
In retrospect, maybe you could allow it and let the authorâs ChooseObjects
routine decide what can be worn or removed. Something like (untested):
[ ChooseObjects obj code;
if (code == 2)
{
! Stage 1: Disambiguation stuff
}
! Stage 2: Processing an "all"
if (obj has scenery or concealed or static or animate)
return 2; !Force exclusion
if (action_to_be == ##Wear && obj notin player && obj has clothing)
return 1; !Force inclusion
if (action_to_be == ##Disrobe && obj in player && obj has worn)
return 1; !Force inclusion
return 0; !Accept parser's decision
];
EDIT: I had ##Remove
in the above routine. It should have been ##Disrobe
. Now corrected.
Do I need to do anything to the library to make this easier?
I have written a little test program. I have added one non-clothing item (a jerry can) and six clothing items: shirt, singlet, pants, underpants, shoes and socks. I have assumed that the shirt goes over the singlet, so you canât wear or remove the singlet if the shirt is already worn. Similarly, you canât wear or remove the underpants if the pants are worn and you canât wear or remove the socks if the shoes are worn. In addition, you canât wear or remove the pants or underpants if the shoes are worn. These are all pretty reasonable assumptions and are handled by before
routines.
As wear and remove clothing are normally defined with held
tokens in the grammar, I extended the grammar with a multiheld
token.
After a lot of experimenting, I had to use a ChooseObjects
routine to forcibly include or exclude items when processing an ALL. The end result is about as good as youâre going to get. WEAR ALL and REMOVE ALL work as expected, both with and without implicit actions, it doesnât try to wear or remove anything stupid and the before
routines are honoured. Obviously, if you donât have any before
routines, there are no restrictions and you can wear and remove anything that has a clothing
attribute.
The code is included below. As to whether you need to do anything to the library, you could perhaps replace the held
token with the multiheld
token and make sure that the libraryâs WearSub
and DisrobeSub
handle the conditions tested for in ChooseObjects
so that a custom ChooseObjects
is not necessary. Otherwise, do nothing and let authors do it manually as Iâve done here.
Constant Story "Wear All";
Constant Headline "^An interactive experiment^^";
Include "parser";
Include "verblib";
[ Initialise;
! no_implicit_actions = true;
location = test_lab;
"This is a test of wearing and removing multiple objects in the one command, such as WEAR SHIRT AND PANTS or REMOVE ALL.";
];
Object test_lab "Test Lab"
with
name 'test' 'lab',
description "You're in the test lab.",
has light;
Object can "jerry can" test_lab
with
name 'jerry' 'can',
description "It's a WW2 vintage jerry can.",
has;
Object shirt "shirt" test_lab
with
name 'shirt',
description "It's a very colourful Hawaiian shirt.",
has clothing;
Object singlet "singlet" test_lab
with
name 'singlet',
description "It's a white singlet.",
before
[;
Disrobe, Wear:
if (shirt has worn)
"You'll have to take the shirt off first.";
],
has clothing;
Object pants "pants" test_lab
with
name 'pants',
description "It's a cheap pair of grey-brown pants that you bought from Lowes.",
before
[;
Disrobe, Wear:
if (shoes has worn)
"You'll have to take the shoes off first.";
],
has clothing pluralname;
Object underpants "underpants" test_lab
with
name 'underpants//p',
description "underpants//p",
before
[;
Disrobe, Wear:
if (pants has worn)
"You'll have to take the pants off first.";
if (shoes has worn)
"You'll have to take the shoes off first.";
],
has clothing pluralname;
Object socks "socks" test_lab
with
name 'socks//p',
description "It's a pair of woollen socks.",
before
[;
Disrobe, Wear:
if (shoes has worn)
"You'll have to take the shoes off first.";
],
has clothing pluralname;
Object shoes "shoes" test_lab
with
name 'shoes//p',
description "It's a pair of leather shoes.",
has clothing pluralname;
[ ChooseObjects obj code;
if (code == 2)
{
! Stage 1: Disambiguation
if (action_to_be == ##Take && obj notin player)
return 1; !Appropriate
if (action_to_be == ##Drop && obj in player && obj hasnt worn)
return 1; !Appropriate
return 0; !Inappropriate
}
! Stage 2: Processing an "all"
if (obj has scenery or concealed or static or animate)
return 2; !Force exclusion
if (action_to_be == ##Take && obj ~= player && obj notin player)
return 1; !Force inclusion
if (action_to_be == ##Drop && obj in player && obj hasnt worn)
return 1; !Force inclusion
if (action_to_be == ##Wear && obj hasnt clothing)
return 2; !Force exclusion
if (action_to_be == ##Wear && obj hasnt worn)
return 1; !Force inclusion
if (action_to_be == ##Disrobe && obj has worn)
return 1; !Force inclusion
if (action_to_be == ##Disrobe)
return 2; !Force exclusion
return 0; !Accept parser's decision
];
Include "grammar";
Extend 'remove' first
* multiheld -> Disrobe;
Extend 'wear' first
* multiheld -> Wear;
End;
Actually, I think REMOVE ALL would work. Every object has a linked list of children. When a new child is added (e.g. an object is worn), it is inserted at the front of the list. Thus, when traversing the children (e.g. as part of an object loop due to ALL), they will be encountered in reverse order, compared to how they were added. So as long as the player is prevented from wearing the socks after the shoes, REMOVE ALL will never attempt to remove the socks before the shoes.
The point about WEAR ALL remains.
If you do a WEAR ALL immediately followed by a REMOVE ALL, I think youâre right, but if you remove individual items in order to wear the things that failed when you did a WEAR ALL, and then wear the things that you just removed until youâre wearing everything and then do a REMOVE ALL, it fails again on certain items depending on the structure of the tree. You can try it in the little demo game I posted. Itâs standalone, so you can copy, paste and compile.
You then remove the * multi -> Take from the verb remove, otherwise it conflicts with * multiheld -> Disrobe;
Verb 'remove'
* multiheld -> Disrobe
* multi -> Take
And you donât put multiheld to the verb disrobe:
Verb 'disrobe' 'doff' 'shed'
* held -> Disrobe;