<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.minegoboom.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=BDwinsAlt</id>
		<title>ASSS Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.minegoboom.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=BDwinsAlt"/>
		<link rel="alternate" type="text/html" href="http://wiki.minegoboom.com/index.php/Special:Contributions/BDwinsAlt"/>
		<updated>2026-05-05T22:11:33Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.28.2</generator>

	<entry>
		<id>http://wiki.minegoboom.com/index.php?title=UBill&amp;diff=5638</id>
		<title>UBill</title>
		<link rel="alternate" type="text/html" href="http://wiki.minegoboom.com/index.php?title=UBill&amp;diff=5638"/>
				<updated>2007-08-06T17:40:27Z</updated>
		
		<summary type="html">&lt;p&gt;BDwinsAlt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== UBill 0.2 ==&lt;br /&gt;
UBill is a small TCP [[Biller]] created by BDwinsAlt.  It is currently in small development.  This biller includes BanG and several other features. A list of commands can be found [http://braddavis.info/ubill/cmd.html here].  You can report bugs at http://braddavis.info/help.&lt;br /&gt;
&lt;br /&gt;
A portion of the biller has remained open, so you can create your own commands.  All you have to do is edit UBillCmd.java.&lt;br /&gt;
&lt;br /&gt;
== Ways to execute this biller ==&lt;br /&gt;
(Console)&amp;lt;br /&amp;gt;&lt;br /&gt;
java -jar UBill.jar (Must be updated when UBillCmd is updated)&amp;lt;br /&amp;gt;&lt;br /&gt;
java UBill (Uses the .class instead of the .jar, does not need to be updated to run UBillCmd)&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Clicking)&amp;lt;br /&amp;gt;&lt;br /&gt;
You can simply double click on the jar file to open it.&lt;br /&gt;
&lt;br /&gt;
== Ways to compile this biller ==&lt;br /&gt;
In the terminal:&amp;lt;br /&amp;gt;&lt;br /&gt;
1. javac UBill.java&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(The rest is optional if you chose to use the jar file.)&amp;lt;br /&amp;gt;&lt;br /&gt;
2. copy all class files into a folder (contents?) [mkdir contents  ....then....  cp *.class contents]&amp;lt;br /&amp;gt;&lt;br /&gt;
3. jar cvfm UBill.jar ubill.mf -C contents/ .  (Copy and paste. Cases, spaces, and periods matter!)&lt;br /&gt;
&lt;br /&gt;
== Using a batch file ==&lt;br /&gt;
If you chose not to update a jar each time, create a batch file.&lt;br /&gt;
&lt;br /&gt;
Create a file named compile.bat.&lt;br /&gt;
Edit with notepad by copying and pasting:&lt;br /&gt;
javac UBill.java&lt;br /&gt;
&lt;br /&gt;
Create a file named run.bat.&lt;br /&gt;
Edit with notepad by copying and pasting:&lt;br /&gt;
java UBill&lt;br /&gt;
&lt;br /&gt;
== Download UBill ==&lt;br /&gt;
You can download UBill at http://braddavis.info/UBill.zip&lt;/div&gt;</summary>
		<author><name>BDwinsAlt</name></author>	</entry>

	<entry>
		<id>http://wiki.minegoboom.com/index.php?title=TCP_Billing_FAQ&amp;diff=5637</id>
		<title>TCP Billing FAQ</title>
		<link rel="alternate" type="text/html" href="http://wiki.minegoboom.com/index.php?title=TCP_Billing_FAQ&amp;diff=5637"/>
				<updated>2007-08-06T17:38:57Z</updated>
		
		<summary type="html">&lt;p&gt;BDwinsAlt: /* Are there any TCP billers available for public download? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What's so special about TCP billers? ==&lt;br /&gt;
TCP billers use a new simpler protocol compared to the original UDP billers.&lt;br /&gt;
&lt;br /&gt;
== Can I use subgame with a TCP biller? ==&lt;br /&gt;
No, currently only ASSS can connect to a TCP biller. It is possible to use proxy to convert between the UDP and TCP protocols to allow subgame.&lt;br /&gt;
&lt;br /&gt;
== Why is there no ability for the billing server to shutdown/restart a server? ==&lt;br /&gt;
The ability of the billing servers to shutdown a zone server is a relic from the old system. The biller is no longer an administrative and control server, but simply a validation system used to control passwords for player names and bans.&lt;br /&gt;
&lt;br /&gt;
== Are there any TCP billers available for public download? ==&lt;br /&gt;
Yes, but only unfinished ones.&lt;br /&gt;
&lt;br /&gt;
* Two different versions of [[POCoB]] written by [[User:Smong|Smong]] are available at http://toktok.sscentral.com/ss-pocob.php.&lt;br /&gt;
* [[SkyBill]] written by [[User:Doc flabby|Doc Flabby]] is available at http://playsubspace.com.&lt;br /&gt;
* [[UBill]] written by [http://braddavis.info BDwinsAlt] is available at http://braddavis.info/UBill.zip&lt;br /&gt;
[[Category: FAQ]]&lt;br /&gt;
[[Category: Protocol]]&lt;/div&gt;</summary>
		<author><name>BDwinsAlt</name></author>	</entry>

	<entry>
		<id>http://wiki.minegoboom.com/index.php?title=UBill&amp;diff=5636</id>
		<title>UBill</title>
		<link rel="alternate" type="text/html" href="http://wiki.minegoboom.com/index.php?title=UBill&amp;diff=5636"/>
				<updated>2007-08-06T17:36:35Z</updated>
		
		<summary type="html">&lt;p&gt;BDwinsAlt: New page: == UBill 0.2 == UBill is a small TCP Biller created by BDwinsAlt.  It is currently in small development.  This biller includes BanG and several other features. A list of commands can b...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== UBill 0.2 ==&lt;br /&gt;
UBill is a small TCP [[Biller]] created by BDwinsAlt.  It is currently in small development.  This biller includes BanG and several other features. A list of commands can be found [http://braddavis.info/ubill/cmd.html here].  You can report bugs at http://braddavis.info/help.&lt;br /&gt;
&lt;br /&gt;
A portion of the biller has remained open, so you can create your own commands.  All you have to do is edit UBillCmd.java.&lt;br /&gt;
&lt;br /&gt;
== Ways to execute this biller ==&lt;br /&gt;
(Console)&amp;lt;br /&amp;gt;&lt;br /&gt;
java -jar UBill.jar (Must be updated when UBillCmd is updated)&amp;lt;br /&amp;gt;&lt;br /&gt;
java UBill (Uses the .class instead of the .jar, does not need to be updated to run UBillCmd)&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Clicking)&amp;lt;br /&amp;gt;&lt;br /&gt;
You can simply double click on the jar file to open it.&lt;br /&gt;
&lt;br /&gt;
== Ways to compile this biller ==&lt;br /&gt;
In the terminal:&amp;lt;br /&amp;gt;&lt;br /&gt;
1. javac UBill.java&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(The rest is optional if you chose to use the jar file.)&amp;lt;br /&amp;gt;&lt;br /&gt;
2. copy all class files into a folder (contents?) [mkdir contents  ....then....  cp *.class contents]&amp;lt;br /&amp;gt;&lt;br /&gt;
3. jar cvfm UBill.jar ubill.mf -C contents/ .  (Copy and paste. Cases, spaces, and periods matter!)&lt;br /&gt;
&lt;br /&gt;
== Using a batch file ==&lt;br /&gt;
If you chose not to update a jar each time, create a batch file.&lt;br /&gt;
&lt;br /&gt;
Create a file named compile.bat.&lt;br /&gt;
Edit with notepad by copying and pasting:&lt;br /&gt;
javac UBill.java&lt;br /&gt;
&lt;br /&gt;
Create a file named run.bat.&lt;br /&gt;
Edit with notepad by copying and pasting:&lt;br /&gt;
java UBill&lt;/div&gt;</summary>
		<author><name>BDwinsAlt</name></author>	</entry>

	<entry>
		<id>http://wiki.minegoboom.com/index.php?title=Category:Linux&amp;diff=5622</id>
		<title>Category:Linux</title>
		<link rel="alternate" type="text/html" href="http://wiki.minegoboom.com/index.php?title=Category:Linux&amp;diff=5622"/>
				<updated>2007-04-07T02:10:36Z</updated>
		
		<summary type="html">&lt;p&gt;BDwinsAlt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Description ==&lt;br /&gt;
[http://linux.org Linux] is a free, open-source operating system.  It was created by Linus Torvalds while he attended college at the University of Helsinki in Finland.  It is based off the [http://en.wikipedia.org/wiki/Unix Unix system].  A penguin, named Tux, was chosen as the mascot for Linux.  Since then, developers have been making their own distributions (distros) of Linux.  A few popular distros are [http://www.redhat.com RedHat], [http://www.fedoraproject.org Fedora], [http://novell.com/linux Suse], and [http://www.Debian.org Debian].&lt;br /&gt;
&lt;br /&gt;
Most distros are completely free.  All you have to do it download it, install it, and configure it the way you want it.  You can even get a CD in the mail if you pay for shipping.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Advantages ==&lt;br /&gt;
There are many advantages to using Linux.  First of all, it's free.  This means you don't have to worry about buying a new version of Windows to run new applications or games.  Second, it's stable.  Linux can run for over a year without needing a single reboot, if you configure it correctly.  This is required for people who run web servers or game servers.  Third, it's open-source.  This means you can edit ANYTHING you want to edit.  You could even tweak it into your own distro (please give some credit to the original author).  Finally, wine lets you emulate some Windows applications.  This is great for transferring to Windows but still using your old applications you love.  Many people contribute to the code to make it run better.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Disadvantages ==&lt;br /&gt;
Some disadvantages are that Linux doesn't have a lot of business software like [http://QuickBooks.com QuickBooks].  There is SpreadSheet software, but people don't use it that much when it comes to larger companies.  Linux has no toll-free number to call if something messes up.  They have a community you can visit, but you're not guaranteed a resolution to your problem.  Also, wine doesn't always run all of your applications.  Bigger and older applications have problems running on wine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Is Linux right for me? ==&lt;br /&gt;
Linux has many distros.  You simply have to find the right distro for you.  If you are interested in educational software or if you're in college you may want to try [http://www.edubuntu.org Edubuntu] or something similar.  If your interested in programming or multimedia, there are a lot of distros you can choose from.&lt;br /&gt;
&lt;br /&gt;
The best way to find out which is better for you is to ask yourself what you will use it for.  Ask yourself why you don't want to use Windows.  Look at some screenshots of different distros.  If you find a nice GUI, read some information about the distro and run it in [http://vmware.com VMWare].  VMWare is a virtual operating system player.  You can run a different operating system inside your current one.  That means no partitions are messed up or anything like that.  Once you get the hang of using Linux in VMWare, you may want to install it as your main operating system.&lt;br /&gt;
&lt;br /&gt;
Don't give up if you can't figure something out right away.  You aren't suppose to understand something completely new to you. If that was the case you would already speak any language you wanted to speak.&lt;br /&gt;
&lt;br /&gt;
For more information please use a very nice website that I like to call Google, or add to this page if you're bored.&lt;/div&gt;</summary>
		<author><name>BDwinsAlt</name></author>	</entry>

	<entry>
		<id>http://wiki.minegoboom.com/index.php?title=Writing_Modules_In_Python&amp;diff=4015</id>
		<title>Writing Modules In Python</title>
		<link rel="alternate" type="text/html" href="http://wiki.minegoboom.com/index.php?title=Writing_Modules_In_Python&amp;diff=4015"/>
				<updated>2006-09-21T00:49:07Z</updated>
		
		<summary type="html">&lt;p&gt;BDwinsAlt: /* Per-player/arena data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Basic python module ==&lt;br /&gt;
I have tried to comment what is going on in the source. This module demonstrates callbacks, commands and using interfaces.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# demo asss python module&lt;br /&gt;
# dec 28 2004 smong&lt;br /&gt;
&lt;br /&gt;
# nearly always use this&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# get some interfaces&lt;br /&gt;
# see chat.h for where I_CHAT comes from, see other .h files for more (fx:&lt;br /&gt;
#  game.h)&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# a callback&lt;br /&gt;
# this function is called when a player enters/leaves, see core.h for PA_???&lt;br /&gt;
#  constants&lt;br /&gt;
def paction(p, action, arena):&lt;br /&gt;
    # start indenting&lt;br /&gt;
    if action == PA_ENTERARENA:&lt;br /&gt;
        # see chat.h for the names of more functions like SendMessage&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;hello &amp;quot; + p.name)&lt;br /&gt;
&lt;br /&gt;
# tell asss to call 'paction' when CB_PLAYERACTION is signalled&lt;br /&gt;
# see .h files for CB_??? names&lt;br /&gt;
cb1 = reg_callback(CB_PLAYERACTION, paction)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# a command&lt;br /&gt;
# see cmdman.h for what each parameter does&lt;br /&gt;
def c_moo(cmd, params, p, targ):&lt;br /&gt;
# help text (?help moo)&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
Module: &amp;lt;py&amp;gt; demo&lt;br /&gt;
Targets: none&lt;br /&gt;
a sample command.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    chat.SendMessage(p, &amp;quot;moo cows&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# tell asss to call 'c_moo' when a player types ?moo&lt;br /&gt;
# note: add cmd_moo to conf/groupdef.dir/default so players have permission to&lt;br /&gt;
#  use this command.&lt;br /&gt;
cmd1 = add_command(&amp;quot;moo&amp;quot;, c_moo)&lt;br /&gt;
&lt;br /&gt;
# setting chat (or other interfaces), cb* or cmd* to None is equivalent to&lt;br /&gt;
#  unregistering that item.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Save this in bin/demo.py. Then ingame make sure pymod is loaded by using ?lsmod and ?insmod. Then add this module with the following command: ?insmod &amp;lt;py&amp;gt; demo. Re-entering the arena and typing ?moo should do some stuff.&lt;br /&gt;
&lt;br /&gt;
== Code snippets ==&lt;br /&gt;
The bread and butter of most custom modules.&lt;br /&gt;
=== Callbacks ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
def goal(arena, p, bid, x, y):&lt;br /&gt;
    chat.SendArenaMessage(arena, &amp;quot;goal.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
cb1 = reg_callback(CB_GOAL, goal) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Commands ===&lt;br /&gt;
Useful for controlling events, fx: ?elim start. In this case the command is ?t1.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
# cmd = the name of the command, fx: elim&lt;br /&gt;
# params = any parameters, fx: start&lt;br /&gt;
# p = who sent the command&lt;br /&gt;
# targ = player or arena&lt;br /&gt;
def c_mycmd(cmd, params, p, targ):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
some help text&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if isinstance(targ, ArenaType):&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;command sent to public chat&amp;quot;)&lt;br /&gt;
    elif isinstance(targ, PlayerType):&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;command sent as priv msg to %s&amp;quot; % targ.name)&lt;br /&gt;
&lt;br /&gt;
cmd1 = add_command(&amp;quot;t1&amp;quot;, c_mycmd)&lt;br /&gt;
#where the &amp;quot;t1&amp;quot; is located would be the name of the command, ex: ?t1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can parse integers from the params using the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    val = int(params)&lt;br /&gt;
except ValueError:&lt;br /&gt;
    # here the conversion of params from a string to an int failed.&lt;br /&gt;
    # change the next line to 'pass' to silently ignore the conversion error,&lt;br /&gt;
    # 'return' to exit the function, or 'val = 0' to set a default value to val.&lt;br /&gt;
    chat.SendMessage(p, &amp;quot;Integer parameter required.&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Per-player/arena data ===&lt;br /&gt;
Use this to store game state, player score, etc.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def shipchange(p, newship, newfreq):&lt;br /&gt;
    # prefix mymod_ an abbreviation of your module name to the variable&lt;br /&gt;
    #  so that it doesn't clash with other modules. per arena data works&lt;br /&gt;
    #  in exactly the same way.&lt;br /&gt;
    p.mymod_lastship = p.ship&lt;br /&gt;
&lt;br /&gt;
cb1 = reg_callback(CB_SHIPCHANGE, shipchange)&lt;br /&gt;
&lt;br /&gt;
def kill(arena, killer, killed, bty, flags, pts, green):&lt;br /&gt;
    # Make sure you use &amp;quot;stat = get_interface(I_STATS)&amp;quot; without the quotation marks.&lt;br /&gt;
    # This checks to see if the killer killed someone on the team same.&lt;br /&gt;
    # If so then it will take away a kill from the killer and take away a death from the killed player.&lt;br /&gt;
    # The scores are updated right away and it appears as if you never died.&lt;br /&gt;
&lt;br /&gt;
    if killer.freq == killed.freq:&lt;br /&gt;
	tkevent1 = stat.GetStat(killer, STAT_KILLS, INTERVAL_RESET) - 1&lt;br /&gt;
	tkevent2 = stat.GetStat(killed, STAT_DEATHS, INTERVAL_RESET) - 1&lt;br /&gt;
	stat.SetStat(killer, STAT_KILLS, INTERVAL_RESET, tkevent1)&lt;br /&gt;
	stat.SetStat(killed, STAT_DEATHS, INTERVAL_RESET, tkevent2)&lt;br /&gt;
	stat.SendUpdates()&lt;br /&gt;
    &lt;br /&gt;
    return pts, green&lt;br /&gt;
&lt;br /&gt;
cb2 = reg_callback(CB_KILL, kill)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Persistent per-player data ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;color: red; font-weight: bold; border: thin solid; padding: 5px 5px 5px 5px&amp;quot;&amp;gt;Note this has changed since 1.4.2. See bin/fg_turf.py for the latest implementation. Or the example at: http://forums.minegoboom.com/viewtopic.php?p=63321#63321&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ASSS has built in mechanisms for saving data per player and per arena across sessions (users logging off or server restarting).&lt;br /&gt;
&lt;br /&gt;
You need to provide three functions that will be called by ASSS to save, restore and clear the data. The example below is a complete module.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# each player can save a note that only they can see&lt;br /&gt;
&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
# show and store a note&lt;br /&gt;
def c_note(cmd, params, p, targ):&lt;br /&gt;
    if params:&lt;br /&gt;
        p.note = params&lt;br /&gt;
    if p.note:&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;note: %s&amp;quot; % p.note)&lt;br /&gt;
    else:&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;no note set&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
cmd1 = add_command(&amp;quot;note&amp;quot;, c_note)&lt;br /&gt;
&lt;br /&gt;
# return the data to save for player p&lt;br /&gt;
# returning None means &amp;quot;don't store a record in the database,&lt;br /&gt;
# and delete any record that's there already&amp;quot;.&lt;br /&gt;
def getpd(p):&lt;br /&gt;
    return p.note&lt;br /&gt;
&lt;br /&gt;
# restore the data for player p&lt;br /&gt;
def setpd(p, d):&lt;br /&gt;
    p.note = d&lt;br /&gt;
&lt;br /&gt;
# reset/clear the data for player p&lt;br /&gt;
def clearpd(p):&lt;br /&gt;
    p.note = None&lt;br /&gt;
&lt;br /&gt;
mypd = reg_player_persistent(&lt;br /&gt;
	7890, INTERVAL_FOREVER, PERSIST_GLOBAL,&lt;br /&gt;
	getpd, setpd, clearpd)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ideally you should load the module when the server starts. Alternatively if you load it dynamically you can kick everyone (not desirable) or alter the code to catch AttributeError when it attempts to read from the per player data ''.note''.&lt;br /&gt;
&lt;br /&gt;
Taking a look at ''reg_player_persistent'' the number ''7890'' is arbitrary, but must be unique for every module using persistent data. Low numbers are reserved for the core modules. ''INTERVAL_FOREVER'' is how long this data will be kept for. Interestingly the INTERVAL_* constants are defined in statcodes.h, not persist.h. ''PERSIST_GLOBAL'' is defined in persist.h. Here are the respective code extracts (as of Feb 7 2005).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* these are the possible intervals */&lt;br /&gt;
enum interval_t&lt;br /&gt;
{&lt;br /&gt;
	/* pyconst: enum, &amp;quot;INTERVAL_*&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	/* these are shared between arenas with the same arenagrp */&lt;br /&gt;
	INTERVAL_FOREVER = 0,&lt;br /&gt;
	INTERVAL_RESET,&lt;br /&gt;
	INTERVAL_MAPROTATION,&lt;br /&gt;
	/* these are not shared between arenas */&lt;br /&gt;
	INTERVAL_GAME = 5,&lt;br /&gt;
	INTERVAL_FOREVER_NONSHARED&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef enum persist_scope_t&lt;br /&gt;
{&lt;br /&gt;
	/* pyconst: enum, &amp;quot;PERSIST_*&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	PERSIST_ALLARENAS,&lt;br /&gt;
	/* using this for scope means per-player data in every arena */&lt;br /&gt;
	/* using this for scope means per-arena data will be stored&lt;br /&gt;
	 * per-arena */&lt;br /&gt;
&lt;br /&gt;
	PERSIST_GLOBAL&lt;br /&gt;
	/* using this for scope means per-player data shared among all arenas */&lt;br /&gt;
	/* using this for scope means per-arena data will be shared among&lt;br /&gt;
	 * all arenas (so it will effectively be global data). */&lt;br /&gt;
} persist_scope_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: ASSS must be compiled with the berkeleydb option for persistent data to be available.&lt;br /&gt;
&lt;br /&gt;
=== Attach/Detach ===&lt;br /&gt;
Attaching and detaching is similar to load/unload in a C module except it is arena specific. So you can use it to initialise per-arena data.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mm_attach(arena):&lt;br /&gt;
    # do stuff with arena&lt;br /&gt;
def mm_detach(arena):&lt;br /&gt;
    # undo stuff&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Looping over all players ===&lt;br /&gt;
This example counts the number of players in an arena.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def count_players(arena):&lt;br /&gt;
    # a list must be used as all other variables are immutable to&lt;br /&gt;
    #  nested functions.&lt;br /&gt;
    players = [0]&lt;br /&gt;
    def cb_count(p):&lt;br /&gt;
        if p.arena == arena:&lt;br /&gt;
            players[0] = players[0] + 1&lt;br /&gt;
    for_each_player(cb_count)&lt;br /&gt;
    return players[0]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Timers ===&lt;br /&gt;
Good for checking if a game is over yet. '''A reference to the timer is returned and must be retained''' (you can use per-arena data to store it). Losing the reference will cancel the timer.&lt;br /&gt;
&lt;br /&gt;
''initial'' is the time in 1/100th's of a second before the nested function timer() will be called, you can cancel the timer before it is called. ''interval'' is the time gap, again in 1/100th's of a second between all future calls of timer(). So make_hello_timer(100, 200, arena) will make it send the arena message &amp;quot;hello&amp;quot; every 2 seconds starting from 1 second after make_hello_timer() was called.&lt;br /&gt;
&lt;br /&gt;
The third argument to set_timer (''interval'') can be omitted and it will be assumed to be the same as ''initial''.&lt;br /&gt;
&lt;br /&gt;
The parameter ''arena'' is needed in this case because SendArenaMessage() requires an arena parameter.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def make_hello_timer(initial, interval, arena):&lt;br /&gt;
    def timer():&lt;br /&gt;
        # announce&lt;br /&gt;
        chat.SendArenaMessage(arena, &amp;quot;hello&amp;quot;)&lt;br /&gt;
        # non-repeating timer. return 1 for it to be called after the next interval&lt;br /&gt;
        return 0&lt;br /&gt;
    return set_timer(timer, initial, interval)&lt;br /&gt;
&lt;br /&gt;
def somefunc(arena):&lt;br /&gt;
    # create a hello timer that will execute after 1 second, and then every&lt;br /&gt;
    #  2 seconds until cancelled. timers can cancel themselves, see above.&lt;br /&gt;
    myref = make_hello_timer(100, 200, arena)&lt;br /&gt;
&lt;br /&gt;
    # cancel the timer by losing the reference to it&lt;br /&gt;
    myref = None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Regions ===&lt;br /&gt;
This is untested but it should go something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mapdata = get_interface(I_MAPDATA)&lt;br /&gt;
&lt;br /&gt;
# regionname is a string, x and y are map tile coords.&lt;br /&gt;
def region_contains(arena, regionname, x, y):&lt;br /&gt;
    success = 0&lt;br /&gt;
&lt;br /&gt;
    rgn = mapdata.FindRegionByName(arena, regionname)&lt;br /&gt;
&lt;br /&gt;
    if rgn != None and mapdata.Contains(rgn, x, y):&lt;br /&gt;
        success = 1&lt;br /&gt;
&lt;br /&gt;
    return success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is a good idea to cache ''rgn'' within [[#Per-player.2Farena_data|per-arena data]] so you don't add unecessary load to the server looking it up everytime.&lt;br /&gt;
&lt;br /&gt;
You might come across a region callback when browsing the .h files. This is currently (1.4.2) not available in python.&lt;br /&gt;
&lt;br /&gt;
== Trouble shooting ==&lt;br /&gt;
Look at the asss console for execution errors (at the time of writing not all errors are relayed to logged in staff), and if that doesn't help, add some chat.SendArenaMessage(ALLARENAS, &amp;quot;i'm at line ...&amp;quot;) type messages to locate the buggy piece of code.&lt;br /&gt;
&lt;br /&gt;
[[Category:Module]]&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>BDwinsAlt</name></author>	</entry>

	<entry>
		<id>http://wiki.minegoboom.com/index.php?title=Writing_Modules_In_Python&amp;diff=4012</id>
		<title>Writing Modules In Python</title>
		<link rel="alternate" type="text/html" href="http://wiki.minegoboom.com/index.php?title=Writing_Modules_In_Python&amp;diff=4012"/>
				<updated>2006-09-20T21:11:35Z</updated>
		
		<summary type="html">&lt;p&gt;BDwinsAlt: /* Per-player/arena data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Basic python module ==&lt;br /&gt;
I have tried to comment what is going on in the source. This module demonstrates callbacks, commands and using interfaces.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# demo asss python module&lt;br /&gt;
# dec 28 2004 smong&lt;br /&gt;
&lt;br /&gt;
# nearly always use this&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# get some interfaces&lt;br /&gt;
# see chat.h for where I_CHAT comes from, see other .h files for more (fx:&lt;br /&gt;
#  game.h)&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# a callback&lt;br /&gt;
# this function is called when a player enters/leaves, see core.h for PA_???&lt;br /&gt;
#  constants&lt;br /&gt;
def paction(p, action, arena):&lt;br /&gt;
    # start indenting&lt;br /&gt;
    if action == PA_ENTERARENA:&lt;br /&gt;
        # see chat.h for the names of more functions like SendMessage&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;hello &amp;quot; + p.name)&lt;br /&gt;
&lt;br /&gt;
# tell asss to call 'paction' when CB_PLAYERACTION is signalled&lt;br /&gt;
# see .h files for CB_??? names&lt;br /&gt;
cb1 = reg_callback(CB_PLAYERACTION, paction)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# a command&lt;br /&gt;
# see cmdman.h for what each parameter does&lt;br /&gt;
def c_moo(cmd, params, p, targ):&lt;br /&gt;
# help text (?help moo)&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
Module: &amp;lt;py&amp;gt; demo&lt;br /&gt;
Targets: none&lt;br /&gt;
a sample command.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    chat.SendMessage(p, &amp;quot;moo cows&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# tell asss to call 'c_moo' when a player types ?moo&lt;br /&gt;
# note: add cmd_moo to conf/groupdef.dir/default so players have permission to&lt;br /&gt;
#  use this command.&lt;br /&gt;
cmd1 = add_command(&amp;quot;moo&amp;quot;, c_moo)&lt;br /&gt;
&lt;br /&gt;
# setting chat (or other interfaces), cb* or cmd* to None is equivalent to&lt;br /&gt;
#  unregistering that item.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Save this in bin/demo.py. Then ingame make sure pymod is loaded by using ?lsmod and ?insmod. Then add this module with the following command: ?insmod &amp;lt;py&amp;gt; demo. Re-entering the arena and typing ?moo should do some stuff.&lt;br /&gt;
&lt;br /&gt;
== Code snippets ==&lt;br /&gt;
The bread and butter of most custom modules.&lt;br /&gt;
=== Callbacks ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
def goal(arena, p, bid, x, y):&lt;br /&gt;
    chat.SendArenaMessage(arena, &amp;quot;goal.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
cb1 = reg_callback(CB_GOAL, goal) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Commands ===&lt;br /&gt;
Useful for controlling events, fx: ?elim start. In this case the command is ?t1.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
# cmd = the name of the command, fx: elim&lt;br /&gt;
# params = any parameters, fx: start&lt;br /&gt;
# p = who sent the command&lt;br /&gt;
# targ = player or arena&lt;br /&gt;
def c_mycmd(cmd, params, p, targ):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
some help text&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if isinstance(targ, ArenaType):&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;command sent to public chat&amp;quot;)&lt;br /&gt;
    elif isinstance(targ, PlayerType):&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;command sent as priv msg to %s&amp;quot; % targ.name)&lt;br /&gt;
&lt;br /&gt;
cmd1 = add_command(&amp;quot;t1&amp;quot;, c_mycmd)&lt;br /&gt;
#where the &amp;quot;t1&amp;quot; is located would be the name of the command, ex: ?t1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can parse integers from the params using the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    val = int(params)&lt;br /&gt;
except ValueError:&lt;br /&gt;
    # here the conversion of params from a string to an int failed.&lt;br /&gt;
    # change the next line to 'pass' to silently ignore the conversion error,&lt;br /&gt;
    # 'return' to exit the function, or 'val = 0' to set a default value to val.&lt;br /&gt;
    chat.SendMessage(p, &amp;quot;Integer parameter required.&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Per-player/arena data ===&lt;br /&gt;
Use this to store game state, player score, etc.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def shipchange(p, newship, newfreq):&lt;br /&gt;
    # prefix mymod_ an abbreviation of your module name to the variable&lt;br /&gt;
    #  so that it doesn't clash with other modules. per arena data works&lt;br /&gt;
    #  in exactly the same way.&lt;br /&gt;
    p.mymod_lastship = p.ship&lt;br /&gt;
&lt;br /&gt;
cb1 = reg_callback(CB_SHIPCHANGE, shipchange)&lt;br /&gt;
&lt;br /&gt;
def kill(arena, killer, killed, bty, flags, pts, green):&lt;br /&gt;
    # Make sure you use &amp;quot;stat = get_interface(I_STATS)&amp;quot; without the quotation marks.&lt;br /&gt;
    # This checks to see if the killer killed someone on the team same.&lt;br /&gt;
    # If so then it will take away a kill from the killer and take away a death from the killed player.&lt;br /&gt;
    # The scores are updated right away and it appears as if you never died.&lt;br /&gt;
&lt;br /&gt;
    if killer.freq == killed.freq:&lt;br /&gt;
	tkevent1 = stat.GetStat(killer, STAT_KILLS, INTERVAL_RESET)&lt;br /&gt;
	tkevent2 = stat.GetStat(killed, STAT_DEATHS, INTERVAL_RESET)&lt;br /&gt;
	tkevent1 -= 1&lt;br /&gt;
	tkevent2 -= 1&lt;br /&gt;
	stat.SetStat(killer, STAT_KILLS, INTERVAL_RESET, tkevent1)&lt;br /&gt;
	stat.SetStat(killed, STAT_DEATHS, INTERVAL_RESET, tkevent2)&lt;br /&gt;
	stat.SendUpdates()&lt;br /&gt;
    &lt;br /&gt;
    return pts, green&lt;br /&gt;
&lt;br /&gt;
cb2 = reg_callback(CB_KILL, kill)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Persistent per-player data ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: red; font-weight: bold; border: thin solid; padding: 5px 5px 5px 5px&amp;quot;&amp;gt;Note this has changed since 1.4.2. See bin/fg_turf.py for the latest implementation. Or the example at: http://forums.minegoboom.com/viewtopic.php?p=63321#63321&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ASSS has built in mechanisms for saving data per player and per arena across sessions (users logging off or server restarting).&lt;br /&gt;
&lt;br /&gt;
You need to provide three functions that will be called by ASSS to save, restore and clear the data. The example below is a complete module.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# each player can save a note that only they can see&lt;br /&gt;
&lt;br /&gt;
from asss import *&lt;br /&gt;
&lt;br /&gt;
chat = get_interface(I_CHAT)&lt;br /&gt;
&lt;br /&gt;
# show and store a note&lt;br /&gt;
def c_note(cmd, params, p, targ):&lt;br /&gt;
    if params:&lt;br /&gt;
        p.note = params&lt;br /&gt;
    if p.note:&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;note: %s&amp;quot; % p.note)&lt;br /&gt;
    else:&lt;br /&gt;
        chat.SendMessage(p, &amp;quot;no note set&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
cmd1 = add_command(&amp;quot;note&amp;quot;, c_note)&lt;br /&gt;
&lt;br /&gt;
# return the data to save for player p&lt;br /&gt;
# returning None means &amp;quot;don't store a record in the database,&lt;br /&gt;
# and delete any record that's there already&amp;quot;.&lt;br /&gt;
def getpd(p):&lt;br /&gt;
    return p.note&lt;br /&gt;
&lt;br /&gt;
# restore the data for player p&lt;br /&gt;
def setpd(p, d):&lt;br /&gt;
    p.note = d&lt;br /&gt;
&lt;br /&gt;
# reset/clear the data for player p&lt;br /&gt;
def clearpd(p):&lt;br /&gt;
    p.note = None&lt;br /&gt;
&lt;br /&gt;
mypd = reg_player_persistent(&lt;br /&gt;
	7890, INTERVAL_FOREVER, PERSIST_GLOBAL,&lt;br /&gt;
	getpd, setpd, clearpd)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ideally you should load the module when the server starts. Alternatively if you load it dynamically you can kick everyone (not desirable) or alter the code to catch AttributeError when it attempts to read from the per player data ''.note''.&lt;br /&gt;
&lt;br /&gt;
Taking a look at ''reg_player_persistent'' the number ''7890'' is arbitrary, but must be unique for every module using persistent data. Low numbers are reserved for the core modules. ''INTERVAL_FOREVER'' is how long this data will be kept for. Interestingly the INTERVAL_* constants are defined in statcodes.h, not persist.h. ''PERSIST_GLOBAL'' is defined in persist.h. Here are the respective code extracts (as of Feb 7 2005).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* these are the possible intervals */&lt;br /&gt;
enum interval_t&lt;br /&gt;
{&lt;br /&gt;
	/* pyconst: enum, &amp;quot;INTERVAL_*&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	/* these are shared between arenas with the same arenagrp */&lt;br /&gt;
	INTERVAL_FOREVER = 0,&lt;br /&gt;
	INTERVAL_RESET,&lt;br /&gt;
	INTERVAL_MAPROTATION,&lt;br /&gt;
	/* these are not shared between arenas */&lt;br /&gt;
	INTERVAL_GAME = 5,&lt;br /&gt;
	INTERVAL_FOREVER_NONSHARED&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef enum persist_scope_t&lt;br /&gt;
{&lt;br /&gt;
	/* pyconst: enum, &amp;quot;PERSIST_*&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	PERSIST_ALLARENAS,&lt;br /&gt;
	/* using this for scope means per-player data in every arena */&lt;br /&gt;
	/* using this for scope means per-arena data will be stored&lt;br /&gt;
	 * per-arena */&lt;br /&gt;
&lt;br /&gt;
	PERSIST_GLOBAL&lt;br /&gt;
	/* using this for scope means per-player data shared among all arenas */&lt;br /&gt;
	/* using this for scope means per-arena data will be shared among&lt;br /&gt;
	 * all arenas (so it will effectively be global data). */&lt;br /&gt;
} persist_scope_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: ASSS must be compiled with the berkeleydb option for persistent data to be available.&lt;br /&gt;
&lt;br /&gt;
=== Attach/Detach ===&lt;br /&gt;
Attaching and detaching is similar to load/unload in a C module except it is arena specific. So you can use it to initialise per-arena data.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mm_attach(arena):&lt;br /&gt;
    # do stuff with arena&lt;br /&gt;
def mm_detach(arena):&lt;br /&gt;
    # undo stuff&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Looping over all players ===&lt;br /&gt;
This example counts the number of players in an arena.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def count_players(arena):&lt;br /&gt;
    # a list must be used as all other variables are immutable to&lt;br /&gt;
    #  nested functions.&lt;br /&gt;
    players = [0]&lt;br /&gt;
    def cb_count(p):&lt;br /&gt;
        if p.arena == arena:&lt;br /&gt;
            players[0] = players[0] + 1&lt;br /&gt;
    for_each_player(cb_count)&lt;br /&gt;
    return players[0]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Timers ===&lt;br /&gt;
Good for checking if a game is over yet. '''A reference to the timer is returned and must be retained''' (you can use per-arena data to store it). Losing the reference will cancel the timer.&lt;br /&gt;
&lt;br /&gt;
''initial'' is the time in 1/100th's of a second before the nested function timer() will be called, you can cancel the timer before it is called. ''interval'' is the time gap, again in 1/100th's of a second between all future calls of timer(). So make_hello_timer(100, 200, arena) will make it send the arena message &amp;quot;hello&amp;quot; every 2 seconds starting from 1 second after make_hello_timer() was called.&lt;br /&gt;
&lt;br /&gt;
The third argument to set_timer (''interval'') can be omitted and it will be assumed to be the same as ''initial''.&lt;br /&gt;
&lt;br /&gt;
The parameter ''arena'' is needed in this case because SendArenaMessage() requires an arena parameter.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def make_hello_timer(initial, interval, arena):&lt;br /&gt;
    def timer():&lt;br /&gt;
        # announce&lt;br /&gt;
        chat.SendArenaMessage(arena, &amp;quot;hello&amp;quot;)&lt;br /&gt;
        # non-repeating timer. return 1 for it to be called after the next interval&lt;br /&gt;
        return 0&lt;br /&gt;
    return set_timer(timer, initial, interval)&lt;br /&gt;
&lt;br /&gt;
def somefunc(arena):&lt;br /&gt;
    # create a hello timer that will execute after 1 second, and then every&lt;br /&gt;
    #  2 seconds until cancelled. timers can cancel themselves, see above.&lt;br /&gt;
    myref = make_hello_timer(100, 200, arena)&lt;br /&gt;
&lt;br /&gt;
    # cancel the timer by losing the reference to it&lt;br /&gt;
    myref = None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Regions ===&lt;br /&gt;
This is untested but it should go something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mapdata = get_interface(I_MAPDATA)&lt;br /&gt;
&lt;br /&gt;
# regionname is a string, x and y are map tile coords.&lt;br /&gt;
def region_contains(arena, regionname, x, y):&lt;br /&gt;
    success = 0&lt;br /&gt;
&lt;br /&gt;
    rgn = mapdata.FindRegionByName(arena, regionname)&lt;br /&gt;
&lt;br /&gt;
    if rgn != None and mapdata.Contains(rgn, x, y):&lt;br /&gt;
        success = 1&lt;br /&gt;
&lt;br /&gt;
    return success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is a good idea to cache ''rgn'' within [[#Per-player.2Farena_data|per-arena data]] so you don't add unecessary load to the server looking it up everytime.&lt;br /&gt;
&lt;br /&gt;
You might come across a region callback when browsing the .h files. This is currently (1.4.2) not available in python.&lt;br /&gt;
&lt;br /&gt;
== Trouble shooting ==&lt;br /&gt;
Look at the asss console for execution errors (at the time of writing not all errors are relayed to logged in staff), and if that doesn't help, add some chat.SendArenaMessage(ALLARENAS, &amp;quot;i'm at line ...&amp;quot;) type messages to locate the buggy piece of code.&lt;br /&gt;
&lt;br /&gt;
[[Category:Module]]&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>BDwinsAlt</name></author>	</entry>

	</feed>