Any physical object can and usually does have properties, which are general purpose storage containers for values. Common ways to set properties include the +setprop command, Merry's Set() function, and the <set-property> SAM tag. Properties are also copied into a newly spawned object from its ur-parent's InitialProperties.
The system supplies a set of properties that are always present without being explicitly set. These are called derived properties because their value tends to be computed rather than just fetched from storage. For example, we might export a property "skill:average" which, when read, computes the average of all the player's skills, and returns that for the value.
When writing to a derived property, similarly we do not just copy the raw data into a table somewhere, but rather execute some sequence of instructions associated with that property. For example, we might have a property base:environment which indicates the current environment of the object: setting this property to another value effectively becomes an order for the object to move into the given environment.
Thus the generalized notion of properties, both derived and otherwise, becomes a very powerful one, capable of exporting most of the functionality a developer needs to make their objects interact in complex ways.
What follows is a table of existing derived properties for physical objects. All these properties can also be fetched with ":local" appended at the end. This suffix tells the system to ignore the ur-parent chain and fetch the object's local value. For example, Zell's "base:strength" is 10.0, but "base:strength:local" is 1.0.
A recent addition are methods which are low-level function calls exported to the scripting environment. These are used when more parameters need to be part of a set/query operation than derived properties can properly encapsulate, or when the parameters are binary (e.g. object pointers). A table of existing methods follows the tables of derived properties.
base properties
Local | Property name | Access | Type | Description |
---|---|---|---|---|
base:gender | RW | int | object's gender | |
base:possessive | RO | string | possessive pronoun e.g. 'his' | |
base:objective | RO | string | objective pronoun e.g. 'him' | |
base:pronoun | RO | string | basic pronoun e.g. 'he' | |
base:genderstring | RO | string | gender string e.g. 'male' | |
X | base:maxfatigue | RW | float | object's max fatigue |
X | base:strength | RW | float | object's strength |
base:possessor | RW | object | object possessing us | |
base:possessee | RW | object | object possessed by us | |
base:actualmass | RO | float | object's perceived mass | |
base:actualdensity | RO | float | object's perceived density | |
base:actualcapacity | RO | float | object's perceived capacity | |
base:actualvolume | RO | float | object's perceived volume | |
base:minimumvolume | RW | float | object's minimum volume | |
base:urparent | RW | object | object's ur parent | |
base:firsturchild | RO | object | first object in ur-child linked list | |
base:nextursibling | RO | object | next object in ur-sibling linked list | |
base:previousursibling | RO | object | previous object in ur-sibling linked list | |
base:objectname | RW | string | object's name woe or (fallback) base name | |
base:scriptrunner | RW | boolean | does this object receieve witness script events? | |
base:environment | RW | object | object's environment | |
base:inventory | RO | object * | object's inventory | |
base:proximity | RW | NRef | object's proximity | |
base:holder | RO | object | object's volitional super-environment | |
base:deep-inventory | RO | object * | object's recursive inventory | |
base:proximates | RW | object * | objects proximate to object | |
base:offered-to | RO | object | object we're being offered to, if any | |
base:offered-by | RO | object | object we're being offered by, if any | |
base:incoming-offers | RO | mapping | complex: offerer -> objects offered us | |
base:outgoing-offers | RO | mapping | complex: offeee -> objects offered them | |
base:worn-by | RW | object | object's wearer (wielded-by alias) | |
base:wielded-by | RW | object | object's wielder (worn-by alias) | |
X | base:parts-covered | RO | string * | bodyparts covered by object when worn |
X | base:parts-covered:foo | RW | boolean | true if 'foo' is in parts-covered |
base:clothes-worn | RO | object * | object's currently worn clothing | |
base:weapons | RO | object ** | object's currently wielded weapons | |
base:light | RO | float | object's perceived light level | |
base:light-category | RO | string | "dark", "dim", or "bright" | |
base:dark | RO | boolean | true if the light level is "dark" | |
base:dim | RO | boolean | true if the light level is "dim" | |
base:bright | RO | boolean | true if the light level is "bright" | |
base:stance | RW | int | object's current stance | |
base:stancestring(*) | RW | string | as above, but english-language string | |
base:preposition | RW | int | object's current preposition | |
base:prepositionstring(**) | RW | string | as above, but english-language string | |
X | base:gait | RW | string | object's gait |
X | base:weapon | RW | boolean | object's a weapon |
X | base:combinable | RW | boolean | object's combinable |
X | base:unsafe | RW | boolean | object's unsafe to quit in |
X | base:safe | RW | boolean | object's safe to quit in |
X | base:clothesexpected | RW | boolean | object's expected to be dressed |
X | base:maxweight | RW | float | how much mass can the object hold? |
X | base:edible | RW | boolean | object's edible |
X | base:potable | RW | boolean | object's potable |
X | base:intrinsicmass | RW | float | object's intrinsic mass |
X | base:intrinsicdensity | RW | float | object's intrinsic density |
X | base:intrinsiccapacity | RW | float | object's intrinsic capacity |
X | base:public-container | RW | int | skip the holder check when displaying guts? |
X | base:transparent-container | RW | int | skip the open/close check when displaying guts? |
X | base:immobile | RW | int | should all movement be forbidden? |
X | base:transparency | RW | boolean | object's transparent |
X | base:details | RO | string * | names of object's details |
X | base:dirs | RO | string * | exit directions given in object's details |
X | base:doors | RO | string * | details in the object that are doors |
X | base:opendoors | RO | string * | details in the object that are open doors |
X | base:closeddoors | RO | string * | details in the object that are closed doors |
detail properties
Local | Property name | Access | Type | Description |
---|---|---|---|---|
X | details:foo:prime | RW | boolean | detail 'foo' is prime |
X | details:foo:face | RW | string | detail 'foo' has the given face |
X | details:foo:abstract | RW | boolean | detail 'foo' is abstract |
X | details:foo:definite | RW | boolean | detail 'foo' is definite |
X | details:foo:plural | RW | boolean | detail 'foo' is plural |
details:foo:prepositions | RO | string * | prepositions associated with detail 'foo' -- currently broken | |
X | details:foo:description:brief | RW | SAM | description type 'brief' in detail 'foo' |
details:foo:prepositions | RO | string * | prepositions associated with detail 'foo' -- currently broken | |
details:foo:preposition:up | RW | boolean | preposition 'up' is associated with detail 'foo' -- currently broken | |
X | details:foo:snames | RO | string * | snames associated with detail 'foo' |
X | details:foo:sname:wound | RW | boolean/string | sname 'wound' is associated with detail 'foo'; the value is e.g. 'wounds' or TRUE for snames without pnames |
X | details:foo:pnames | RO | string * | pnames associated with detail 'foo' |
X | details:foo:pname:wounds | RW | boolean | pname 'wounds' is associated with detail 'foo' |
X | details:foo:adjectives | RO | string * | adjectives associated with detail 'foo' |
X | details:foo:adjective:blue | RW | boolean | adjective 'blue' is associated with detail 'foo' |
X | details:foo:hidden | RW | boolean | detail 'foo' is hidden |
X | details:foo:never-obvious | RW | boolean | detail 'foo' is never obvious |
X | details:foo:obvious-when-open | RW | boolean | detail 'foo' is only obvious when open |
X | details:foo:hidden-when-closed | RW | boolean | detail 'foo' is hidden when closed |
X | details:foo:climbable | RW | NREF | detail 'foo' is climbable with the given destination |
X | details:foo:exit:dest | RW | NREF | detail 'foo' is an exit leading to the given destination |
X | details:foo:exit:directions | RO | string * | directions associated with exit detail 'foo' |
X | details:foo:exit:direction:up | RW | boolean | direction 'up' is valid for exit detail 'foo' |
X | details:foo:exit:door | RW | boolean | exit detail 'foo' has a door |
details:foo:exit:closed | RW | boolean | door detail 'foo' is closed | |
details:foo:exit:locked | RW | boolean | door detail 'foo' is locked | |
X | details:foo:exit:keycode | RW | string | door detail 'foo' has a lock with the given keycode |
X | details:foo:luminosity | RW | float | detail 'foo' has the given luminosity |
*) Available stance strings: * {crouching, kneeling, lying, sitting, standing} (floating and hanging also)
**) Available prepositions strings: * {close to, against, beneath, on, in, near, above, behind, in front of, next to}
Currently missing that should not be missing: * you can't get a list of description types
This is a table of existing methods:
base:addoffer | void | from | object | who is offering the objects? |
what | object * | what objects are being offered? | ||
base:removeoffer | void | from | object | remove offer from whom? |
base:removefromoffer | void | what | object | remove which offered object? |
from | object | who is offering the object? | ||
base:getoffersfrom | object * | from | object | objects offered us by 'from' |
base:getoffersto | object * | to | object | objects we're offering 'to' |
In Merry, these methods would be used like e.g.
Call($target, "base:addoffer", $what: ({ sword_ob }), $from: $actor);
For moving into its own document soon:
Date: Wed, 14 May 2003 15:23:32 -0500
From: Par Winzell <zell@skotos.net>
To: List for Skotos Seven developers and their cohorts <skotos-seven@skotos.net>
Subject: Re: [skotos-seven] Naming request
OK! On S7 and Marrach both, Merry-callable functions in the object /usr/System/sys/idd (which has no higher level object name because, well, it IS the higher level object name database, and I don't want to get recursive on it)...
idd:get-folders
idd:get-objects
where $folder is expected; if empty, the root folder is assumed.
+tool merry eval Call(${/usr/System/sys/idd}, "idd:get-folders", $folder: "Zell")
Merry result: ({ "MiniCombat", "Test", "Tutorial" })
+tool merry eval Call(${/usr/System/sys/idd}, "idd:get-objects", $folder: "Zell")
Merry result: ({ "GunfightDB", "luminometer" })
* See NamingAnUnnamedObject for an example of change the base:objectname derived property
The following base:* properties are in use in Castle Marrach, but are not derived properties, and are not inherited. We should eventually phase them out.
* base:keycode - a key's keycode * base:combat:weapon (currently wielded weapon? unsure of support) * base:initialspawner - set in object created from InitialContents * base:initialcontents - set in object with InitialContents
-- Main.ChristopherAllen - 28 Aug 2002
Emails
----- Original Message -----
From: "Par Winzell" <zell@skotos.net>
To: <skotos-seven@skotos.net>
Sent: Wednesday, September 11, 2002 9:59 AM
Subject: [skotos-seven] nrefs get properties!
Hi folks,
Among those of you who have worked with Merry, a fair portion have
probably written cumbersome expressions like maybe
Get(NRefOb($what), "details:" + NRefDetail($what) + ":exit:dest")
which means $what is an nref and you're trying to retrieve its exit
destination. You look up the relevant details: derived property in the
nref's actual object.
Pretty annoying.
So, I've introduced a new derived property namespace to automate the
above, using the namespace 'detail:'. The really interesting part is
that these properties can be looked up on the nrefs themselves -- no
need to explicitly go to the NRefOb().
Thus the equivalent of the above using the new paradigm is
$what."detail:exit:dest"
which, one must say, is rather an improvement.
I dunno about you guys, but I'm going to go back and simplify a lot of
old Merry code now.
This is in effect both on Marrach and S7.
Cheers,
Zell
----- Original Message -----
From: "Christopher Allen" <ChristopherA@skotos.net>
To: <skotos-seven@skotos.net>
Sent: Tuesday, April 15, 2003 10:42 AM
Subject: [skotos-seven] Alternative Way to Refer to Detail Properties
I discovered an undocumented feature for referring to details that is causing me
to go back and rewrite some of my recently examples in Examples:complete:*
Basically the way that TWiki document DerivedProperties had documented how to
get and set various properties of details was to use the format:
$this.details:detail-id:detailproperty
For example:
{? | $this.details:lamp:luminosity | The lamp is lit | The lamp is unlit.}
The problem with this technique is that you have to know what the detail ID is,
and if you are a novice builder and try to copy this script to another object,
it will not work unless you remember to change :lamp: to the new detail name.
You can also run into problems if the detail ID has a space in it, you have to
remember then to encapsulate the reference:
{? | $("this.details:lamp ceiling:luminosity") | The lamp is lit | The lamp
is unlit.}
...which is easy to forget.
With this alternative way to reference detail properties, you can now refer to
directly to the details without knowing the detail ID if you have an NREF
argument available that points to the detail rather then just a OBJ argument.
NREFs contain the name of the object, plus the name of the detail. In most
signals this argument would be $target rather then $this.
This makes the above example look like this:
{? | $target.detail:luminosity | The lamp is lit | The lamp is unlit.}
You'll still need the original reference technique of
$this.details:detail-id:detailproperty when you want to refer to properties of
details other then what your signal has an easily available NREF for. For
instance, my toggle scripts are typically located in a "switch" detail, but they
test and toggle a "lamp" detail, thus they have to use the older reference
technique.
-- Christopher Allen