Search System
Overview
TinyMUX provides several commands for locating objects in the database: @search, @find, @entrances, and the search() function. Because these commands scan part or all of the database, they each cost coins to run (100 by default, controlled by the search_cost configuration parameter). Understanding the search system is essential for both everyday building and administrative work.
@search
@search is the primary database search command.
@search [<player>] [<class>=<restriction>[,<low>[,<high>]]
The optional <player> argument restricts results to objects owned by that player. The <low> and <high> arguments limit the range of database objects scanned, with <low> defaulting to #0 and <high> defaulting to the last object in the database.
Non-wizard players may only search for objects they own, with one exception: searches for players (type=player or flags=P) are available to everyone.
Search Classes
The following classes may be used with both @search and search():
| Class | Description |
|---|---|
| TYPE | Restricts to a given type: ROOM, EXIT, PLAYER, or OBJECT (alias: THING). |
| NAME | Restricts to objects whose names start with the given string. |
| FLAGS | Restricts to objects that have the specified flags set. |
| POWER | Restricts to objects that have the specified power. |
| EVAL | Evaluates an expression for each object, replacing ## with the dbref. Objects where the expression returns true (non-zero, not #-1) are selected. |
| PARENT | Restricts to objects with the specified parent. |
| ZONE | Restricts to objects in the specified zone. |
Several shorthand classes combine TYPE and NAME or TYPE and EVAL:
| Class | Equivalent |
|---|---|
| OBJECTS (or THINGS) | TYPE=OBJECT and NAME=… |
| ROOMS | TYPE=ROOM and NAME=… |
| EXITS | TYPE=EXIT and NAME=… |
| PLAYERS | TYPE=PLAYER and NAME=… |
| EOBJECT (or ETHING) | TYPE=OBJECT and EVAL=… |
| EROOM | TYPE=ROOM and EVAL=… |
| EEXIT | TYPE=EXIT and EVAL=… |
| EPLAYER | TYPE=PLAYER and EVAL=… |
Evaluation Expressions
The EVAL class is the most flexible search mechanism. The token ## is replaced with each object’s dbref before the expression is evaluated.
@search eval=gt(money(##),10)
This finds all objects you own whose value exceeds 10 coins. The EROOM, EEXIT, EOBJECT, and EPLAYER classes combine a type restriction with an eval, which is more efficient than filtering by type within the eval expression itself.
@find
@find is a simpler alternative to @search that locates objects by name.
@find <name>[,<low>[,<high>]]
It displays the name and dbref of every room, thing, or player you control whose name matches <name>. Like @search, it costs 100 coins and supports optional range limits.
@find Lost Room
@find Secret Device,12000,14000
@entrances
@entrances searches the database for links pointing to a given object.
@entrances [[<object>][,<low>[,<high>]]]
For rooms, it reports exits linked to the room, drop-tos leading there, and players or objects whose home is set to that room. For players and objects, it lists exits leading to them. The default target is your current room.
@entrances -- all links to the current room
@entrances me,1000 -- links to me from #1000 onward
search() Function
The search() function provides softcode access to the same search engine used by @search. It returns a space-separated list of dbrefs.
search([<player>] [<class>=<restriction>[,<low>[,<high>]]])
Because it carries the same cost as @search, repeated use in softcode can become expensive. When using bracket characters in an EVAL restriction inside softcode, they must be escaped:
say search(eval=\[eq(money(##),1)\])
Cost and Performance
All database search commands perform a scan across part or all of the object database. The search_cost configuration parameter (default: 100 coins) controls the cost charged for @search, @find, @entrances, and @stats with a player argument. The cost exists specifically because these operations are computationally expensive.
On large databases (tens of thousands of objects or more), full scans can cause noticeable lag. To reduce impact:
- Use
<low>and<high>range limits to narrow the scan window. - Prefer type-specific classes (EROOM, EPLAYER) over a bare EVAL that checks type internally.
- Avoid calling
search()in frequently triggered softcode.
@stats
@stats provides aggregate counts without listing individual objects.
@stats[/all] [<player>]
Without arguments or switches, @stats is free and reports total object counts. With /all or a player name, it gives a breakdown by type (rooms, exits, things, players, garbage) but costs the same as @search.
Wizard vs. Mortal Restrictions
Mortals can only search objects they own. The exceptions are player-type searches (type=player, flags=P), which return results regardless of ownership. Wizards can search the entire database and can specify any player as the owner filter. The @mark, @mark_all, and @apply_marked commands are wizard-only.
@mark and @apply_marked
Wizards can perform batch operations using the mark system:
@mark[/set|/clear] [<player>] [<class>=<restriction>]
@mark_all[/set|/clear]
@apply_marked <command>
@mark uses the same search classes as @search to set or clear the MARKED flag on matching objects. @mark_all sets or clears MARKED on every object. @apply_marked then executes a command once per marked object, substituting ## with the dbref.
These commands require database cleaning to be disabled first (@disable cleaning), because the cleaning process uses the MARKED flag internally for connectivity checks.
Practical Examples
Find all rooms you own:
@search type=room
Find connected wizards:
@search flags=PWc
Find all dark rooms (wizard only—searches all owners):
@mark flags=Dd
@apply_marked examine ##/DARK
Find objects in a specific zone:
@search zone=#100
Find orphaned objects (objects in rooms that have been destroyed):
@search eval=not(good(loc(##)))
Search for things named “Test” starting from object #5000:
@search object=Test,5000
List all objects in softcode for further processing:
think iter(search(type=room), name(##) - ##)