Difference between revisions of "Writing Modules In Python"

From ASSS Wiki
Jump to: navigation, search
m (removed asss. prefix on set_timer())
(Fixed formatting to match rest of site. Changes the lines a bit, feel free to change back.)
Line 1: Line 1:
= Basic python module =
+
== Basic python module ==
 
I have tried to comment what is going on in the source. This module demonstrates callbacks, commands and using interfaces.
 
I have tried to comment what is going on in the source. This module demonstrates callbacks, commands and using interfaces.
 
<pre>
 
<pre>
Line 50: Line 50:
 
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 <py> demo. Re-entering the arena and typing ?moo should do some stuff.
 
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 <py> demo. Re-entering the arena and typing ?moo should do some stuff.
  
= Code snippets =
+
== Code snippets ==
 
The bread and butter of most custom modules.
 
The bread and butter of most custom modules.
== Callbacks ==
+
=== Callbacks ===
 
<pre>
 
<pre>
 
from asss import *
 
from asss import *
Line 64: Line 64:
 
</pre>
 
</pre>
  
== Commands ==
+
=== Commands ===
 
Useful for controlling events, fx: ?elim start. In this case the command is ?t1.
 
Useful for controlling events, fx: ?elim start. In this case the command is ?t1.
 
<pre>
 
<pre>
Line 81: Line 81:
 
</pre>
 
</pre>
  
== Per-player/arena data ==
+
=== Per-player/arena data ===
 
Use this to store game state, player score, etc.
 
Use this to store game state, player score, etc.
 
<pre>
 
<pre>
Line 93: Line 93:
 
</pre>
 
</pre>
  
== Attach/Detach ==
+
=== Attach/Detach ===
 
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.
 
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.
 
<pre>
 
<pre>
Line 102: Line 102:
 
</pre>
 
</pre>
  
== Looping over all players ==
+
=== Looping over all players ===
 
This example counts the number of players in an arena. (I'll come back to this later to make sure the code is correct).
 
This example counts the number of players in an arena. (I'll come back to this later to make sure the code is correct).
 
<pre>
 
<pre>
Line 116: Line 116:
 
</pre>
 
</pre>
  
== Timers ==
+
=== Timers ===
 
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.
 
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.
  
Line 130: Line 130:
 
</pre>
 
</pre>
  
= Trouble shooting =
+
== Trouble shooting ==
 
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, "i'm at line ...") type messages to locate the buggy piece of code.
 
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, "i'm at line ...") type messages to locate the buggy piece of code.

Revision as of 23:12, 10 January 2005

Basic python module

I have tried to comment what is going on in the source. This module demonstrates callbacks, commands and using interfaces.

# demo asss python module
# dec 28 2004 smong

# nearly always use this
from asss import *


# get some interfaces
# see chat.h for where I_CHAT comes from, see other .h files for more (fx:
#  game.h)
chat = get_interface(I_CHAT)


# a callback
# this function is called when a player enters/leaves, see core.h for PA_???
#  constants
def paction(p, action, arena):
    # start indenting
    if action == PA_ENTERARENA:
        # see chat.h for the names of more functions like SendMessage
        chat.SendMessage(p, "hello %s" % p.name)

# tell asss to call 'paction' when CB_PLAYERACTION is signalled
# see .h files for CB_??? names
cb1 = reg_callback(CB_PLAYERACTION, paction)


# a command
# see cmdman.h for what each parameter does
def c_moo(cmd, params, p, targ):
# help text (?help moo)
    """\
Module: <py> demo
Targets: none
a sample command.
"""
    chat.SendMessage(p, "moo")

# tell asss to call 'c_moo' when a player types ?moo
# note: add cmd_moo to conf/groupdef.dir/default so players have permission to
#  use this command.
cmd1 = add_command("moo", c_moo)

# setting chat (or other interfaces), cb* or cmd* to None is equivalent to
#  unregistering that item.

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 <py> demo. Re-entering the arena and typing ?moo should do some stuff.

Code snippets

The bread and butter of most custom modules.

Callbacks

from asss import *

chat = get_interface(I_CHAT)

def goal(arena, p, bid, x, y):
    chat.SendArenaMessage(arena, "goal.")

cb1 = reg_callback(CB_GOAL, goal) 

Commands

Useful for controlling events, fx: ?elim start. In this case the command is ?t1.

from asss import *

chat = get_interface(I_CHAT)

def c_mycmd(cmd, params, p, targ):
    """\
some help text
"""
    chat.SendMessage(p, "moo.")

cmd1 = add_command("t1", c_mycmd)
#where the "t1" is located would be the name of the command, ex: ?t1

Per-player/arena data

Use this to store game state, player score, etc.

def shipchange(p, newship, newfreq):
    # prefix mymod_ an abbreviation of your module name to the variable
    #  so that it doesn't clash with other modules. per arena data works
    #  in exactly the same way.
    p.mymod_lastship = p.ship

cb1 = reg_callback(CB_SHIPCHANGE, shipchange)

Attach/Detach

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.

def mm_attach(arena):
    # do stuff with arena
def mm_detach(arena):
    # undo stuff

Looping over all players

This example counts the number of players in an arena. (I'll come back to this later to make sure the code is correct).

def count_players(arena):
    # a list must be used as all other variables are immutable to
    #  nested functions.
    players = [0]
    def cb_count(p):
        if p.arena == arena:
            players[0] = players[0] + 1
    for_each_player(cb_count)
    return players[0]

Timers

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.

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 "hello" every 2 seconds starting from 1 second after make_hello_timer() was called. The parameter arena is needed in this case because SendArenaMessage() requires an arena parameter.

def make_hello_timer(initial, interval, arena):
    def timer():
        # announce
        chat.SendArenaMessage(arena, "hello")
        # non-repeating timer. return 1 for it to be called after the next interval
        return 0
    return set_timer(timer, initial, interval)

Trouble shooting

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, "i'm at line ...") type messages to locate the buggy piece of code.