Any script procedure binded to a ladder log message must take a single argument (here named args). This argument is a list of 0 to n value of any type, depending on the value returned by corresponding ladder log message.

Any script procedure binded to a ladder log message must take a single argument (here named args). This argument is a list of 0 to n value of any type, depending on the value returned by corresponding ladder log message.

+

+

Change:

+

LadderLogWriter now allows multiple bindings, and unbinding too. This is particulary convinient to organize you script code and also to change bindings according to maps. There's no change in the binding logic. Unbinding is straighforward, too.

+

Please note that bindings are managed as a queue: they are run in the very same order they are bound to an event. There's no way to reorganize bindings other then remove and requeue them.

Branch

lp:~armagetronad-ct/armagetronad/armagetronad-ct

Overview

The armagetronad-ct branch comes from an attempt to build armagetronad trunk with scripting enabled. As I faced issues compiling or running it with ruby, and the underlying wrapper, swig, support most of the common scripting language, I started this branch to add an abstraction layer, and eventually, introduce other scripting language support.

At this time, we were switching our script from php to python, and I was unable to compile with ruby, so I'd give Python a try ...

Armagetronad-ct is nothing but an experimental branch, as were armahacktron and sty+ct, based on armagetron trunk, currently being 0.3.x serie. Therefore, there are two major differences with sty+ct:

sty is not (yet) fully ported to 0.3.x serie and has not been included to this branch. So no flags, no balls, no zombies, no shooting...

although you can compile (still true?) trunk with zones v1 or v2, this branch has scripting support for zones v2 only...

There's also a few extra features that comes from sty+ct or has been added to provide scripting support:

DELAY_COMMAND comes from sty+ct.

INGAME_PARSING, INGAME_PARSING_DTD_VALIDATION and INGAME_PARSING_DTD allow to parse additional data during a round. It's meant to be use for zones. Any other parsing might be confusing and might lead to undefine behavior.

Although this branch main target is dedicated server, it might be extended to some client side features. For example, you can define new chat command from scripting on server side. This might be extended to client side soon as it allows to build dynamic instant messages (ex: /hi [<playername>] to salute last entered or specified player(s).

Eventually, if some servers start using it and this branch becomes somehow useful, we might extend it to other languages as ruby, lua or php, or polish it enough to deserve to be merged in its right place: armagetron mainline.

Install

We are working on linux only and there's no support for any other plateform. So here is a raw install procedure for debian/ubuntu users :

Running a server

The server expects to find scripting related files in a specific place: a subdirectory of armagetron data directory called "scripts".
More precisely, it expects to find a file called initialize.py. File extension vary depending on scripting language. So far, as only python support exists, we'll assume we are working with python as during install part.

The first step will be to set up out server specific directory tree. Personaly, I like to keep all config, var, and scripts directory in one place for a specific server. So let's start by setting up our directory tree:

/home/username/tron/servers/hello_scripting
./config
./var
./scripts

I'll assume you have include into the config subdir your config files.

So far, you'll have to copy the armagetronad.py file generated by swig during compilation into the scripts directory. This file is located into the src/swig/ext subdir in you source file directory (the armagetronad-ct directory from install step). Eventually, this file must be copied with other required files into the installation data scripts subdirectory. In this case, this directory should be append in initialize.py below.
Warning, don't forget to update this file each time you reinstall/update your armagetronad-dedicated binary.

You'll have to create the scripts/initialize.py file and include a few lines in it:

static int num_teams()
static Team team(int i)
declare_winner(string message)
int rounds_played() //!< number of rounds played (updated right after spawning, so it includes the current round)
set_locked(bool locked) //!< sets the lock status (whether invitations are required)
bool is_locked() //!< returns the lock status
bool is_locked_for(Player p) //!< returns if a team is locked to join by a certain player (due to ACCESS_LEVEL_PLAY)
invite(Player player) //!< invite the player to join
uninvite(Player player) //!< revoke an invitation
bool is_invited(Player player) //!< check if a player is invited
static bool is_enemy_player(Team team, Player player) //!< determines whether the player is an enemy of the team
static bool is_enemy_team(Team team1, Team team2) //!< determines whether two teams are enemies
static string ranking(int MAX = 6, bool cut = true) //!< return ranking information
static real ranking_graph(real y, int MAX = 6) //!< print ranking information
add_player(Player player) //!< register a player
remove_player(Player player) //!< deregister a player
bool player_may_join(Player player) //!< see if the given player may join this team
bool is_new_team_allowed() //!< is it allowed to create a new team?
static swap_players(Player player1, Player player2) //!< swaps the team positions of the two players (same team or not)
shuffle(int startID, int stopID) //!< shuffles the player at team postion startID to stopID
bool balance_this_team()
bool is_human()
int team_id()
int score()
add_score(int s)
reset_score()
set_score(int s)
add_score_output(int points, Output reasonwin, Output reasonlose)
int num_players()
Player player(int i)
vector_Player players()
int num_human_players() //!< number of human players
int num_ai_players() //!< number of AI players
int alive_players() //!< how many of the current players are currently alive?
Player oldest_player() // the oldest player
Player oldest_human_player() // the oldest human player
Player oldest_ai_player // the oldest AI player
Player youngest_player() // the youngest player
Player youngest_human_player() // the youngest human player
Player youngest_ai_player() // the youngest AI player
bool is_alive() // is any of the players currently alive?
unsigned short red()
unsigned short green()
unsigned short blue()
string name()

Any script procedure binded to a ladder log message must take a single argument (here named args). This argument is a list of 0 to n value of any type, depending on the value returned by corresponding ladder log message.

Change:
LadderLogWriter now allows multiple bindings, and unbinding too. This is particulary convinient to organize you script code and also to change bindings according to maps. There's no change in the binding logic. Unbinding is straighforward, too.
Please note that bindings are managed as a queue: they are run in the very same order they are bound to an event. There's no way to reorganize bindings other then remove and requeue them.

Create new Commands\Settings

You might be able to define new command from scripting. The new command will be available from console within the game, from other console commands like DELAY_COMMAND.
Let's build a RESPAWN_PLAYER command: