A world of object attributes

Uto
9 min readSep 16, 2022

--

In this article we will explain some ways to use object attributes (AKA object flags) in DAAD. To properly understand it, you will need to have some knowledge of The Quill, PAW or DAAD programming.

DAAD advantages

When someone asks which are the advantages of DAAD language over the old PAW language, there are four main points to consider:

  • Indirection
  • Object attributes
  • SKIP condact
  • Main loop is not fixed

From all of them, it’s object attributes the one that uses to be the most underused. I’ll try to propose some ways to use attributes, so you start to understand them, and can think on more options.

DAAD Ready

We will be using DAAD Ready, a suite for Windows that includes all you need to create games with DAAD easily. You can get it here.

If you don’t use Windows, I’ve been told DAAD Ready can be used with Wine, but it requires a 64 bit Wine environment. Also, you can just get DRC, the new DAAD compiler, and use BLANK_EN.DSF file included in the DAAD Ready zip file as a start game (TOOLS/DRC folder).

So what are object attributes?

Using PAW, when you define an object, aside of vocabulary words, you define the initial location, the weight and whether it’s a container, a wearable item, or both. Using DAAD, you also have the object attributes, a set of 16 yes/no flags that can be assigned to any object, just like the one that says if the object is the a container, or wearable, just 16 more yes/no flags like those two ones.

But what do those 16 flags mean? Unlike the container or wearable flags, these sixteen flags don’t have a specific use, in fact, is up to you to decide what they are for.

Let’s go to the folder where we installed DAAD Ready, double click MSDOS.BAT, choose english and run the game. Exit game and edit TEST.DSF file (a new file in your DAAD Ready folder), then have a look at the code in the /OBJ section:

/OBJ    ;Object Definitions;obj  starts  weight    c w  5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0    noun   adjective;num    at/0      CARRIED 1       _ _  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _    TORCH  _

