How a name is assembled, and why it decides what players can type.
You never set an object's display name directly. You set its parts, and the engine assembles the name from them:
article adjectives (up to 3) noun trailer
an old rusty sword (broken)
"an old rusty sword (broken)"| Part | What it is | Example |
|---|---|---|
| Article | a, an, or the. Optional. | an |
| Adjectives | Up to three describing words, in order. | old rusty |
| Noun | What the thing is. Every object has one. | sword |
| Trailer | A tag that follows the noun. Optional. | (broken) |
The engine corrects a and an for you, based on the
word that actually follows the article. Add the adjective old to
"a sword" and it becomes "an old sword" on its own.
The article, adjectives and trailer are stored together in one property called
name_mod_list — a five-slot list:
name_mod_list = [article, adj1, adj2, adj3, trailer]
['an', 'old', 'rusty', '', '(broken)'] -> "an old rusty sword (broken)"
['the', '', '', '', ''] -> "the sword"
['', '', '', '', '(broken)'] -> "sword (broken)"
The noun is not in this list — it is stored separately. Combine the two
and you get the object's name, plus cname, the same
name capitalised for the start of a sentence.
You will rarely touch name_mod_list yourself; the naming commands
below edit the right slot for you. It is worth knowing it exists because it
explains the shape of those commands — and because it is what makes matching
work.
This is the reason names are built from parts rather than typed as a line of text. When a player types something, the engine reads the last word as the noun and everything before it as adjectives that must be present, in that order:
"sword" -> noun: sword adjectives: — first match
"rusty sword" -> noun: sword adjectives: rusty first rusty one
"old rusty sword" -> noun: sword adjectives: old, rusty both, in order
"2nd rusty sword" -> noun: sword adjectives: rusty the second one
Articles are ignored, so get the sword and get sword
are the same request. A leading ordinal — 2nd, third,
or a bare 3 — picks which match when several fit.
Because rusty is stored as a fact about the object rather than
buried in a name string, all of these find your sword without you arranging
anything.
A case holding whiskey should be named "a case", not "a case of fire
whiskey". The name is what players type at, so putting the contents in
the name means drink whiskey starts matching the box. Put
the contents in the description instead, or let players
look in it.
#0 is a special object. Nobody stands in it and players never see
it — it exists to hold world-wide settings and, more usefully to you, a list of
named objects.
Every property on #0 can be referred to anywhere as
$name. Because #0 has a property called
item holding object #12, writing $item
means #12 — anywhere you would otherwise type the number.
> +props #0
bed chair chest eu furniture
globals hat item obj pants
shirt shoes table wearableSo the starter world gives you these to build from:
| Shortcut | Is |
|---|---|
$item | Anything a player can pick up and carry. |
$obj | Scenery — present in the room, but not carriable. |
$chest | A container that holds other objects. |
$furniture, $chair, $table, $bed | Things to sit, stand or lie on. |
$wearable, $hat, $shirt, $pants, $shoes | Clothing. |
Two reasons to prefer $item over #12. It says what you
mean, so a command is readable months later. And it survives renumbering — if
the prototype ever moves, #0 is updated once and every
$item in your world still points at the right thing.
$items or $widget does not raise an error. A
$ name with no matching property on #0 simply
reads as empty, so the command using it does nothing obvious. If
something is silently not working, check the spelling against
+props #0.
@make takes the object to build from, and a name — the bare noun, with
no adjective on it. Adjectives are added afterwards with @adj:
> @make $item = sword
Created #202:a sword, added to inventory.
The new object goes into your hands. Add /drop to leave it in the
room instead:
> @make/drop $chest = crate
Created #207:a crate, dropped here.
Whatever you build from, the new object can already do everything that one
could — a $chair can be sat on before you write anything.
$ or #
@make item = sword does not work — it looks for an
object called "item" nearby and reports
Parent object 'item' not found. Use the shortcut
($item) or the number (#12).
Then fill in the parts. Each command edits one thing:
| Command | Sets | Short form |
|---|---|---|
@name <obj> = sword | The noun. | — |
@article <obj> = a | The article. | @art |
@adjective <obj> = old rusty | Up to three adjectives. Give no value to clear them. | @adj |
@trailer <obj> = (broken) | The trailer. | @trail |
@desc <obj> = <text> | What players read when they look at it. | — |
@title <obj> | Rebuilds the display name from the current parts. | — |
A worked example, from nothing to a described object:
> @make $item = sword
Created #202:a sword, added to inventory.
> @art sword = a
Article of #202:a sword reset to 'a'. Object title: 'a sword'.
> @adj sword = old rusty
Adjectives reset to 'old rusty'. Object title: 'an old rusty sword'.
> @trail sword = (broken)
Trailer reset to '(broken)'. Object title: 'an old rusty sword (broken)'.
> @desc sword = The blade is pitted along its length.
> look sword
an old rusty sword (broken)
The blade is pitted along its length.
Notice the article correcting itself: it was set to a, and adding
the adjective old turned it into an without being
asked.
Most commands can be abbreviated to their first few letters:
@art, @adj, @trail. Any
abbreviation long enough to be unambiguous works —
@adje is the same command as @adj.
A tag is a label you stick on an object so that your own code can find it or test for it later. Players never see tags. They are for you: marking which zone a room belongs to, which items count as light sources, which doors a quest should unlock.
Tags come in categories. Write the category before a slash, and the tag after it:
> @adtag lantern = zone/haven
Added tag 'haven' in category 'zone' to #202:a lantern.
> @adtag lantern = lightsource
Added tag 'lightsource' to #202:a lantern.
Leave the category off and the tag goes into general. A category
can hold as many tags as you like, so an object can be in two zones at once:
{'zone': ['haven', 'docks'], 'general': ['lightsource']}Remove one the same way. Naming the category removes only that tag, leaving the rest of the category alone:
> @rmtag lantern = zone/docks
Removed tag 'docks' from category 'zone' on #202:a lantern.
This is the point of them. Every object has a tags handler your
code can ask:
| Write | To get |
|---|---|
this.tags.has('haven', 'zone') | True if it carries that tag in that category. |
this.tags.has('lightsource') | The same, for an uncategorised tag. |
this.tags.get('zone') | Every tag in one category, as a list. |
this.tags.all() | The whole lot, as a dictionary. |
this.tags.add('haven', 'zone') | Add one from code. |
this.tags.remove('haven', 'zone') | Remove one from code. |
So a torch-lighting verb can refuse anything that is not a light source, and a zone-wide event can act on the rooms it should:
if not target.tags.has('lightsource'):
pobj.msg("You can't light that.")
return@examine <object> lists them, shown as
._tags — they are kept in a hidden property, which is why
+show and +props do not mention them. Both tag
commands need gm3.