Table of Contents

(Note: It would be nice if there were more code examples on this page. For instance bla.WriteKey(“buildinghp”, 100, 1) does not insert the key value “buildinghp 100” into bla. It would be nice to know what is wrong here since this wiki suggests that's how it's to be done. More code examples would clear up any confusion and allow new developers to more quickly pick up cf-python.) [As of march 2013 this note is outdated. Also, see some examples at the bottom of this page.]

Python plugin is a server plugin able to run Python scripts that manipulate Crossfire items, monsters, players, maps, …

The latest version, 2.0, is a major rewrite which introduces Python objects to represent maps, Crossfire objects and players. The hooking system also changed.

Note that this guide doesn't intend to teach you Python. Documentation for that is available on Python's official web site.

Also, advanced functions can require some knowledge of Crossfire's inner workings. Developers seeking help should check Crossfire's page on development or Crossfire's resource page (which includes links to lists, IRC, how to contact people, …). Another option is to check existing Python scripts, available in the maps source tree.

Old plugin's reference can be found on plugin_python, for historical purposes.

Important note: the API, and other parts, are valid for code's master. branch contains hopefully all the changes too, but there may be differences. Also, links to SVN are to trunk.

As from September, 14th, 2021, a .pyi file is available in maps/python/pyi. It lists all available functions and variables, though functions aren't documented, so no parameters or description.

General information

The plugin has access to all built-in functions of Python, and its regular libraries. Python version being used depends on the platform the server was built, but must be 3 or higher. FIXME {is that always true?}

Using a library not part of Python's default distribution is discouraged as this introduces new dependencies.

Scripts execute in their own context, and their state information is not kept between runs. There are functions to persist data, or share between scripts. Note that data persisted through those functions will not survive a server restart.

Scripts should import the Crossfire module to access Crossfire's built-in functions.

Calling Crossfire functions with invalid arguments will result in a Python exception being raised. A function failure will also result in an exception.

Scripts will have the same access rights as the server itself. It may be able to write to some directories, but not others.

Data that should survive a server restart should be persisted in the PlayerDirectory (for specific player information) or DataDirectory (for regular information), where the server normally has write access.

Scripts for server releases muse use the Crossfire.Log(level,message) method over the python build-in print method. The reason of this is to keep coherency between python scripts messages and server logging.

How do I hook a script to an object?

Python plugin is a server plugin, thus you need to insert in this object one of the event_xxx archetype (see /arch/system directory). The fields to fill are:

A script can then use WhoAmI(), WhoIsActivator(), WhoIsOther(), WhatIsMessage() functions of the Crossfire module to find the executing context.

How do I hook a script to a global event?

Create a script, and put it in the /python/events/xxx subdirectory or the maps directory, where xxx is the event's name in lowercase (create the directory if it doesn't exist). Available events are listed on the server_plugin page. In addition, there is a special event, init, which is called just after the plugin has been loaded. It behaves like other events in every aspect, but is called only once when the plugin finished loading.

How do I register a custom command?

Check Crossfire.RegisterCommand.

Return value

The return value of the script can be manipulated through the GetReturnValue and SetReturnValue functions. Signification of this value depends on the event being handled.

Scripts part of Crossfire default maps

Those Python scripts reside in the python subdirectory of the maps tree. They provide additional functionality, and may be considered as always present. FIXME {describe existing ones}

Dialog Helper

Script location: /python/CFDialog.py

This script provides two utility classes a map maker can use to easily create complex dialogs. Go here for a complete explanation on how it works.

Death message

Script location: /python/misc/death_message.py

This script makes the monster/living thing containing it display a message when it dies. It should be hooked through an event_death archetype in monster's inventory.

Message is specified in event object's options field. It can contain %m and %k, which will be replaced by respectively dead item's name and killer's name (if no killer, replaced by an empty string).

Greeting message

Script location: /python/misc/greet_message.py

This script makes the monster/living thing containing it display a message when it attacks for the first time an enemy. It should be hooked through an event_time archetype in monster's inventory.

Message is specified in event object's options field. It can contain %m and %e, which will be replaced by respectively monster's name and enemy's name.

