<h1><spanclass="section-number">11. </span>Searching for things<aclass="headerlink"href="#searching-for-things"title="Permalink to this headline">¶</a></h1>
<h2><spanclass="section-number">11.1. </span>Main search functions<aclass="headerlink"href="#main-search-functions"title="Permalink to this headline">¶</a></h2>
<p>The base tools are the <codeclass="docutils literal notranslate"><spanclass="pre">evennia.search_*</span></code> functions, such as <codeclass="docutils literal notranslate"><spanclass="pre">evennia.search_object</span></code>.</p>
<p>What is returned from the main search functions is actually a <codeclass="docutils literal notranslate"><spanclass="pre">queryset</span></code>. They can be treated like lists except that they can’t modified in-place. We’ll discuss querysets in the <codeclass="docutils literal notranslate"><spanclass="pre">next</span><spanclass="pre">lesson</span></code><Django-queries>`_.</p>
<p>Strings are always case-insensitive, so searching for <codeclass="docutils literal notranslate"><spanclass="pre">"rose"</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">"Rose"</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">"rOsE"</span></code> give the same results.
It’s important to remember that what is returned from these search methods is a <em>listing</em> of 0, one or more
elements - all the matches to your search. To get the first match:</p>
<aclass="reference internal"href="../../../Evennia-API.html"><spanclass="doc std std-doc">in the Search functions section</span></a> of the API frontpage.</p>
<h2><spanclass="section-number">11.2. </span>Searching using Object.search<aclass="headerlink"href="#searching-using-object-search"title="Permalink to this headline">¶</a></h2>
<p>On the <codeclass="docutils literal notranslate"><spanclass="pre">DefaultObject</span></code> is a <codeclass="docutils literal notranslate"><spanclass="pre">.search</span></code> method which we have already tried out when we made Commands. For
this to be used you must already have an object available:</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">.search</span></code> method wraps <codeclass="docutils literal notranslate"><spanclass="pre">evennia.search_object</span></code> and handles its output in various ways.</p>
<ulclass="simple">
<li><p>By default it will always search for objects among those in <codeclass="docutils literal notranslate"><spanclass="pre">obj.location.contents</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">obj.contents</span></code> (that is,
things in obj’s inventory or in the same room).</p></li>
<li><p>It will always return exactly one match. If it found zero or more than one match, the return is <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code>.</p></li>
<li><p>On a no-match or multimatch, <codeclass="docutils literal notranslate"><spanclass="pre">.search</span></code> will automatically send an error message to <codeclass="docutils literal notranslate"><spanclass="pre">obj</span></code>.</p></li>
</ul>
<p>So this method handles error messaging for you. A very common way to use it is in commands:</p>
<p>Remember, <codeclass="docutils literal notranslate"><spanclass="pre">self.caller</span></code> is the one calling the command. This is usually a Character, which
inherits from <codeclass="docutils literal notranslate"><spanclass="pre">DefaultObject</span></code>! This (rather stupid) Command searches for an object named “foo” in
the same location. If it can’t find it, <codeclass="docutils literal notranslate"><spanclass="pre">foo</span></code> will be <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code>. The error has already been reported
to <codeclass="docutils literal notranslate"><spanclass="pre">self.caller</span></code> so we just abort with <codeclass="docutils literal notranslate"><spanclass="pre">return</span></code>.</p>
<p>You can use <codeclass="docutils literal notranslate"><spanclass="pre">.search</span></code> to find anything, not just stuff in the same room:</p>
<p>With <codeclass="docutils literal notranslate"><spanclass="pre">quiet=True</span></code> the user will not be notified on zero or multi-match errors. Instead you are expected to handle this
yourself and what you get back is now a list of zero, one or more matches!</p>
<h2><spanclass="section-number">11.3. </span>What can be searched for<aclass="headerlink"href="#what-can-be-searched-for"title="Permalink to this headline">¶</a></h2>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> is the name of the entity. Searching for this is always case-insensitive.</p>
<h3><spanclass="section-number">11.3.2. </span>Search by aliases<aclass="headerlink"href="#search-by-aliases"title="Permalink to this headline">¶</a></h3>
<p>Objects and Accounts can have any number of aliases. When searching for <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> these will searched too,
<p>If the above <codeclass="docutils literal notranslate"><spanclass="pre">rose</span></code> has a <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code><codeclass="docutils literal notranslate"><spanclass="pre">"Rose"</span></code>, it can now also be found by searching for <codeclass="docutils literal notranslate"><spanclass="pre">flower</span></code>. In-game
you can assign new aliases to things with the <codeclass="docutils literal notranslate"><spanclass="pre">alias</span></code> command.</p>
<h3><spanclass="section-number">11.3.3. </span>Search by location<aclass="headerlink"href="#search-by-location"title="Permalink to this headline">¶</a></h3>
<p>Only Objects (things inheriting from <codeclass="docutils literal notranslate"><spanclass="pre">evennia.DefaultObject</span></code>) has a location. This is usually a room.
The <codeclass="docutils literal notranslate"><spanclass="pre">Object.search</span></code> method will automatically limit it search by location, but it also works for the
general search function. If we assume <codeclass="docutils literal notranslate"><spanclass="pre">room</span></code> is a particular Room instance,</p>
<p>Think of a <aclass="reference internal"href="../../../Components/Tags.html"><spanclass="doc std std-doc">Tag</span></a> as the label the airport puts on your luggage when flying.
<p>Tags can also have categories. By default this category is <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code> which is also considered a category.</p>
<h3><spanclass="section-number">11.3.5. </span>Search by Attribute<aclass="headerlink"href="#search-by-attribute"title="Permalink to this headline">¶</a></h3>
<p>We can also search by the <aclass="reference internal"href="../../../Components/Attributes.html"><spanclass="doc std std-doc">Attributes</span></a> associated with entities.</p>
<h3><spanclass="section-number">11.3.6. </span>Search by Typeclass<aclass="headerlink"href="#search-by-typeclass"title="Permalink to this headline">¶</a></h3>
<p>If you have the <codeclass="docutils literal notranslate"><spanclass="pre">Rose</span></code> class already imported you can also pass it directly:</p>
<p>The database id or <codeclass="docutils literal notranslate"><spanclass="pre">#dbref</span></code> is unique and never-reused within each database table. In search methods you can
replace the search for <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> with the dbref to search for. This must be written as a string <codeclass="docutils literal notranslate"><spanclass="pre">#dbref</span></code>:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>You may be used to using #dbrefs a lot from other codebases. It is however considered
`bad practice` in Evennia to rely on hard-coded #dbrefs. It makes your code hard to maintain
<h2><spanclass="section-number">11.4. </span>Finding objects relative each other<aclass="headerlink"href="#finding-objects-relative-each-other"title="Permalink to this headline">¶</a></h2>
<p>Let’s consider a <codeclass="docutils literal notranslate"><spanclass="pre">chest</span></code> with a <codeclass="docutils literal notranslate"><spanclass="pre">coin</span></code> inside it. The chests stand in a room <codeclass="docutils literal notranslate"><spanclass="pre">dungeon</span></code>. In the dungeon is also
a <codeclass="docutils literal notranslate"><spanclass="pre">door</span></code>. This is an exit leading outside.</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">coin.location</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">chest</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">chest.location</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">dungeon</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">door.location</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">dungeon</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">room.location</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code> since it’s not inside something else.</p></li>
</ul>
<p>One can use this to find what is inside what. For example, <codeclass="docutils literal notranslate"><spanclass="pre">coin.location.location</span></code> is the <codeclass="docutils literal notranslate"><spanclass="pre">room</span></code>.
We can also find what is inside each object. This is a list of things.</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">room.contents</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">[chest,</span><spanclass="pre">door]</span></code></p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">chest.contents</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">[coin]</span></code></p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">coin.contents</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">[]</span></code>, the empty list since there’s nothing ‘inside’ the coin.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">door.contents</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">[]</span></code> too.</p></li>
</ul>
<p>A convenient helper is <codeclass="docutils literal notranslate"><spanclass="pre">.contents_get</span></code> - this allows to restrict what is returned:</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">room.contents_get(exclude=chest)</span></code> - this returns everything in the room except the chest (maybe it’s hidden?)</p></li>
</ul>
<p>There is a special property for finding exits:</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">room.exits</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">[door]</span></code></p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">coin.exits</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">[]</span></code> (same for all the other objects)</p></li>
</ul>
<p>There is a property <codeclass="docutils literal notranslate"><spanclass="pre">.destination</span></code> which is only used by exits:</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">door.destination</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">outside</span></code> (or wherever the door leads)</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">room.destination</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code> (same for all the other non-exit objects)</p></li>