<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">interval</span><spanclass="o">=</span><spanclass="mi">60</span><spanclass="c1"># 1 min repeat</span>
<p>In <codeclass="docutils literal notranslate"><spanclass="pre">mygame/typeclasses/scripts.py</span></code> is the <codeclass="docutils literal notranslate"><spanclass="pre">Script</span></code> class which inherits from <codeclass="docutils literal notranslate"><spanclass="pre">DefaultScript</span></code>
already. This is provided as your own base class to do with what you like: You can tweak <codeclass="docutils literal notranslate"><spanclass="pre">Script</span></code> if
you want to change the default behavior and it is usually convenient to inherit from this instead.
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">desc</span><spanclass="o">=</span><spanclass="s2">"Gives random weather messages."</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">interval</span><spanclass="o">=</span><spanclass="mi">60</span><spanclass="o">*</span><spanclass="mi">5</span><spanclass="c1"># every 5 minutes</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">persistent</span><spanclass="o">=</span><spanclass="bp">True</span><spanclass="c1"># will survive reload</span>
<p>If we put this script on a room, it will randomly report some weather
to everyone in the room every 5 minutes.</p>
<p>To activate it, just add it to the script handler (<codeclass="docutils literal notranslate"><spanclass="pre">scripts</span></code>) on an
<aclass="reference internal"href="Objects.html"><spanclass="doc">Room</span></a>. That object becomes <codeclass="docutils literal notranslate"><spanclass="pre">self.obj</span></code> in the example above. Here we
put it on a room called <codeclass="docutils literal notranslate"><spanclass="pre">myroom</span></code>:</p>
<div><p>Note that <codeclass="docutils literal notranslate"><spanclass="pre">typeclasses</span></code> in your game dir is added to the setting <codeclass="docutils literal notranslate"><spanclass="pre">TYPECLASS_PATHS</span></code>.
Therefore we don’t need to give the full path (<codeclass="docutils literal notranslate"><spanclass="pre">typeclasses.scripts.Weather</span></code>
but only <codeclass="docutils literal notranslate"><spanclass="pre">scripts.Weather</span></code> above.</p>
</div></blockquote>
<p>You can also create scripts using the <codeclass="docutils literal notranslate"><spanclass="pre">evennia.create_script</span></code> function:</p>
<p>Note that if you were to give a keyword argument to <codeclass="docutils literal notranslate"><spanclass="pre">create_script</span></code>, that would
override the default value in your Typeclass. So for example, here is an instance
of the weather script that runs every 10 minutes instead (and also not survive
<p>From in-game you can use the <codeclass="docutils literal notranslate"><spanclass="pre">@script</span></code> command to launch the Script on things:</p>
<p>You can conveniently view and kill running Scripts by using the <codeclass="docutils literal notranslate"><spanclass="pre">@scripts</span></code>
<h2>Properties and functions defined on Scripts<aclass="headerlink"href="#properties-and-functions-defined-on-scripts"title="Permalink to this headline">¶</a></h2>
<p>A Script has all the properties of a typeclassed object, such as <codeclass="docutils literal notranslate"><spanclass="pre">db</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">ndb</span></code>(see
<aclass="reference internal"href="Typeclasses.html"><spanclass="doc">Typeclasses</span></a>). Setting <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> is useful in order to manage scripts (delete them by name
etc). These are usually set up in the Script’s typeclass, but can also be assigned on the fly as
keyword arguments to <codeclass="docutils literal notranslate"><spanclass="pre">evennia.create_script</span></code>.</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">desc</span></code> - an optional description of the script’s function. Seen in script listings.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">interval</span></code> - how often the script should run. If <codeclass="docutils literal notranslate"><spanclass="pre">interval</span><spanclass="pre">==</span><spanclass="pre">0</span></code> (default), this script has no
timing component, will not repeat and will exist forever. This is useful for Scripts used for
storage or acting as bases for various non-time dependent game systems.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">start_delay</span></code> - (bool), if we should wait <codeclass="docutils literal notranslate"><spanclass="pre">interval</span></code> seconds before firing for the first time or
not.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">repeats</span></code> - How many times we should repeat, assuming <codeclass="docutils literal notranslate"><spanclass="pre">interval</span><spanclass="pre">></span><spanclass="pre">0</span></code>. If repeats is set to <codeclass="docutils literal notranslate"><spanclass="pre"><=</span><spanclass="pre">0</span></code>,
the script will repeat indefinitely. Note that <em>each</em> firing of the script (including the first one)
counts towards this value. So a <codeclass="docutils literal notranslate"><spanclass="pre">Script</span></code> with <codeclass="docutils literal notranslate"><spanclass="pre">start_delay=False</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">repeats=1</span></code> will start,
immediately fire and shut down right away.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">persistent</span></code>- if this script should survive a server <em>reset</em> or server <em>shutdown</em>. (You don’t need
to set this for it to survive a normal reload - the script will be paused and seamlessly restart
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">obj</span></code> - the <aclass="reference internal"href="Objects.html"><spanclass="doc">Object</span></a> this script is attached to (if any). You should not need to set
this manually. If you add the script to the Object with <codeclass="docutils literal notranslate"><spanclass="pre">myobj.scripts.add(myscriptpath)</span></code> or give
<codeclass="docutils literal notranslate"><spanclass="pre">myobj</span></code> as an argument to the <codeclass="docutils literal notranslate"><spanclass="pre">utils.create.create_script</span></code> function, the <codeclass="docutils literal notranslate"><spanclass="pre">obj</span></code> property will be set
to <codeclass="docutils literal notranslate"><spanclass="pre">myobj</span></code> for you.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">at_script_creation()</span></code> - this is usually where the script class sets things like <codeclass="docutils literal notranslate"><spanclass="pre">interval</span></code> and
<codeclass="docutils literal notranslate"><spanclass="pre">repeats</span></code>; things that control how the script runs. It is only called once - when the script is
first created.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">is_valid()</span></code> - determines if the script should still be running or not. This is called when
running <codeclass="docutils literal notranslate"><spanclass="pre">obj.scripts.validate()</span></code>, which you can run manually, but which is also called by Evennia
during certain situations such as reloads. This is also useful for using scripts as state managers.
If the method returns <codeclass="docutils literal notranslate"><spanclass="pre">False</span></code>, the script is stopped and cleanly removed.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">at_start()</span></code> - this is called when the script starts or is unpaused. For persistent scripts this
is at least once ever server startup. Note that this will <em>always</em> be called right away, also if
<codeclass="docutils literal notranslate"><spanclass="pre">start_delay</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">True</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">at_repeat()</span></code> - this is called every <codeclass="docutils literal notranslate"><spanclass="pre">interval</span></code> seconds, or not at all. It is called right away at
startup, unless <codeclass="docutils literal notranslate"><spanclass="pre">start_delay</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">True</span></code>, in which case the system will wait <codeclass="docutils literal notranslate"><spanclass="pre">interval</span></code> seconds
before calling.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">at_stop()</span></code> - this is called when the script stops for whatever reason. It’s a good place to do
custom cleanup.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">at_server_reload()</span></code> - this is called whenever the server is warm-rebooted (e.g. with the
<codeclass="docutils literal notranslate"><spanclass="pre">@reload</span></code> command). It’s a good place to save non-persistent data you might want to survive a
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">at_server_shutdown()</span></code> - this is called when a system reset or systems shutdown is invoked.</p></li>
</ul>
<p>Running methods (usually called automatically by the engine, but possible to also invoke manually)</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">start()</span></code> - this will start the script. This is called automatically whenever you add a new script
to a handler. <codeclass="docutils literal notranslate"><spanclass="pre">at_start()</span></code> will be called.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">stop()</span></code> - this will stop the script and delete it. Removing a script from a handler will stop it
automatically. <codeclass="docutils literal notranslate"><spanclass="pre">at_stop()</span></code> will be called.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">pause()</span></code> - this pauses a running script, rendering it inactive, but not deleting it. All
properties are saved and timers can be resumed. This is called automatically when the server reloads
and will <em>not</em> lead to the <em>at_stop()</em> hook being called. This is a suspension of the script, not a
change of state.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">unpause()</span></code> - resumes a previously paused script. The <codeclass="docutils literal notranslate"><spanclass="pre">at_start()</span></code> hook <em>will</em> be called to allow
it to reclaim its internal state. Timers etc are restored to what they were before pause. The server
automatically unpauses all paused scripts after a server reload.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">force_repeat()</span></code> - this will forcibly step the script, regardless of when it would otherwise have
fired. The timer will reset and the <codeclass="docutils literal notranslate"><spanclass="pre">at_repeat()</span></code> hook is called as normal. This also counts towards
the total number of repeats, if limited.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">time_until_next_repeat()</span></code> - for timed scripts, this returns the time in seconds until it next
fires. Returns <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code> if <codeclass="docutils literal notranslate"><spanclass="pre">interval==0</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">remaining_repeats()</span></code> - if the Script should run a limited amount of times, this tells us how many
are currently left.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">reset_callcount(value=0)</span></code> - this allows you to reset the number of times the Script has fired. It
only makes sense if <codeclass="docutils literal notranslate"><spanclass="pre">repeats</span><spanclass="pre">></span><spanclass="pre">0</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">restart(interval=None,</span><spanclass="pre">repeats=None,</span><spanclass="pre">start_delay=None)</span></code> - this method allows you to restart the
Script in-place with different run settings. If you do, the <codeclass="docutils literal notranslate"><spanclass="pre">at_stop</span></code> hook will be called and the
Script brought to a halt, then the <codeclass="docutils literal notranslate"><spanclass="pre">at_start</span></code> hook will be called as the Script starts up with your
(possibly changed) settings. Any keyword left at <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code> means to not change the original setting.</p></li>
<p>Henceforth you can then get it back by searching for its key or other identifier with
<codeclass="docutils literal notranslate"><spanclass="pre">evennia.search_script</span></code>. In-game, the <codeclass="docutils literal notranslate"><spanclass="pre">scripts</span></code> command will show all scripts.</p>
<p>Evennia supplies a convenient “container” called <codeclass="docutils literal notranslate"><spanclass="pre">GLOBAL_SCRIPTS</span></code> that can offer an easy
way to access global scripts. If you know the name (key) of the script you can get it like so:</p>
<div><p>Note that global scripts appear as properties on <codeclass="docutils literal notranslate"><spanclass="pre">GLOBAL_SCRIPTS</span></code> based on their <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code>.
If you were to create two global scripts with the same <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> (even with different typeclasses),
the <codeclass="docutils literal notranslate"><spanclass="pre">GLOBAL_SCRIPTS</span></code> container will only return one of them (which one depends on order in
<p>There are two ways to make a script appear as a property on <codeclass="docutils literal notranslate"><spanclass="pre">GLOBAL_SCRIPTS</span></code>. The first is
to manually create a new global script with <codeclass="docutils literal notranslate"><spanclass="pre">create_script</span></code> as mentioned above. Often you want this
to happen automatically when the server starts though. For this you can use the setting
<p>Here the key (<codeclass="docutils literal notranslate"><spanclass="pre">myscript</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">storagescript</span></code> above) is required, all other fields are optional. If
<codeclass="docutils literal notranslate"><spanclass="pre">typeclass</span></code> is not given, a script of type <codeclass="docutils literal notranslate"><spanclass="pre">settings.BASE_SCRIPT_TYPECLASS</span></code> is assumed. The keys
related to timing and intervals are only needed if the script is timed.</p>
<p>Evennia will use the information in <codeclass="docutils literal notranslate"><spanclass="pre">settings.GLOBAL_SCRIPTS</span></code> to automatically create and start
these
scripts when the server starts (unless they already exist, based on their <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code>). You need to reload
the server before the setting is read and new scripts become available. You can then find the <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code>
you gave as properties on <codeclass="docutils literal notranslate"><spanclass="pre">evennia.GLOBAL_SCRIPTS</span></code>
<div><p>Note: Make sure that your Script typeclass does not have any critical errors. If so, you’ll see
errors in your log and your Script will temporarily fall back to being a <codeclass="docutils literal notranslate"><spanclass="pre">DefaultScript</span></code> type.</p>
<p>That is, if the script is deleted, next time you get it from <codeclass="docutils literal notranslate"><spanclass="pre">GLOBAL_SCRIPTS</span></code>, it will use the
<div><p>Note that if your goal with the Script is to store persistent data, you should set it as
<codeclass="docutils literal notranslate"><spanclass="pre">persistent=True</span></code>, either in <codeclass="docutils literal notranslate"><spanclass="pre">settings.GLOBAL_SCRIPTS</span></code> or in the Scripts typeclass. Otherwise any
data you wanted to store on it will be gone (since a new script of the same name is restarted
<div><p>Note: Since <codeclass="docutils literal notranslate"><spanclass="pre">evennia/contrib/tutorial_examples</span></code> is in the default setting
<codeclass="docutils literal notranslate"><spanclass="pre">TYPECLASS_PATHS</span></code>, we only need to specify the final part of the path,
that is, <codeclass="docutils literal notranslate"><spanclass="pre">bodyfunctions.BodyFunctions</span></code>.</p>
</div></blockquote>
<p>If you want to inflict your flatulence script on another person, place or
<p>This will kill the script again. You can use the <codeclass="docutils literal notranslate"><spanclass="pre">@scripts</span></code> command to list all
active scripts in the game, if any (there are none by default).</p>
<p>For another example of a Script in use, check out the <aclass="reference external"href="https://github.com/evennia/evennia/wiki/Turn%20based%20Combat%20System">Turn Based Combat System