Experience rewarder

Script location: /python/items/experience_rewarder.py

This script will give experience to the “activating” player. It should be linked through the “trigger” event of an altar, or similar thing.

Options are specified in the event object's fields.

A key/value will be used to store in the player if she activated the item already.

Available options are:

Time of the day

Scripts location: /python/tod/*.py

Those scripts add behaviour to items based on time of the day. Want to open doors at specific time, make werewolfes, deactivate a magic_mouth during the Season of Winter? Those scripts are ready to use. See time of day based python scripts

Hall of fame

Script location: /python/misc/hall_of_fame.py (trunk)

This script is intended to be bound to event objects, generally the apply one.

If the item this script is bound to is a SIGN, then it will display its list of players, preceded by the own item's message (as header).

For any other item, the player is added to the list, with her title. If the event object itself has a message, it will be displayed to the player if she is added to the list.

The script's parameters is the internal name of the quest, which must be suitable for a file name (no conversion done).

Quest support scripts

Scripts location: /python/quests, and various archetypes (quest_ ones).

Those scripts are intended to help write quests. See the relevant guide for more information.

Crossfire module

To use the crossfire module, add to your python script:

import Crossfire

The following functions and objects are available to all scripts using the Crossfire module through import Crossfire.

Convention: in the reference, xxx() specifies a method, xxx specifies a property.

Constants

Constants are available to wrap values used in Crossfire code like object types, movements, … They are available through Crossfire.xxx.VALUE, where xxx is the constant type and VALUE the value as in the C source code, in uppercase, without specific prefix (ie F_TRUE becomes TRUE, AT_FIRE becomes FIRE, and so on).

For each constant group xxx there exists a xxxName dictionary object containing the name of the value as a string.

The following constant types exist:

MessageFlag and Move can be combined, using +, to build multiple values.

{FIXME} do a nice table, with link to values?

Example:

whoami.Say("%s => %d"%(Crossfire.DirectionName[Crossfire.Direction.NORTH], Crossfire.Direction.NORTH))

will write

NORTH => 1

Warning: Python doesn't know about constants, thus scripts can modify those values. Doing this can lead to weird results, and should be avoided at all cost. Note that the C code itself is immune to the changes, only the scripts would suffer.

Methods

WhoAmI

Returns the Crossfire.Object from which the event being handled was raised, corresponds to the op parameter of the event. Can be None. For a map event, this is a Crossfire.Map

WhoIsActivator

Returns the Crossfire.Object having caused the event being handled, corresponds to the activator parameter of the event. Can be None.

Examples

WhoIsOther

Returns the Crossfire.Object being part of the event, corresponds to the third parameter of the event. Can be None.

WhatIsMessage

Returns the String that was sent as part of the event, corresponds to the message parameter of the event.

ScriptName

Returns the absolute path of the currently executing script.

ScriptParameters

This String variable contains:

WhatIsEvent

Crossfire.Object representing the event object that links to the plugin. Will be None for global events and custom commands.

GetReturnValue

Return current return value.

SetReturnValue

Parameters:

Sets the value the plugin will return to the server when the script exits. Value and effect depend on the event being handled.

PluginVersion

Returns an integer representing the Python plugin version.

MapDirectory

Returns the system directory containing the maps. Note that it is relative to the Data directory.

UniqueDirectory

Returns the system directory where unique items and maps are stored.

TempDirectory

Returns the system directory where temporary files are stored.

ConfigDirectory

Returns the system directory containing configuration files.

LocalDirectory

Returns the system directory containing read/write files.

PlayerDirectory

Returns the system directory containing player files.

DataDirectory

Returns the system directory containing read-only data.

FindPlayer

Parameter:

Returns a Crossfire.Player object for specified player, based on partial name matching, or None if not found. If only one player name can match, return this player, else return None.

GetArchetypes

Returns a Python list containing Crossfire.Archetype objects representing all archetypes the server knows. Should not be called lightly, as this can take some time.

GetMaps

Returns a Python list containing Crossfire.Map objects, one for each map currently being loaded. This includes random and unique maps.

GetParties

Returns a Python list containing Crossfire.Party objects, one for each existing party on the server.

GetRegions

Returns a Python list containing Crossfire.Region objects, one for each region.

GetFriendlyList

Returns a list of Crossfire.Object representing all items on the friendly list. Individual objects can be added/removed through their Friendly flag.

GetPlayers

Returns a list containing Crossfire.Players objects, one for each player on the server

GetTime

Returns a Python list corresponding to the in-game server time. Fields are (start at 0 to access):

  1. year
  2. month
  3. day
  4. hour
  5. minute
  6. day of week
  7. week of month
  8. season

MapHasBeenLoaded

Parameter:

Returns the Crossfire.Map with specified path, or None if such a map isn't loaded. Will not try to load the map, see Crossfire.ReadyMap for that.

FindFace

Parameter:

Returns the number of the specified face, 0 if it doesn't exist. The face name is the name as it appears in the archetypes, ie dcross-red1.111, without the set name or extension.

FindAnimation

Parameter:

Returns the number of the specified animation, 0 if it doesn't exist. The name is has it appears in the archetypes, ie campfire or bat.

ReadyMap

Loads specified map, and returns a Crossfire.Map object wrapping it. Will return None if map couldn't be found.

Parameter:

Examples

CreateObject

Returns an empty object which can then be manipulated and inserted in a map.

CreateObjectByName

Parameters:

Returns object with specified archetype or object name, or None if no object has the name, and archetype wasn't found.

CreateMap

Parameters:

Returns an empty map of specified dimensions. Unless map is removed immediately, Path should be set so the map correctly displays in the maps output.

Log

Parameters:

Use the server logging facilities to output script messages in server console. This is the recommended method, instead of using the python build-in “print” method. Using this, scripts take advantage of Debug and Monster level which can be hidden at will by server admin (log level), and have access to the error level, mentioning to admin serious troubles.

Example:

Crossfire.Log(Crossfire.LogDebug,'Player %s entered guild %s' %obj.Name %guildName)

RegisterCommand

Parameters:

Registers a server command which will be mapped to specified script. See Registering a command for more information.

The script path is relative to the maps subdirectory. When the command is called, the following methods will provide information:

RegisterGlobalEvent

Parameters:

This instructs the server to call the Python plugin for all events of specified type. Python will then call scripts in the /python/events/xxx directory, where xx is the event's name.

This function should not be used except in special circumstances, as Python by default registers all events anyway.

UnregisterGlobalEvent

Parameters:

This instructs the server to stop calling the Python plugin for all events of specified type.

This function should not be used, except in special circumstances, as it can disable other scripts that use those events.

DestroyTimer

Removes a timer created through a call to Crossfire.Object.AddTimer.

Arguments:

Returns:

GetPrivateDictionary

Returns a Python dictionary the script can use to store data between runs. This data is not shared with other scripts.

Note that data will be lost in case of server restart.

GetSharedDictionary

Returns a Python dictionary the script can use to share data with other scripts.

Note that data will be lost in case of server restart.

MatchString

Parameters:

Returns 1 if string matches the pattern, 0 else.

Pattern can be a regular expression FIXME specifications

AddReply

Parameters:

This method can only be called in a EVENT_SAY context.

Will generate an error if too many replies defined or not in an EVENT_SAY context.

SetPlayerMessage

Parameters:

This method can only be called in a EVENT_SAY context.

NPCSay

Parameters:

This method can only be called in a EVENT_SAY context.

Will add an NPC reply, that will be displayed to the player when the dialog processing ends.

Will generate an error if too many messages defined or not in an EVENT_SAY context.

CostStringFromValue

(trunk only)

Parameters:

Return value: formatted string describing the amount, with coin descriptions.

Will return “nothing” if amount is 0.

Crossfire module classes

All classes below are part of Crossfire module

Archetype

This represents an archetype, from which all objects are derived. Pointer to such item can be obtained through the Crossfire.Object.Archetype or the list returned by Crossfire.GetArchetypes().

Clone

A Crossfire.Object property representing the default values for items of that archetype. Will never be None. Its values can't be changed (but trying to change one will not result in any error)

archetype to which this archetype is linked. Will be None if not applicable.

Name

archetype's name

Next

next archetype in the archetype list. Will be None for last item

More

next archetype linked to current archetype. Will be None for last item

NewObject()

Returns a Crossfire.Object having this archetype as type. It isn't on any map or in any inventory, so should be inserted somewhere or deleted if not used.

Object

FIXME link to dev:objects 's fields? split flag & such info. Make a table with property / mapping to object / Python type

Properties in bold are read-write, others are read-only. Most properties are mapped to fields of the object structure. Boolean values are mapped to the various flags.

FIXME document all parameters. Link to relevant Crossfire function. Split in “standard function” and “helper function”?

ActivateRune

Current object springs like a trap, hitting the victim.

Arguments:

AddExp

Adds or subtracts experience to current object.

Arguments:

Apply

Current object applies specified object. The effect depends on the object being applied, which can be a potion, a trigger, …

Arguments:

Return value:

Arrest

Player is jailed, put in a map defined based on the region. No information is sent to victim.

Return value:

Cast

Current object casts a spell.

Arguments:

Return value:

Note that all checks related to spell-casting apply: enough sp/gp, knowing the skill, sufficient level, spot where magic isn't forbidden, …

The spell needn't be known to be known to be cast, though.

CastAbility

Obsolete, will be removed, use Cast.

ChangeAbil

Displays relevant messages about resistances and so on changes.

Arguments:

CheckArchInventory

Finds an object in current object's inventory.

Arguments:

Will return the first object in inventory that has the specified name. Name must be the raw name, without bonuses and such.

CheckInventory

Finds an object in current object's inventory.

Arguments:

Will return the first object in inventory that has the specified archetype, or the specified name (partial matches are fine), or the specified “slaying” field.

CheckTrigger

Checks if current object should/can react to another object moving on it.

Arguments:

Return value:

CreateObject

Create an object inside the current object.

Arguments:

Will create a new Crossfire.Object from specified name (like Crossfire.CreateObjectByName) and insert it into the current object.

CreateTimer

Fires an event_timer after the specified delay. Object should have a handler for this event.

Arguments:

Returns: timer identifier, which can be used to remove the timer through a call to Crossfire.DestroyTimer

Drop

Current object drops specified object, which will be put on the ground, or in a container, depending on applied containers.

Argument:

Event

Generates a user event to the object.

Arguments:

Fix

Current object is reinitialized from its default values, values (ac, wc, Str, …) are recomputed from items worn, in inventory, …

ForgetSpell

Player forgets a spell.

Arguments:

Object forgetting should be a player.

GetResist

Gets the value of a resistance to an attacktype.

Arguments:

Return: Number with the value. Note that an invalid attacktype will return 0, which can't be distinguished from a neutral resistance.

InsertInto

Insert the current object into another object.

Arguments:

Return:

After using this function, you should not use the initial Crossfire.Object, as it can be merged with others.

KnowSpell

Checks if current object knows a spell.

Arguments:

Return:

LearnSpell

Make the current object learn a spell.

Arguments:

There is no learning failure. Note that any spell can be learned this way. Player will receive the message that the spell was learnt correctly.

Move

Tries to move the object in a direction.

Arguments:

Return:

MoveTo

Tries to move the object towards a specified destination. trunk only.

Arguments:

Return:

OutOfMap

Check a position on the object's map.

Arguments:

Return:

Note that this function takes into account maps tiling.

Pay

Buys an item.

Arguments:

Return value:

This function applies bargaining skill if applicable, and will handle shop-based price difference. Note that the object to buy doesn't need to have the FLAG_UNPAID set.

PayAmount

Pays money.

Arguments:

Return:

QueryCost

Finds the price of an object.

Arguments:

Return value:

QueryName

Return: String containing the object's full name.

ReadKey

Reads key associated to value.

Arguments:

Return: String containing the value. Will be empty if NULL value.

Remove

Destroys current object, which then becomes invalid. If the object is on a map, its inventory is dropped to the ground (except no drop or god given items), else everything is destroyed.

Reposition

Moves current object to specified position on its current map.

Arguments:

Say

Current object says something in current map. If in a dialog context (reacting to a SAY event), the message will be queued to be displayed after the player actually says something, to enable changing her reply. If not in a dialog context, will just display the message.

Argument:

Speak

Current object says something in current map

Argument:

Equivalent to Say.

Split

This should only be called on stacks of objects (where Object.Quantity is greater than 1) This takes an object with n items in it's stack, and splits it into two objects, returning the new object. This new object contains the number of items specified by the argument, the original object has its Quantity reduced by the same amount.

Argument:

Take

Current object picks up specified object, which will be put in inventory, or in a container, depending on applied containers.

Argument:

Teleport

Teleports the object to specified place.

Arguments:

Return value: Number, 0 for success, 1 for failure.

Examples

WriteKey

Inserts specified key/value in the object.

Arguments:

Note: if you're not sure whether the key exists in the object, you must use 1 for the last argument, else the key will not be created if it doesn't exist.

Map

Properties in bold are read-write, others read only.

Print

Prints the specified message to all players on the map.

Arguments:

ObjectAt

Returns the first Crossfire.Object at specified location.

Arguments:

Other objects on the position are available through the use of the Above field.

CreateObject

Creates an object on the map.

Arguments:

Equivalent of calling Crossfire.CreateObjectByName() (creates an item from archetype or name) and inserting it in the map at the specified location

Check

Arguments:

Return:

Next

No arguments.

Return the next map in the list of active maps.

ChangeLight

Change the map's light level.

Arguments:

Note that light will never be negative or over 5 (MAX_DARKNESS)

Insert

Inserts an object at specified location.

Arguments:

Return: Crossfire.Object representing the inserted object. Can be None if object was removed for some reason (eaten by an altar, …)

InsertAround

Inserts an object around a specified location, randomly choosing a free spot.

Arguments:

Return: Crossfire.Object representing the inserted object. Can be None if object was removed for some reason (eaten by an altar, …)

TriggerConnected

Triggers the connected value for the map, this is normally used for activating gates, etc.

Arguments:

Player

This class inherits from Crossfire.Object, and introduces the new properties (bold = read-write):

CanPay

Checks if player can pay for unpaid items in inventory.

Return value:

This will print suitable messages if player can't pay.

Message

Sends a message to the player.

Arguments:

Write

Equivalent of Message.

QuestStart

(trunk only)

TODO explain quest definitions

Signal a player that she started a quest. Note that the quest must be correctly defined in the default.quests file.

Arguments:

QuestGetState

(trunk only)

Query the current state of a quest for the player. Note that the quest must be correctly defined in the default.quests file.

Arguments:

Return:

QuestSetState

(trunk only)

Signal a player that she advanced in a quest. Note that the quest must be correctly defined in the default.quests file.

Arguments:

QuestWasCompleted

(trunk only)

Query whether the player completed the quest previously. Note that the quest must be correctly defined in the default.quests file.

Arguments:

Return:

KnowledgeKnown

(trunk only)

Query whether the player knowns through the knowledge system the specified factoid.

Arguments:

Return:

GiveKnowledge

(trunk only)

Give a knowledge item to the player.

Arguments:

Party

This class merely encapsulates a party. Everything is read-only. Attributes:

GetPlayers

Return value: a list of Crossfire.Players

Region

This class encapsulates an in-game region. Properties are read-only.

Parent

Return value: a Crossfire.Region, or None if no parent region.

Example Scripts

A section

Move a player onto a map

This script will send its activator to jail, placing them in the 15 minute cell.

import Crossfire
 
#we get the the object that triggered this script
activator = Crossfire.WhoIsActivator()
 
#make sure that the map is loaded, and get the object representing it
#we could get the map's default entry coordinates with 'm.enter_x' and 'm.enter_y'
m = Crossfire.ReadyMap('/scorn/misc/jail')
 
#teleport the activating object to the x:15 y:1 coordinates of the map (m) we just readied
activator.Teleport(m, 15, 1)

Object.WriteKey

FIXME write an example

(see a working example at maps/python/monsters/farnass.py used from maps/scorn/misc/castle_kitchen )