<h1>NPC shop Tutorial<aclass="headerlink"href="#npc-shop-tutorial"title="Permalink to this headline">¶</a></h1>
<p>This tutorial will describe how to make an NPC-run shop. We will make use of the <aclass="reference internal"href="../Components/EvMenu.html"><spanclass="doc std std-doc">EvMenu</span></a>
system to present shoppers with a menu where they can buy things from the store’s stock.</p>
<p>Our shop extends over two rooms - a “front” room open to the shop’s customers and a locked “store
room” holding the wares the shop should be able to sell. We aim for the following features:</p>
<ulclass="simple">
<li><p>The front room should have an Attribute <codeclass="docutils literal notranslate"><spanclass="pre">storeroom</span></code> that points to the store room.</p></li>
<li><p>Inside the front room, the customer should have a command <codeclass="docutils literal notranslate"><spanclass="pre">buy</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">browse</span></code>. This will open a
menu listing all items available to buy from the store room.</p></li>
<li><p>A customer should be able to look at individual items before buying.</p></li>
<li><p>We use “gold” as an example currency. To determine cost, the system will look for an Attribute
<codeclass="docutils literal notranslate"><spanclass="pre">gold_value</span></code> on the items in the store room. If not found, a fixed base value of 1 will be assumed.
The wealth of the customer should be set as an Attribute <codeclass="docutils literal notranslate"><spanclass="pre">gold</span></code> on the Character. If not set, they
have no gold and can’t buy anything.</p></li>
<li><p>When the customer makes a purchase, the system will check the <codeclass="docutils literal notranslate"><spanclass="pre">gold_value</span></code> of the goods and
compare it to the <codeclass="docutils literal notranslate"><spanclass="pre">gold</span></code> Attribute of the customer. If enough gold is available, this will be
deducted and the goods transferred from the store room to the inventory of the customer.</p></li>
<li><p>We will lock the store room so that only people with the right key can get in there.</p></li>
</ul>
<sectionid="the-shop-menu">
<h2>The shop menu<aclass="headerlink"href="#the-shop-menu"title="Permalink to this headline">¶</a></h2>
<p>We want to show a menu to the customer where they can list, examine and buy items in the store. This
menu should change depending on what is currently for sale. Evennia’s <em>EvMenu</em> utility will manage
the menu for us. It’s a good idea to <aclass="reference internal"href="../Components/EvMenu.html"><spanclass="doc std std-doc">read up on EvMenu</span></a> if you are not familiar with it.</p>
<sectionid="designing-the-menu">
<h3>Designing the menu<aclass="headerlink"href="#designing-the-menu"title="Permalink to this headline">¶</a></h3>
<p>The shopping menu’s design is straightforward. First we want the main screen. You get this when you
enter a shop and use the <codeclass="docutils literal notranslate"><spanclass="pre">browse</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">buy</span></code> command:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>*** Welcome to ye Old Sword shop! ***
Things for sale (choose 1-3 to inspect, quit to exit):
<p>Finally, when you buy something, a brief message should pop up:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>You pay 5 gold and purchase A rusty sword!
</pre></div>
</div>
<p>or</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>You cannot afford 5 gold for A rusty sword!
</pre></div>
</div>
<p>After this you should be back to the top level of the shopping menu again and can continue browsing.</p>
</section>
<sectionid="coding-the-menu">
<h3>Coding the menu<aclass="headerlink"href="#coding-the-menu"title="Permalink to this headline">¶</a></h3>
<p>EvMenu defines the <em>nodes</em> (each menu screen with options) as normal Python functions. Each node
must be able to change on the fly depending on what items are currently for sale. EvMenu will
automatically make the <codeclass="docutils literal notranslate"><spanclass="pre">quit</span></code> command available to us so we won’t add that manually. For compactness
we will put everything needed for our shop in one module, <codeclass="docutils literal notranslate"><spanclass="pre">mygame/typeclasses/npcshop.py</span></code>.</p>
<spanclass="n">text</span><spanclass="o">=</span><spanclass="sa">f</span><spanclass="s2">"*** Welcome to </span><spanclass="si">{</span><spanclass="n">shopname</span><spanclass="si">}</span><spanclass="s2">! ***</span><spanclass="se">\n</span><spanclass="s2">"</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="sa">f</span><spanclass="s2">" Things for sale (choose 1-</span><spanclass="si">{</span><spanclass="nb">len</span><spanclass="p">(</span><spanclass="n">wares</span><spanclass="p">)</span><spanclass="si">}</span><spanclass="s2"> to inspect); quit to exit:"</span>
<spanclass="k">else</span><spanclass="p">:</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">" There is nothing for sale; quit to exit."</span>
<p>In this code we assume the caller to be <em>inside</em> the shop when accessing the menu. This means we can
access the shop room via <codeclass="docutils literal notranslate"><spanclass="pre">caller.location</span></code> and get its <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> to display as the shop’s name. We also
assume the shop has an Attribute <codeclass="docutils literal notranslate"><spanclass="pre">storeroom</span></code> we can use to get to our stock. We loop over our goods
to build up the menu’s options.</p>
<p>Note that <em>all options point to the same menu node</em> called <codeclass="docutils literal notranslate"><spanclass="pre">menunode_inspect_and_buy</span></code>! We can’t know
which goods will be available to sale so we rely on this node to modify itself depending on the
circumstances. Let’s create it now.</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># further down in mygame/typeclasses/npcshop.py</span>
<spanclass="s2">"desc"</span><spanclass="p">:</span><spanclass="sa">f</span><spanclass="s2">"Buy </span><spanclass="si">{</span><spanclass="n">ware</span><spanclass="o">.</span><spanclass="n">key</span><spanclass="si">}</span><spanclass="s2"> for </span><spanclass="si">{</span><spanclass="n">gold_val</span><spanclass="si">}</span><spanclass="s2"> gold"</span><spanclass="p">,</span>
<p>In this menu node we make use of the <codeclass="docutils literal notranslate"><spanclass="pre">raw_string</span></code> argument to the node. This is the text the menu
user entered on the <em>previous</em> node to get here. Since we only allow numbered options in our menu,
<codeclass="docutils literal notranslate"><spanclass="pre">raw_input</span></code> must be an number for the player to get to this point. So we convert it to an integer
index (menu lists start from 1, whereas Python indices always starts at 0, so we need to subtract
1). We then use the index to get the corresponding item from storage.</p>
<p>We just show the customer the <codeclass="docutils literal notranslate"><spanclass="pre">desc</span></code> of the item. In a more elaborate setup you might want to show
things like weapon damage and special stats here as well.</p>
<p>When the user choose the “buy” option, EvMenu will execute the <codeclass="docutils literal notranslate"><spanclass="pre">exec</span></code> instruction <em>before</em> we go
back to the top node (the <codeclass="docutils literal notranslate"><spanclass="pre">goto</span></code> instruction). For this we make a little inline function
<codeclass="docutils literal notranslate"><spanclass="pre">buy_ware_result</span></code>. EvMenu will call the function given to <codeclass="docutils literal notranslate"><spanclass="pre">exec</span></code> like any menu node but it does not
need to return anything. In <codeclass="docutils literal notranslate"><spanclass="pre">buy_ware_result</span></code> we determine if the customer can afford the cost and
give proper return messages. This is also where we actually move the bought item into the inventory
of the customer.</p>
</section>
<sectionid="the-command-to-start-the-menu">
<h3>The command to start the menu<aclass="headerlink"href="#the-command-to-start-the-menu"title="Permalink to this headline">¶</a></h3>
<p>We could <em>in principle</em> launch the shopping menu the moment a customer steps into our shop room, but
this would probably be considered pretty annoying. It’s better to create a <aclass="reference internal"href="../Components/Commands.html"><spanclass="doc std std-doc">Command</span></a> for
customers to explicitly wanting to shop around.</p>
<p>This will launch the menu. The <codeclass="docutils literal notranslate"><spanclass="pre">EvMenu</span></code> instance is initialized with the path to this very module -
since the only global functions available in this module are our menu nodes, this will work fine
(you could also have put those in a separate module). We now just need to put this command in a
<aclass="reference internal"href="../Components/Command-Sets.html"><spanclass="doc std std-doc">CmdSet</span></a> so we can add it correctly to the game:</p>
<h2>Building the shop<aclass="headerlink"href="#building-the-shop"title="Permalink to this headline">¶</a></h2>
<p>There are really only two things that separate our shop from any other Room:</p>
<ulclass="simple">
<li><p>The shop has the <codeclass="docutils literal notranslate"><spanclass="pre">storeroom</span></code> Attribute set on it, pointing to a second (completely normal) room.</p></li>
<li><p>It has the <codeclass="docutils literal notranslate"><spanclass="pre">ShopCmdSet</span></code> stored on itself. This makes the <codeclass="docutils literal notranslate"><spanclass="pre">buy</span></code> command available to users entering
the shop.</p></li>
</ul>
<p>For testing we could easily add these features manually to a room using <codeclass="docutils literal notranslate"><spanclass="pre">@py</span></code> or other admin
commands. Just to show how it can be done we’ll instead make a custom <aclass="reference internal"href="../Components/Typeclasses.html"><spanclass="doc std std-doc">Typeclass</span></a> for
the shop room and make a small command that builders can use to build both the shop and the
storeroom at once.</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># bottom of mygame/typeclasses/npcshop.py</span>
<spanclass="c1"># inform the builder about progress</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="sa">f</span><spanclass="s2">"The shop </span><spanclass="si">{</span><spanclass="n">shop</span><spanclass="si">}</span><spanclass="s2"> was created!"</span><spanclass="p">)</span>
</pre></div>
</div>
<p>Our typeclass is simple and so is our <codeclass="docutils literal notranslate"><spanclass="pre">buildshop</span></code> command. The command (which is for Builders only)
just takes the name of the shop and builds the front room and a store room to go with it (always
named <codeclass="docutils literal notranslate"><spanclass="pre">"<shopname>-storage"</span></code>. It connects the rooms with a two-way exit. You need to add
<codeclass="docutils literal notranslate"><spanclass="pre">CmdBuildShop</span></code> [to the default cmdset](Starting/Adding-Command-Tutorial#step-2-adding-the-command-to-a-
default-cmdset) before you can use it. Once having created the shop you can now <codeclass="docutils literal notranslate"><spanclass="pre">@teleport</span></code> to it or
<codeclass="docutils literal notranslate"><spanclass="pre">@open</span></code> a new exit to it. You could also easily expand the above command to automatically create
exits to and from the new shop from your current location.</p>
<p>To avoid customers walking in and stealing everything, we create a <aclass="reference internal"href="../Components/Locks.html"><spanclass="doc std std-doc">Lock</span></a> on the storage
door. It’s a simple lock that requires the one entering to carry an object named
<codeclass="docutils literal notranslate"><spanclass="pre"><shopname>-storekey</span></code>. We even create such a key object and drop it in the shop for the new shop
keeper to pick up.</p>
<blockquote>
<div><p>If players are given the right to name their own objects, this simple lock is not very secure and
you need to come up with a more robust lock-key solution.</p>
</div></blockquote>
<blockquote>
<div><p>We don’t add any descriptions to all these objects so looking “at” them will not be too thrilling.
You could add better default descriptions as part of the <codeclass="docutils literal notranslate"><spanclass="pre">@buildshop</span></code> command or leave descriptions
this up to the Builder.</p>
</div></blockquote>
</section>
<sectionid="the-shop-is-open-for-business">
<h2>The shop is open for business!<aclass="headerlink"href="#the-shop-is-open-for-business"title="Permalink to this headline">¶</a></h2>
<p>We now have a functioning shop and an easy way for Builders to create it. All you need now is to
<codeclass="docutils literal notranslate"><spanclass="pre">@open</span></code> a new exit from the rest of the game into the shop and put some sell-able items in the store
room. Our shop does have some shortcomings:</p>
<ulclass="simple">
<li><p>For Characters to be able to buy stuff they need to also have the <codeclass="docutils literal notranslate"><spanclass="pre">gold</span></code> Attribute set on
themselves.</p></li>
<li><p>We manually remove the “door” exit from our items for sale. But what if there are other unsellable
items in the store room? What if the shop owner walks in there for example - anyone in the store
could then buy them for 1 gold.</p></li>
<li><p>What if someone else were to buy the item we’re looking at just before we decide to buy it? It
would then be gone and the counter be wrong - the shop would pass us the next item in the list.</p></li>
</ul>
<p>Fixing these issues are left as an exercise.</p>
<p>If you want to keep the shop fully NPC-run you could add a <aclass="reference internal"href="../Components/Scripts.html"><spanclass="doc std std-doc">Script</span></a> to restock the shop’s
store room regularly. This shop example could also easily be owned by a human Player (run for them
by a hired NPC) - the shop owner would get the key to the store room and be responsible for keeping