evennia/docs/6.x/Components/Channels.html
2026-02-15 19:06:04 +01:00

552 lines
No EOL
46 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Channels &#8212; Evennia latest documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
<link rel="stylesheet" type="text/css" href="../_static/nature.css?v=279e0f84" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css?v=e4a91a55" />
<script src="../_static/documentation_options.js?v=c6e86fd7"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Msg" href="Msg.html" />
<link rel="prev" title="Scripts" href="Scripts.html" />
</head><body>
<div class="related" role="navigation" aria-label="Related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Msg.html" title="Msg"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Scripts.html" title="Scripts"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Channels</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="channels">
<h1>Channels<a class="headerlink" href="#channels" title="Link to this heading"></a></h1>
<p>In a multiplayer game, players often need other means of in-game communication
than moving to the same room and use <code class="docutils literal notranslate"><span class="pre">say</span></code> or <code class="docutils literal notranslate"><span class="pre">emote</span></code>.</p>
<p><em>Channels</em> allows Evennias to act as a fancy chat program. When a player is
connected to a channel, sending a message to it will automatically distribute
it to every other subscriber.</p>
<p>Channels can be used both for chats between <a class="reference internal" href="Accounts.html"><span class="std std-doc">Accounts</span></a> and between
<a class="reference internal" href="Objects.html"><span class="std std-doc">Objects</span></a> (usually Characters). Chats could be both OOC
(out-of-character) or IC (in-charcter) in nature. Some examples:</p>
<ul class="simple">
<li><p>A support channel for contacting staff (OOC)</p></li>
<li><p>A general chat for discussing anything and foster community (OOC)</p></li>
<li><p>Admin channel for private staff discussions (OOC)</p></li>
<li><p>Private guild channels for planning and organization (IC/OOC depending on game)</p></li>
<li><p>Cyberpunk-style retro chat rooms (IC)</p></li>
<li><p>In-game radio channels (IC)</p></li>
<li><p>Group telepathy (IC)</p></li>
<li><p>Walkie-talkies (IC)</p></li>
</ul>
<div class="versionchanged">
<p><span class="versionmodified changed">Changed in version 1.0: </span>Channel system changed to use a central channel command and nicks instead of
auto-generated channel-commands and -cmdset. ChannelHandler was removed.</p>
</div>
<section id="working-with-channels">
<h2>Working with channels<a class="headerlink" href="#working-with-channels" title="Link to this heading"></a></h2>
<section id="viewing-and-joining-channels">
<h3>Viewing and joining channels<a class="headerlink" href="#viewing-and-joining-channels" title="Link to this heading"></a></h3>
<p>In the default command set, channels are all handled via the mighty <a class="reference internal" href="../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel" title="evennia.commands.default.comms.CmdChannel"><span class="xref myst py py-class">channel command</span></a>, <code class="docutils literal notranslate"><span class="pre">channel</span></code> (or <code class="docutils literal notranslate"><span class="pre">chan</span></code>). By default, this command will assume all entities dealing with channels are <code class="docutils literal notranslate"><span class="pre">Accounts</span></code>.</p>
<p>Viewing channels</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel - shows your subscriptions
channel/all - shows all subs available to you
channel/who - shows who subscribes to this channel
</pre></div>
</div>
<p>To join/unsub a channel do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/sub channelname
channel/unsub channelname
</pre></div>
</div>
<p>If you temporarily dont want to hear the channel for a while (without actually
unsubscribing), you can mute it:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/mute channelname
channel/unmute channelname
</pre></div>
</div>
</section>
<section id="talk-on-channels">
<h3>Talk on channels<a class="headerlink" href="#talk-on-channels" title="Link to this heading"></a></h3>
<p>To speak on a channel, do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel public Hello world!
</pre></div>
</div>
<p>If the channel-name has spaces in it, you need to use a <code class="docutils literal notranslate"><span class="pre">=</span></code>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel rest room = Hello world!
</pre></div>
</div>
<p>Now, this is more to type than wed like, so when you join a channel, the
system automatically sets up an personal alias so you can do this instead:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>public Hello world
</pre></div>
</div>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>This shortcut will not work if the channel-name has spaces in it.
So channels with long names should make sure to provide a one-word alias as
well.</p>
</div>
<p>Any user can make up their own channel aliases:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/alias public = foo;bar
</pre></div>
</div>
<p>You can now just do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>foo Hello world!
bar Hello again!
</pre></div>
</div>
<p>And even remove the default one if they dont want to use it</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/unalias public
public Hello (gives a command-not-found error now)
</pre></div>
</div>
<p>But you can also use your alias with the <code class="docutils literal notranslate"><span class="pre">channel</span></code> command:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel foo Hello world!
</pre></div>
</div>
<blockquote>
<div><p>What happens when aliasing is that a <a class="reference internal" href="Nicks.html"><span class="std std-doc">nick</span></a> is created that maps your
alias + argument onto calling the <code class="docutils literal notranslate"><span class="pre">channel</span></code> command. So when you enter <code class="docutils literal notranslate"><span class="pre">foo</span> <span class="pre">hello</span></code>,
what the server sees is actually <code class="docutils literal notranslate"><span class="pre">channel</span> <span class="pre">foo</span> <span class="pre">=</span> <span class="pre">hello</span></code>. The system is also
clever enough to know that whenever you search for channels, your channel-nicks
should also be considered so as to convert your input to an existing channel name.</p>
</div></blockquote>
<p>You can check if you missed channel conversations by viewing the channels
scrollback with</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/history public
</pre></div>
</div>
<p>This retrieves the last 20 lines of text (also from a time when you were
offline). You can step further back by specifying how many lines back to start:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/history public = 30
</pre></div>
</div>
<p>This again retrieve 20 lines, but starting 30 lines back (so youll get lines
30-50 counting backwards).</p>
</section>
<section id="channel-administration">
<h3>Channel administration<a class="headerlink" href="#channel-administration" title="Link to this heading"></a></h3>
<p>Evennia can create certain channels when it starts. Channels can also
be created on-the-fly in-game.</p>
<section id="default-channels-from-settings">
<h4>Default channels from settings<a class="headerlink" href="#default-channels-from-settings" title="Link to this heading"></a></h4>
<p>You can specify default channels you want to auto-create from the Evennia
settings. New accounts will automatically be subscribed to such default channels if
they have the right permissions. This is a list of one dict per channel (example is the default public channel):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/server/conf/settings.py</span>
<span class="n">DEFAULT_CHANNELS</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="s2">&quot;Public&quot;</span><span class="p">,</span>
<span class="s2">&quot;aliases&quot;</span><span class="p">:</span> <span class="p">(</span><span class="s2">&quot;pub&quot;</span><span class="p">,),</span>
<span class="s2">&quot;desc&quot;</span><span class="p">:</span> <span class="s2">&quot;Public discussion&quot;</span><span class="p">,</span>
<span class="s2">&quot;locks&quot;</span><span class="p">:</span> <span class="s2">&quot;control:perm(Admin);listen:all();send:all()&quot;</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">]</span>
</pre></div>
</div>
<p>Each dict is fed as <code class="docutils literal notranslate"><span class="pre">**channeldict</span></code> into the <a class="reference internal" href="../api/evennia.utils.create.html#evennia.utils.create.create_channel" title="evennia.utils.create.create_channel"><span class="xref myst py py-func">create_channel</span></a> function, and thus supports all the same keywords.</p>
<p>Evennia also has two system-related channels:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">CHANNEL_MUDINFO</span></code> is a dict describing the “MudInfo” channel. This is assumed to exist and is a place for Evennia to echo important server information. The idea is that server admins and staff can subscribe to this channel to stay in the loop.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CHANNEL_CONECTINFO</span></code> is not defined by default. It will receive connect/disconnect-messages and could be visible also for regular players. If not given, connection-info will just be logged quietly.</p></li>
</ul>
</section>
<section id="managing-channels-in-game">
<h4>Managing channels in-game<a class="headerlink" href="#managing-channels-in-game" title="Link to this heading"></a></h4>
<p>To create/destroy a new channel on the fly you can do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/create channelname;alias;alias = description
channel/destroy channelname
</pre></div>
</div>
<p>Aliases are optional but can be good for obvious shortcuts everyone may want to
use. The description is used in channel-listings. You will automatically join a
channel you created and will be controlling it. You can also use <code class="docutils literal notranslate"><span class="pre">channel/desc</span></code> to
change the description on a channel you own later.</p>
<p>If you control a channel you can also kick people off it:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/boot mychannel = annoyinguser123 : stop spamming!
</pre></div>
</div>
<p>The last part is an optional reason to send to the user before they are booted.
You can give a comma-separated list of channels to kick the same user from all
those channels at once. The user will be unsubbed from the channel and all
their aliases will be wiped. But they can still rejoin if they like.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/ban mychannel = annoyinguser123
channel/ban - view bans
channel/unban mychannel = annoyinguser123
</pre></div>
</div>
<p>Banning adds the user to the channels blacklist. This means they will not be
able to <em>rejoin</em> if you boot them. You will need to run <code class="docutils literal notranslate"><span class="pre">channel/boot</span></code> to
actually kick them out.</p>
<p>See the <a class="reference internal" href="../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel" title="evennia.commands.default.comms.CmdChannel"><span class="xref myst py py-class">Channel command</span></a> api docs (and in-game help) for more details.</p>
<p>Admin-level users can also modify channels <a class="reference internal" href="Locks.html"><span class="std std-doc">locks</span></a>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>channel/lock buildchannel = listen:all();send:perm(Builders)
</pre></div>
</div>
<p>Channels use three lock-types by default:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">listen</span></code> - who may listen to the channel. Users without this access will not
even be able to join the channel and it will not appear in listings for them.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">send</span></code> - who may send to the channel.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">control</span></code> - this is assigned to you automatically when you create the channel. With
control over the channel you can edit it, boot users and do other management tasks.</p></li>
</ul>
</section>
<section id="restricting-channel-administration">
<h4>Restricting channel administration<a class="headerlink" href="#restricting-channel-administration" title="Link to this heading"></a></h4>
<p>By default everyone can use the channel command (<a class="reference internal" href="../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel" title="evennia.commands.default.comms.CmdChannel"><span class="xref myst py py-class">evennia.commands.default.comms.CmdChannel</span></a>) to create channels and will then control the channels they created (to boot/ban people etc). If you as a developer does not want regular players to do this (perhaps you want only staff to be able to spawn new channels), you can override the <code class="docutils literal notranslate"><span class="pre">channel</span></code> command and change its <code class="docutils literal notranslate"><span class="pre">locks</span></code> property.</p>
<p>The default <code class="docutils literal notranslate"><span class="pre">help</span></code> command has the following <code class="docutils literal notranslate"><span class="pre">locks</span></code> property:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not perm(channel_banned); admin:all(); manage:all(); changelocks: perm(Admin)&quot;</span>
</pre></div>
</div>
<p>This is a regular <a class="reference internal" href="Locks.html"><span class="std std-doc">lockstring</span></a>.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">cmd:</span> <span class="pre">pperm(channel_banned)</span></code> - The <code class="docutils literal notranslate"><span class="pre">cmd</span></code> locktype is the standard one used for all Commands.
an accessing object failing this will not even know that the command exists. The <code class="docutils literal notranslate"><span class="pre">pperm()</span></code> lockfunc
checks an on-account [Permission](Building Permissions) channel_banned - and the <code class="docutils literal notranslate"><span class="pre">not</span></code> means
that if they <em>have</em> that permission they are cut off from using the <code class="docutils literal notranslate"><span class="pre">channel</span></code> command. You usually
dont need to change this lock.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">admin:all()</span></code> - this is a lock checked in the <code class="docutils literal notranslate"><span class="pre">channel</span></code> command itself. It controls access to the
<code class="docutils literal notranslate"><span class="pre">/boot</span></code>, <code class="docutils literal notranslate"><span class="pre">/ban</span></code> and <code class="docutils literal notranslate"><span class="pre">/unban</span></code> switches (by default letting everyone use them).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">manage:all()</span></code> - this controls access to the <code class="docutils literal notranslate"><span class="pre">/create</span></code>, <code class="docutils literal notranslate"><span class="pre">/destroy</span></code>, <code class="docutils literal notranslate"><span class="pre">/desc</span></code> switches.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">changelocks:</span> <span class="pre">perm(Admin)</span></code> - this controls access to the <code class="docutils literal notranslate"><span class="pre">/lock</span></code> and <code class="docutils literal notranslate"><span class="pre">/unlock</span></code> switches. By
default this is something only [Admins](Building Permissions) can change.</p></li>
</ul>
<blockquote>
<div><p>Note - while <code class="docutils literal notranslate"><span class="pre">admin:all()</span></code> and <code class="docutils literal notranslate"><span class="pre">manage:all()</span></code> will let everyone use these switches, users
will still only be able to admin or destroy channels they actually control!</p>
</div></blockquote>
<p>If you only want (say) Builders and higher to be able to create and admin
channels you could override the <code class="docutils literal notranslate"><span class="pre">help</span></code> command and change the lockstring to:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># in for example mygame/commands/commands.py</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">default_cmds</span>
<span class="k">class</span><span class="w"> </span><span class="nc">MyCustomChannelCmd</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd: not pperm(channel_banned);admin:perm(Builder);manage:perm(Builder);changelocks:perm(Admin)&quot;</span>
</pre></div>
</div>
<p>Add this custom command to your default cmdset and regular users will now get an
access-denied error when trying to use use these switches.</p>
</section>
</section>
</section>
<section id="using-channels-in-code">
<h2>Using channels in code<a class="headerlink" href="#using-channels-in-code" title="Link to this heading"></a></h2>
<p>For most common changes, the default channel, the recipient hooks and possibly
overriding the <code class="docutils literal notranslate"><span class="pre">channel</span></code> command will get you very far. But you can also tweak
channels themselves.</p>
<section id="allowing-characters-to-use-channels">
<h3>Allowing Characters to use Channels<a class="headerlink" href="#allowing-characters-to-use-channels" title="Link to this heading"></a></h3>
<p>The default <code class="docutils literal notranslate"><span class="pre">channel</span></code> command (<a class="reference internal" href="../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel" title="evennia.commands.default.comms.CmdChannel"><span class="xref myst py py-class">evennia.commands.default.comms.CmdChannel</span></a>) sits in the <code class="docutils literal notranslate"><span class="pre">Account</span></code> <a class="reference internal" href="Command-Sets.html"><span class="std std-doc">command set</span></a>. It is set up such that it will always operate on <code class="docutils literal notranslate"><span class="pre">Accounts</span></code>, even if you were to add it to the <code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code>.</p>
<p>Its a one-line change to make this command accept non-account callers. But for convenience we provide a version for Characters/Objects. Just import <a class="reference internal" href="../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdObjectChannel" title="evennia.commands.default.comms.CmdObjectChannel"><span class="xref myst py py-class">evennia.commands.default.comms.CmdObjectChannel</span></a> and inherit from that instead.</p>
</section>
<section id="customizing-channel-output-and-behavior">
<h3>Customizing channel output and behavior<a class="headerlink" href="#customizing-channel-output-and-behavior" title="Link to this heading"></a></h3>
<p>When distributing a message, the channel will call a series of hooks on itself
and (more importantly) on each recipient. So you can customize things a lot by
just modifying hooks on your normal Object/Account typeclasses.</p>
<p>Internally, the message is sent with
<code class="docutils literal notranslate"><span class="pre">channel.msg(message,</span> <span class="pre">senders=sender,</span> <span class="pre">bypass_mute=False,</span> <span class="pre">**kwargs)</span></code>, where
<code class="docutils literal notranslate"><span class="pre">bypass_mute=True</span></code> means the message ignores muting (good for alerts or if you
delete the channel etc) and <code class="docutils literal notranslate"><span class="pre">**kwargs</span></code> are any extra info you may want to pass
to the hooks. The <code class="docutils literal notranslate"><span class="pre">senders</span></code> (its always only one in the default implementation
but could in principle be multiple) and <code class="docutils literal notranslate"><span class="pre">bypass_mute</span></code> are part of the <code class="docutils literal notranslate"><span class="pre">kwargs</span></code>
below:</p>
<ol class="arabic simple">
<li><p><code class="docutils literal notranslate"><span class="pre">channel.at_pre_msg(message,</span> <span class="pre">**kwargs)</span></code></p></li>
<li><p>For each recipient:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">message</span> <span class="pre">=</span> <span class="pre">recipient.at_pre_channel_msg(message,</span> <span class="pre">channel,</span> <span class="pre">**kwargs)</span></code> -
allows for the message to be tweaked per-receiver (for example coloring it depending
on the users preferences). If this method returns <code class="docutils literal notranslate"><span class="pre">False/None</span></code>, that
recipient is skipped.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">recipient.channel_msg(message,</span> <span class="pre">channel,</span> <span class="pre">**kwargs)</span></code> - actually sends to recipient.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">recipient.at_post_channel_msg(message,</span> <span class="pre">channel,</span> <span class="pre">**kwargs)</span></code> - any post-receive effects.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">channel.at_post_channel_msg(message,</span> <span class="pre">**kwargs)</span></code></p></li>
</ol>
<p>Note that <code class="docutils literal notranslate"><span class="pre">Accounts</span></code> and <code class="docutils literal notranslate"><span class="pre">Objects</span></code> both have their have separate sets of hooks.
So make sure you modify the set actually used by your subscribers (or both).
Default channels all use <code class="docutils literal notranslate"><span class="pre">Account</span></code> subscribers.</p>
</section>
<section id="channel-class">
<h3>Channel class<a class="headerlink" href="#channel-class" title="Link to this heading"></a></h3>
<p>Channels are <a class="reference internal" href="Typeclasses.html"><span class="std std-doc">Typeclassed</span></a> entities. This means they are persistent in the database, can have <a class="reference internal" href="Attributes.html"><span class="std std-doc">attributes</span></a> and <a class="reference internal" href="Tags.html"><span class="std std-doc">Tags</span></a> and can be easily extended.</p>
<p>To change which channel typeclass Evennia uses for default commands, change <code class="docutils literal notranslate"><span class="pre">settings.BASE_CHANNEL_TYPECLASS</span></code>. The base command class is <a class="reference internal" href="../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel" title="evennia.comms.comms.DefaultChannel"><span class="xref myst py py-class"><code class="docutils literal notranslate"><span class="pre">evennia.comms.comms.DefaultChannel</span></code></span></a>. There is an empty child class in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/channels.py</span></code>, same as for other typelass-bases.</p>
<p>In code you create a new channel with <code class="docutils literal notranslate"><span class="pre">evennia.create_channel</span></code> or
<code class="docutils literal notranslate"><span class="pre">Channel.create</span></code>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">create_channel</span><span class="p">,</span> <span class="n">search_object</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">typeclasses.channels</span><span class="w"> </span><span class="kn">import</span> <span class="n">Channel</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">create_channel</span><span class="p">(</span><span class="s2">&quot;my channel&quot;</span><span class="p">,</span> <span class="n">aliases</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;mychan&quot;</span><span class="p">],</span> <span class="n">locks</span><span class="o">=...</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=...</span><span class="p">)</span>
<span class="c1"># alternative</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">Channel</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="s2">&quot;my channel&quot;</span><span class="p">,</span> <span class="n">aliases</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;mychan&quot;</span><span class="p">],</span> <span class="n">locks</span><span class="o">=...</span><span class="p">)</span>
<span class="c1"># connect to it</span>
<span class="n">me</span> <span class="o">=</span> <span class="n">search_object</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s2">&quot;Foo&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">me</span><span class="p">)</span>
<span class="c1"># send to it (this will trigger the channel_msg hooks described earlier)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Hello world!&quot;</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="n">me</span><span class="p">)</span>
<span class="c1"># view subscriptions (the SubscriptionHandler handles all subs under the hood)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">has</span><span class="p">(</span><span class="n">me</span><span class="p">)</span> <span class="c1"># check we subbed</span>
<span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="c1"># get all subs</span>
<span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">online</span><span class="p">()</span> <span class="c1"># get only subs currently online</span>
<span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span> <span class="c1"># unsub all</span>
<span class="c1"># leave channel</span>
<span class="n">channel</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">me</span><span class="p">)</span>
<span class="c1"># permanently delete channel (will unsub everyone)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
</pre></div>
</div>
<p>The Channels <code class="docutils literal notranslate"><span class="pre">.connect</span></code> method will accept both <code class="docutils literal notranslate"><span class="pre">Account</span></code> and <code class="docutils literal notranslate"><span class="pre">Object</span></code> subscribers
and will handle them transparently.</p>
<p>The channel has many more hooks, both hooks shared with all typeclasses as well as special ones related to muting/banning etc. See the channel class for
details.</p>
</section>
<section id="channel-logging">
<h3>Channel logging<a class="headerlink" href="#channel-logging" title="Link to this heading"></a></h3>
<div class="versionchanged">
<p><span class="versionmodified changed">Changed in version 0.7: </span>Channels changed from using Msg to TmpMsg and optional log files.</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">Changed in version 1.0: </span>Channels stopped supporting Msg and TmpMsg, using only log files.</p>
</div>
<p>The channel messages are not stored in the database. A channel is instead always logged to a regular text log-file <code class="docutils literal notranslate"><span class="pre">mygame/server/logs/channel_&lt;channelname&gt;.log</span></code>. This is where <code class="docutils literal notranslate"><span class="pre">channels/history</span> <span class="pre">channelname</span></code> gets its data from. A channels log will rotate when it grows too big, which thus also automatically limits the max amount of history a user can view with
<code class="docutils literal notranslate"><span class="pre">/history</span></code>.</p>
<p>The log file name is set on the channel class as the <code class="docutils literal notranslate"><span class="pre">log_file</span></code> property. This
is a string that takes the formatting token <code class="docutils literal notranslate"><span class="pre">{channelname}</span></code> to be replaced with
the (lower-case) name of the channel. By default the log is written to in the
channels <code class="docutils literal notranslate"><span class="pre">at_post_channel_msg</span></code> method.</p>
</section>
<section id="properties-on-channels">
<h3>Properties on Channels<a class="headerlink" href="#properties-on-channels" title="Link to this heading"></a></h3>
<p>Channels have all the standard properties of a Typeclassed entity (<code class="docutils literal notranslate"><span class="pre">key</span></code>,
<code class="docutils literal notranslate"><span class="pre">aliases</span></code>, <code class="docutils literal notranslate"><span class="pre">attributes</span></code>, <code class="docutils literal notranslate"><span class="pre">tags</span></code>, <code class="docutils literal notranslate"><span class="pre">locks</span></code> etc). This is not an exhaustive list;
see the <a class="reference internal" href="../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel" title="evennia.comms.comms.DefaultChannel"><span class="xref myst py py-class">Channel api docs</span></a> for details.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">send_to_online_only</span></code> - this class boolean defaults to <code class="docutils literal notranslate"><span class="pre">True</span></code> and is a
sensible optimization since people offline people will not see the message anyway.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">log_file</span></code> - this is a string that determines the name of the channel log file. Default
is <code class="docutils literal notranslate"><span class="pre">&quot;channel_{channelname}.log&quot;</span></code>. The log file will appear in <code class="docutils literal notranslate"><span class="pre">settings.LOG_DIR</span></code> (usually
<code class="docutils literal notranslate"><span class="pre">mygame/server/logs/</span></code>). You should usually not change this.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">channel_prefix_string</span></code> - this property is a string to easily change how
the channel is prefixed. It takes the <code class="docutils literal notranslate"><span class="pre">channelname</span></code> format key. Default is <code class="docutils literal notranslate"><span class="pre">&quot;[{channelname}]</span> <span class="pre">&quot;</span></code>
and produces output like <code class="docutils literal notranslate"><span class="pre">[public]</span> <span class="pre">...</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">subscriptions</span></code> - this is the <a class="reference internal" href="../api/evennia.comms.models.html#evennia.comms.models.SubscriptionHandler" title="evennia.comms.models.SubscriptionHandler"><span class="xref myst py py-class">SubscriptionHandler</span></a>, which
has methods <code class="docutils literal notranslate"><span class="pre">has</span></code>, <code class="docutils literal notranslate"><span class="pre">add</span></code>, <code class="docutils literal notranslate"><span class="pre">remove</span></code>, <code class="docutils literal notranslate"><span class="pre">all</span></code>, <code class="docutils literal notranslate"><span class="pre">clear</span></code> and also <code class="docutils literal notranslate"><span class="pre">online</span></code> (to get
only actually online channel-members).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">wholist</span></code>, <code class="docutils literal notranslate"><span class="pre">mutelist</span></code>, <code class="docutils literal notranslate"><span class="pre">banlist</span></code> are properties that return a list of subscribers,
as well as who are currently muted or banned.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">channel_msg_nick_pattern</span></code> - this is a regex pattern for performing the in-place nick
replacement (detect that <code class="docutils literal notranslate"><span class="pre">channelalias</span> <span class="pre">&lt;msg</span></code> means that you want to send a message to a channel).
This pattern accepts an <code class="docutils literal notranslate"><span class="pre">{alias}</span></code> formatting marker. Dont mess with this unless you really
want to change how channels work.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">channel_msg_nick_replacement</span></code> - this is a string on the [nick replacement</p></li>
<li><p>form](./Nicks.md). It accepts the <code class="docutils literal notranslate"><span class="pre">{channelname}</span></code> formatting tag. This is strongly tied to the
<code class="docutils literal notranslate"><span class="pre">channel</span></code> command and is by default <code class="docutils literal notranslate"><span class="pre">channel</span> <span class="pre">{channelname}</span> <span class="pre">=</span> <span class="pre">$1</span></code>.</p></li>
</ul>
<p>Notable <code class="docutils literal notranslate"><span class="pre">Channel</span></code> hooks:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">at_pre_channel_msg(message,</span> <span class="pre">**kwargs)</span></code> - called before sending a message, to
modify it. Not used by default.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">msg(message,</span> <span class="pre">senders=...,</span> <span class="pre">bypass_mute=False,</span> <span class="pre">**kwargs)</span></code> - send the message onto
the channel. The <code class="docutils literal notranslate"><span class="pre">**kwargs</span></code> are passed on into the other call hooks (also on the recipient).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">at_post_channel_msg(message,</span> <span class="pre">**kwargs)</span></code> - by default this is used to store the message
to the log file.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">channel_prefix(message)</span></code> - this is called to allow the channel to prefix. This is called
by the object/account when they build the message, so if wanting something else one can
also just remove that call.</p></li>
<li><p>every channel message. By default it just returns <code class="docutils literal notranslate"><span class="pre">channel_prefix_string</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">has_connection(subscriber)</span></code> - shortcut to check if an entity subscribes to
this channel.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mute/unmute(subscriber)</span></code> - this mutes the channel for this user.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ban/unban(subscriber)</span></code> - adds/remove user from banlist.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">connect/disconnect(subscriber)</span></code> - adds/removes a subscriber.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">add_user_channel_alias(user,</span> <span class="pre">alias,</span> <span class="pre">**kwargs)</span></code> - sets up a user-nick for this channel. This is
what maps e.g. <code class="docutils literal notranslate"><span class="pre">alias</span> <span class="pre">&lt;msg&gt;</span></code> to <code class="docutils literal notranslate"><span class="pre">channel</span> <span class="pre">channelname</span> <span class="pre">=</span> <span class="pre">&lt;msg&gt;</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">remove_user_channel_alias(user,</span> <span class="pre">alias,</span> <span class="pre">**kwargs)</span></code> - remove an alias. Note that this is
a class-method that will happily remove found channel-aliases from the user linked to <em>any</em>
channel, not only from the channel the method is called on.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">pre_join_channel(subscriber)</span></code> - if this returns <code class="docutils literal notranslate"><span class="pre">False</span></code>, connection will be refused.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">post_join_channel(subscriber)</span></code> - by default this sets up a users channel-nicks/aliases.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">pre_leave_channel(subscriber)</span></code> - if this returns <code class="docutils literal notranslate"><span class="pre">False</span></code>, the user is not allowed to leave.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">post_leave_channel(subscriber)</span></code> - this will clean up any channel aliases/nicks of the user.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">delete</span></code> the standard typeclass-delete mechanism will also automatically un-subscribe all
subscribers (and thus wipe all their aliases).</p></li>
</ul>
</section>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo of Evennia"/>
</a></p>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Channels</a><ul>
<li><a class="reference internal" href="#working-with-channels">Working with channels</a><ul>
<li><a class="reference internal" href="#viewing-and-joining-channels">Viewing and joining channels</a></li>
<li><a class="reference internal" href="#talk-on-channels">Talk on channels</a></li>
<li><a class="reference internal" href="#channel-administration">Channel administration</a><ul>
<li><a class="reference internal" href="#default-channels-from-settings">Default channels from settings</a></li>
<li><a class="reference internal" href="#managing-channels-in-game">Managing channels in-game</a></li>
<li><a class="reference internal" href="#restricting-channel-administration">Restricting channel administration</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#using-channels-in-code">Using channels in code</a><ul>
<li><a class="reference internal" href="#allowing-characters-to-use-channels">Allowing Characters to use Channels</a></li>
<li><a class="reference internal" href="#customizing-channel-output-and-behavior">Customizing channel output and behavior</a></li>
<li><a class="reference internal" href="#channel-class">Channel class</a></li>
<li><a class="reference internal" href="#channel-logging">Channel logging</a></li>
<li><a class="reference internal" href="#properties-on-channels">Properties on Channels</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="Scripts.html"
title="previous chapter">Scripts</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="Msg.html"
title="next chapter">Msg</a></p>
</div>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Components/Channels.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Doc Versions</h3>
<ul>
<li>
<a href="https://www.evennia.com/docs/latest/index.html">latest (main branch)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/5.x/index.html">v5.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/4.x/index.html">v4.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/3.x/index.html">v3.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/2.x/index.html">v2.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/1.x/index.html">v1.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/0.x/index.html">v0.9.5 branch (outdated)</a>
</li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Msg.html" title="Msg"
>next</a> |</li>
<li class="right" >
<a href="Scripts.html" title="Scripts"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Channels</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2024, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>