Inspecting entities
Once you have a creature, object, or room — as $self, $actor, or
something pulled from an iterable — you usually need to ask questions about
it before acting. This chapter covers reading an entity's attributes,
sorting one kind from another, finding where an object sits, and guarding
against references that are empty or stale.
Reading attributes
The accessor built-ins read a live entity's current state. They are read-only — they never change the entity (for that, see Changing the world).
| Accessor | Returns |
|---|---|
name |
display name (string) |
vnum |
vnum / room number (int; players error) |
level |
level (int) |
class |
class name (string) |
alignment |
good / evil / neutral |
gen |
remort generation (int) |
position |
position name (standing, sleeping, …) |
room |
the entity's room (or a vnum resolved to a room) |
carrier |
the creature carrying an object, else null |
after command (appraise) {
echo $actor "[name $actor], a level [level $actor] [class $actor], standing [position $actor]."
echo $actor "Your alignment reads [alignment $actor]; generation [gen $actor]."
}
room is the bridge between vnums and rooms:
[room $self] is the owner's room, while [room 3001] resolves a room
vnum. carrier goes the other way for an
object — who is holding it:
after get {
let who [carrier $self]
unless [isnull $who]
echo $who "The amulet grows warm in your grasp."
}
(That handler lives on the object: $self is the item, $actor the
creature, and the get event fires when it is picked up.)
What kind of thing is this?
The type predicates let one handler treat players, mobs, and objects differently. They each return a bool:
isplayer/ismob— a creature is a player / an NPC.isobj— an object reference resolves.isfighting— a creature has a living opponent.
after command (assess) {
if [ismob $actor] {
do "say Another of my kind."
} elif [isfighting $actor] {
do "say You are in the thick of it!"
} else {
do "say Welcome, [name $actor]."
}
}
Where is this object?
Two questions come up constantly. "Does this creature/room hold an item of
vnum N?" is answered by vnum predicates:
isholding searches carried/contained
objects, and iswearing searches worn gear
and implants:
before command (enter) {
require [isholding $actor 1] # carrying the token?
do "say The gate recognises your token."
}
before command (sanctum) {
require [iswearing $actor 1] # wearing the sigil?
do "say The wards admit you."
}
"Where is this specific object right now?" is answered by
location, which tests one known object
against a place name (carried, container, worn, wielded, held,
implanted, room):
after command (inspect) {
let item [first [inventory $self]]
require [isobj $item] # resolves to a live object?
do "say My [name $item] is carried: [location $item carried]."
}
isobj here doubles as the empty-inventory
guard: when first returns null, isobj is false and the handler stops.
The world clock
A couple of accessors describe the world rather than an entity:
hour gives the current game hour (0–23) and
moonphase the lunar phase. They take no
arguments and pair naturally with tick handlers:
handle tick {
if [lt [hour] 6] {
do "emote yawns in the pre-dawn gloom."
}
if [streqi [moonphase] "full"] {
do "say The full moon stirs something in me."
}
}
Presence and staleness
An entity reference resolves to the live thing each time it is read, so it always reflects current state — but the thing it points at can vanish (a mob is killed, an object is purged). A reference whose entity is gone is stale, and resolving it quietly stops the script. Two guards keep you safe:
isnull— the value is null (e.g. achooseover an empty room, or arecallof an unwritten slot).exists— the value is non-null and, for an entity reference, the entity is still live.
after command (track) {
let prey [first [select [creatures $self] &isplayer]]
if [isnull $prey] {
do "say No quarry in sight."
}
if [exists $prey] {
do "hunt [name $prey]"
}
}
Use isnull for "was there anything to begin with?" and exists for "is
this remembered reference still valid?" — especially after a pause, when
the world may have moved on.
A note on types
Every value has exactly one type: null,
bool, int, string, iterable, block, list, and the
entity references creature, object, room, mob_proto, and
obj_proto. Accessors and predicates expect particular types and raise a
run-time type error on a mismatch; convert explicitly when you need to (see
Numbers, text, and logic). The prototype types
come from mob and object,
covered in Changing the world.
See also
- Finding things — producing the entities you inspect.
- Types · Values
- Combat and death —
positionandisfightingin a fight.