As you can see, there is the object number first, followed by initial location (CARRIED), then comes the weight, and the the “carried” or “worn” flags. After that there are 16 more underscore characters. Underscore or “N” means that specific flag is not set, and Y means it is set. As you can see the flags are numbered from 15 to 0 in the comment above (well, actually 15 to 11 are showing also 5 to 1 but you can see the first flags is #15 and last one is #0).

Let’s change last flag from “_” to “Y”. Then go to vocabulary and add a new verb “TEST 200 verb”, and finally go to PROCESS 5, the response table, and add the following code:

> TEST _
WHATO
HASAT
0
MESSAGE "Object flag of current object is enabled"
DONE

This makes, when user types TEST, first make the search of current object identified by the noun in the sentence (if any) be set at several system flags (WHATO), which is required so HASAT later can check if the currently referenced object has its #0 attribute set. Thus, if you run the game, and type “TEST TORCH” you would get the message “Object flag of current object is enabled” in screen. But if you just type “TEST” then there is no referenced object, and HASAT will fail (you get the “I can’t do that” message).

Please add the following just below:

> TEST _  
WHATO
HASNAT
0
MESSAGE "Object flag of current object is disabled"
DONE

And also add a new object in the /OBJ section:

/1      CARRIED 1       _ _  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _    KNIFE  _

Then the object text in the /OTX section:

/1 "A knife"

And finally the noun in he vocabulary:

KNIFE   101     noun

When you have done that, you can run the game again, and check the difference if you type TEST TORCH or TEST KNIFE. The second doesn’t have attribute #0 set, so the response is different.

So now you know how to set an attribute for an object and check from code whether it’s active (HASAT) or not (HASNAT).

But how can I use that?

Ok, first you need to know what each attribute means. Unlike the container and wearable attributes, these ones are free to use, but you need to decide what are they for. For instance, you can decide attribute #0, the one set in the torch, means “canBurn”, then if the player types “Throw torch” and he is at the stable, you can make the stable burn, while if what the player throws is the knife, nothing happens.

Let’s change the location 1 description at the LTX section to:

/1 "I'm at a stable. A road leads north."

Then let’s also add verb “THROW” to vocabulary:

THROW 201 verb

and finally, this code on top or process 5:

> THROW _
AT 1 ; at the stable
WHATO
HASAT
0 ; object burns
MESSAGE "There's fire in the stable! You try to rush out but the ceiling fastly collapses and.. well, you're dead."
END
> THROW _
AT 1
SYNONYM DROP _

If you run the game now, you can throw the knife harmlessly at the stable, but you can’t do the same with the torch.

But, isn’t it just easier to check if you are throwing the torch and act consequently? Yes, it is, if only one object has an specific attribute, then it makes no sense to use it like this, but what if there are 4 objects in your game that can set the stable on fire? Let’s say aside of the torch, you have an oil lamp, an lit match, and a burning fire magic gem. Without attributes, you would have to check for all of them, with them, the same entry handles them all, whereas all of them have attribute #0 set.

Let’s add a new object to the OTX, OBJ and VOC sections:

(voc)
GEM 102 noun
(otx)
/2 "A burning magic gem"
(obj)
/2 CARRIED 1 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Y GEM _

Make sure the attribute #0 is set for the gem. Then try again (no code added at process 5).

You can also test activating the knife’s attribute #0 and you’ll see the knife will burn the stable too, if thrown.

Multiple attributes

An object can have more that one attribute. We have used attribute #0 to control if the object can burn other things, but we could use, for instance attribute #1, to handle if the object is a weapon. In this case we could set attribute 1 for the knife (and well, maybe for the torch), like this:

/0      CARRIED 1       _ _  _ _ _ _ _ _ _ _ _ _ _ _ _ _ Y Y    TORCH  _/1      CARRIED 1       _ _  _ _ _ _ _ _ _ _ _ _ _ _ _ _ Y _    KNIFE  _/2      CARRIED 1       _ _  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Y    GEM  _

As you can see, the torch has now set both canBurn and isWeapon attributes, the knife just the isWeapon one, and the gem only the canBurn one. You can add code that checks if it’s a weapon when the player tries to brandish it, and if it burns in other cases. There may be even one case where you need an object that burns and is a weapon for a specific action, you have to check both attributes then (HASAT 0 HASAT 1).

Some attribute use suggestions

So what can I use attributes for? This is a list with some ideas:

  • CanBurn -> if object can burn other things
  • ProvidesLight -> if object provides light
  • Weapon -> if object is a weapon
  • Food -> if object is edible/drinkable
  • Scenery -> if object is a scenery object, so you can have standard response for all scenery objects
  • Radioactive -> what if your game happens in a post-nuclear-war environment? You can set the flag into the radioactive items.
  • NPC -> to mark the object is not an object, but a “Non player character”, then you can add standar responses to actions like “TAKE XXXX” so when XXXX is a NPC, your response is something like “That wouldn’t be very polite, not good manners”

Also, if the object is actually an NPC, you can use other attrubutes to create his/her personallity:

  • isHostile -> whether will be attacking the player or not
  • isStrong -> whether is strong or not, so can perform certain actions if asked by the player
  • hasMagic -> whether can cast spells or not
  • etc.

Other ways to use attributes

So far we have checked for object attributes when an action is done with a specific object, we check the object specified by the player, but there are other ways to use them:

  • Imagine the player has to go through a small crack in a cave. We can check for all objects carried or worn for one with a isBig attribute, and make the player fail to go through.
  • Let’s go back to radioactivity: we can check every turn if the player is carrying any radioactive items, and increase the value of a flag 1 per radioactive item, and make the player die when he has been carrying radioactive items for several turns.

Looping though object list is something that will be explained below, but first let’s talk about readability:

Readability

So far we have used HASAT 0 and HASNAT 0 to determine if attribute #0 is set or not. We know attribute #0 means “can Burn”. But the code, when HASAT 0 is used, is not very readable and will be hard to understand once a few months have passed and you come back to it.

An easy way to improve readability, is using constants, of course. Let’s go to the beginning of our DSF file, and add the following:

#define canBurn 0
#define isWeapon 1

Then let’s change the “throw” code to this:

> THROW _
AT 1 ; at the stable
WHATO
HASAT
canBurn
MESSAGE "There's fire in the stable! You try to rush out but the ceiling fastly collapses and.. well, you're dead."
END

Isn’t it clearer now and easier to remember?

We are not using isWeapon anywhere, we let you try to think uses of the “isWeapon” attribute.

Object loops

Sometimes, as said above, we don’t need to check for a specific object attribute, but from any object which is present, worn, carried, etc. Let’s see how to check all objects for an attribute. We will use another two DAAD nice features, the SKIP condact and indirection.

Let’s first add a new process, proces 7, at the end of the file (just before the /END):

/PRO 7> _ _
CLEAR 100
> _ _
CARRIED @100
SETCO @100
HASAT canBurn
DONE
> _ _
PLUS 100 1
GT 100 LAST_OBJECT
NOTDONE
> _ _
SKIP -3

Then, lets’s change the two old entries we had for “TEST _” to this:

> TEST _  
PROCESS 7
ISDONE
MESSAGE
"There is an object that can burn"
DONE
> TEST _
MESSAGE "There is no object that can burn"
DONE

What we are doing here is checking if there is any object carried that has the “canBurn” attribute. The code in process 7 loops over all objects, and in case there is one that has the canBurn attribute, ends the process with DONE. Otherwise the loop continues until last object and ends the process without “done” status. In process 5, just after the process “done” status is checked with ISDONE condact, so we know if there was any item that can burn in our inventory. See the output:

As you can see, while we have the torch or the gem in our inventory, the code detects an object that can burn in it, but when oly the knife is left, it doesn’t.

You can use code like this to implement the “big items and the cave crack” feature, or the “radioactive items” one. In this last case you just have to add an entry in process 4 which at every turn checks if there is radioactive items in the inventory, and increases another flag that leads to player death when it reaches some specific value.

Well, that’s all folks, I hope this article has helped you to understand the object attributes in depth. Now is time for you to think what to use them for.

--

--

Uto

Developing indie interactive fiction and IF engines since 1984