<p>For an introduction and motivation to using batch processors, see <aclass="reference internal"href="Batch-Processors.html"><spanclass="doc">here</span></a>. This
page describes the Batch-<em>code</em> processor. The Batch-<em>command</em> one is covered [here](Batch-Command-
<p>Where <codeclass="docutils literal notranslate"><spanclass="pre">path.to.batchcodefile</span></code> is the path to a <em>batch-code file</em>. Such a file should have a name
ending in “<codeclass="docutils literal notranslate"><spanclass="pre">.py</span></code>” (but you shouldn’t include that in the path). The path is given like a python path
relative to a folder you define to hold your batch files, set by <codeclass="docutils literal notranslate"><spanclass="pre">BATCH_IMPORT_PATH</span></code> in your
settings. Default folder is (assuming your game is called “mygame”) <codeclass="docutils literal notranslate"><spanclass="pre">mygame/world/</span></code>. So if you want
to run the example batch file in <codeclass="docutils literal notranslate"><spanclass="pre">mygame/world/batch_code.py</span></code>, you could simply use</p>
<p>This will try to run through the entire batch file in one go. For more gradual, <em>interactive</em>
control you can use the <codeclass="docutils literal notranslate"><spanclass="pre">/interactive</span></code> switch. The switch <codeclass="docutils literal notranslate"><spanclass="pre">/debug</span></code> will put the processor in
<em>debug</em> mode. Read below for more info.</p>
<p>A batch-code file is a normal Python file. The difference is that since the batch processor loads
and executes the file rather than importing it, you can reliably update the file, then call it
again, over and over and see your changes without needing to <codeclass="docutils literal notranslate"><spanclass="pre">@reload</span></code> the server. This makes for
easy testing. In the batch-code file you have also access to the following global variables:</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code> - This is a reference to the object running the batchprocessor.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">DEBUG</span></code> - This is a boolean that lets you determine if this file is currently being run in debug-
mode or not. See below how this can be useful.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code> as the first on a line marks the start of a <em>code</em> block. It will last until the beginning
of another marker or the end of the file. Code blocks contain functional python code. Each <codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code>
block will be run in complete isolation from other parts of the file, so make sure it’s self-
contained.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">#HEADER</span></code> as the first on a line marks the start of a <em>header</em> block. It lasts until the next
marker or the end of the file. This is intended to hold imports and variables you will need for all
other blocks .All python code defined in a header block will always be inserted at the top of every
<codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code> blocks in the file. You may have more than one <codeclass="docutils literal notranslate"><spanclass="pre">#HEADER</span></code> block, but that is equivalent to
having one big one. Note that you can’t exchange data between code blocks, so editing a header-
variable in one code block won’t affect that variable in any other code block!</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">#INSERT</span><spanclass="pre">path.to.file</span></code> will insert another batchcode (Python) file at that position.</p></li>
<li><p>A <codeclass="docutils literal notranslate"><spanclass="pre">#</span></code> that is not starting a <codeclass="docutils literal notranslate"><spanclass="pre">#HEADER</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">#INSERT</span></code> instruction is considered a comment.</p></li>
<p>Below is a version of the example file found in <codeclass="docutils literal notranslate"><spanclass="pre">evennia/contrib/tutorial_examples/</span></code>.</p>
<spanclass="c1"># caller points to the one running the script</span>
<spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"A red button was created."</span><spanclass="p">)</span>
<spanclass="c1"># importing more code from another batch-code file</span>
<spanclass="n">string</span><spanclass="o">=</span><spanclass="s2">"A </span><spanclass="si">%s</span><spanclass="s2"> and </span><spanclass="si">%s</span><spanclass="s2"> were created."</span>
<p>The batch script will run to the end and tell you it completed. You will also get messages that the
button and the two pieces of furniture were created. Look around and you should see the button
there. But you won’t see any chair nor a table! This is because we ran this with the <codeclass="docutils literal notranslate"><spanclass="pre">/debug</span></code>
switch, which is directly visible as <codeclass="docutils literal notranslate"><spanclass="pre">DEBUG==True</span></code> inside the script. In the above example we
handled this state by deleting the chair and table again.</p>
<p>The debug mode is intended to be used when you test out a batchscript. Maybe you are looking for
bugs in your code or try to see if things behave as they should. Running the script over and over
would then create an ever-growing stack of chairs and tables, all with the same name. You would have
to go back and painstakingly delete them later.</p>
<p>Interactive mode works very similar to the [batch-command processor counterpart](Batch-Command-
Processor). It allows you more step-wise control over how the batch file is executed. This is useful
for debugging or for picking and choosing only particular blocks to run. Use <codeclass="docutils literal notranslate"><spanclass="pre">@batchcode</span></code> with the
<codeclass="docutils literal notranslate"><spanclass="pre">/interactive</span></code> flag to enter interactive mode.</p>
<p>This shows that you are on the first <codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code> block, the first of only two commands in this batch
file. Observe that the block has <em>not</em> actually been executed at this point!</p>
<p>To take a look at the full code snippet you are about to run, use <codeclass="docutils literal notranslate"><spanclass="pre">ll</span></code> (a batch-processor version of
<spanclass="c1"># caller points to the one running the script</span>
<spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"A red button was created."</span><spanclass="p">)</span>
<p>Compare with the example code given earlier. Notice how the content of <codeclass="docutils literal notranslate"><spanclass="pre">#HEADER</span></code> has been pasted at
the top of the <codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code> block. Use <codeclass="docutils literal notranslate"><spanclass="pre">pp</span></code> to actually execute this block (this will create the button
and give you a message). Use <codeclass="docutils literal notranslate"><spanclass="pre">nn</span></code> (next) to go to the next command. Use <codeclass="docutils literal notranslate"><spanclass="pre">hh</span></code> for a list of commands.</p>
<p>If there are tracebacks, fix them in the batch file, then use <codeclass="docutils literal notranslate"><spanclass="pre">rr</span></code> to reload the file. You will
still be at the same code block and can rerun it easily with <codeclass="docutils literal notranslate"><spanclass="pre">pp</span></code> as needed. This makes for a simple
debug cycle. It also allows you to rerun individual troublesome blocks - as mentioned, in a large
batch file this can be very useful (don’t forget the <codeclass="docutils literal notranslate"><spanclass="pre">/debug</span></code> mode either).</p>
<p>Use <codeclass="docutils literal notranslate"><spanclass="pre">nn</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">bb</span></code> (next and back) to step through the file; e.g. <codeclass="docutils literal notranslate"><spanclass="pre">nn</span><spanclass="pre">12</span></code> will jump 12 steps forward
(without processing any blocks in between). All normal commands of Evennia should work too while
<p>Global variables won’t work in code batch files, each block is executed as stand-alone environments.
<codeclass="docutils literal notranslate"><spanclass="pre">#HEADER</span></code> blocks are literally pasted on top of each <codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code> block so updating some header-variable
in your block will not make that change available in another block. Whereas a python execution
limitation, allowing this would also lead to very hard-to-debug code when using the interactive mode</p>
<ulclass="simple">
<li><p>this would be a classical example of “spaghetti code”.</p></li>
</ul>
<p>The main practical issue with this is when building e.g. a room in one code block and later want to
connect that room with a room you built in the current block. There are two ways to do this:</p>
<li><p>Perform a database search for the name of the room you created (since you cannot know in advance
which dbref it got assigned). The problem is that a name may not be unique (you may have a lot of “A
dark forest” rooms). There is an easy way to handle this though - use <aclass="reference internal"href="Tags.html"><spanclass="doc">Tags</span></a> or <em>Aliases</em>. You
can assign any number of tags and/or aliases to any object. Make sure that one of those tags or
aliases is unique to the room (like “room56”) and you will henceforth be able to always uniquely
search and find it later.</p></li>
<li><p>Use the <codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code> global property as an inter-block storage. For example, you could have a
dictionary of room references in an <codeclass="docutils literal notranslate"><spanclass="pre">ndb</span></code>:</p>
<p>Note how we check in <codeclass="docutils literal notranslate"><spanclass="pre">#HEADER</span></code> if <codeclass="docutils literal notranslate"><spanclass="pre">caller.ndb.all_rooms</span></code> doesn’t already exist before creating the
dict. Remember that <codeclass="docutils literal notranslate"><spanclass="pre">#HEADER</span></code> is copied in front of every <codeclass="docutils literal notranslate"><spanclass="pre">#CODE</span></code> block. Without that <codeclass="docutils literal notranslate"><spanclass="pre">if</span></code> statement
<h3>Don’t treat a batchcode file like any Python file<aclass="headerlink"href="#don-t-treat-a-batchcode-file-like-any-python-file"title="Permalink to this headline">¶</a></h3>
<h3>Don’t let code rely on the batch-file’s real file path<aclass="headerlink"href="#don-t-let-code-rely-on-the-batch-file-s-real-file-path"title="Permalink to this headline">¶</a></h3>
<li><aclass="reference internal"href="#no-communication-between-code-blocks">No communication between code blocks</a></li>
<li><aclass="reference internal"href="#don-t-treat-a-batchcode-file-like-any-python-file">Don’t treat a batchcode file like any Python file</a></li>
<li><aclass="reference internal"href="#don-t-let-code-rely-on-the-batch-file-s-real-file-path">Don’t let code rely on the batch-file’s real file path</a></li>