Skip to content

OCTGN Python 3.1.0.1 API Reference

brine edited this page Jun 11, 2015 · 5 revisions

This document outlines the Python API version 3.1.0.1 used by OCTGN's scripting engine. Previous API versions are no longer documented or officially supported by OCTGN.

CONTENTS:
Global Class Generic functions
Player Class Require a Player object to be passed
Group Class Accepts Table, Hand or Pile objects
Table Class Requires the Table object to be passed
Pile Class Requires a Pile object to be passed
Card Class Requires a Card object to be passed
Event Functions Special functions that receive variables from game events

CHANGES MADE TO API FUNCTIONS


# GLOBAL CLASS FUNCTION | DESCRIPTION | LAST REVISION ----------|-------------|--------------- [askCard()](#askcard) | Shows a dialog box of cards for the user to choose | 2015/01/19 3.1.159 [askChoice()](#askchoice) | Shows a dialog box with multiple buttons that the user can choose from | 2013/05/27 3.1.35 [askInteger()](#askinteger) | Creates a dialog box to input a number | [askMarker()](#askmarker) | Shows a dialog box so that the user can choose a marker type and quantity | [askString()](#askstring) | Creates a dialog box to input a string | 2015/01/19 3.1.159 [currentGameName()](#currentgamename) | returns the user-defined name for this game | [confirm()](#confirm) | Creates a yes/no dialog box | [gameVersion](#gameversion) | Returns the game definition's current version | [getGlobalVariable()](#getglobalvariable) | Returns the value of a game-defined global variable | [getSetting()](#getsetting) | Returns a saved game setting | 2013/07/30 3.1.56 [mute()](#mute) | Mute's OCTGN's automatic chat log notifications | [notify()](#notify) | Sends a notification message to all players | [notifyBar()](#notify) | Sends a notification message to all players | [openUrl()](#openurl) | Opens the URL in your default browser | [getPlayers()](#getplayers) | Returns a list of all players in the game | 2013/11/22 3.1.110 [playSound()](#playsound) | Plays a pre-defined sound file | [remoteCall()](#remotecall) | Invokes a function remotely for a specific player | 2013/09/08 3.1.87 [resetGame()](#resetgame) | Reset the game | 2014/12/20 3.1.127 [rnd()](#rnd) | Generates a random number between two integers | [setGlobalVariable()](#setglobalvariable) | Sets the value of a game-defined global variable | [setSetting()](#setsetting) | Saves a game setting | 2013/07/30 3.1.56 [turnNumber()](#turnnumber) | Returns the internal turn count | [version](#version) | Returns OCTGN's current version | [webRead()](#webread) | Reads the contents of a URL and the HTTP status code | [whisper()](#whisper) | Sends a notification message to the local player | [update()](#update) | Forces the Python engine to wait until OCTGN's queued networking processes are finished. | 2013/09/11 3.1.92 ## mute()

Stops OCTGN from logging its own messages to the chat log. This only applies to the context of the executed function, and does not persist between Python functions.

This function is useful if you want to use your own chat log notifications for functions such as shuffling, adding markers to cards, increasing counters, or moving cards.

## notify(message)
Argument Type Description
message string a customized message to send to the chat log of all players.

Sends a customized message to the chat log of all players. You can use Python's str.format() method to include variables in the string.

If you pass a Player object as a variable, OCTGN will replace it with the player's nickname. If you pass a Card object, OCTGN will replace it with the card's name, and you can 'Hover' over the name to preview the card's image.

notify("{} plays {} from his hand.".format(me, card))
>>> "Joe plays Ace of Spades from his hand."

Important: Some users have reported that OCTGN will crash if you start a notify message with a line break \n. To prevent unnecessary crashes, it is recommended to add whitespace in front of the line break..

## notifyBar(color, message)
Argument Type Description
color string the font color for the message, MUST be in the #HEX color format.
message string a customized message to send to the chat log of all players.

Sends a customized message to the alert bar above the playtable. This is only seen by the local player, use remoteCall() to send to other players.

If you pass a Player object as a variable, OCTGN will replace it with the player's nickname. If you pass a Card object, OCTGN will replace it with the card's name, and you can 'hover' over the name to preview the card's image.

notifyBar("#FF0000", "{} plays {} from his hand.".format(me, card))
>>> "Joe plays Ace of Spades from his hand."
## whisper(message)
Argument Type Description
message string a customized message to send to the local player's chat log.

Sends a customized message to the chat log of the local player only. You can use Python's str.format() method to include variables in the string.

If you pass a Player object as a variable, OCTGN will replace it with the player's nickname. If you pass a Card object, OCTGN will replace it with the card's name, and you can 'Hover' over the name to display the card's image.

whisper("You can't play {}, {}.".format(card, me))
>>> "You can't play Blue Bunny, Dave."

NOTE: Since whisper() doesn't send through the server network, it sometimes appears in the chat log before notify() messages will, even if whisper() is processed first.

rnd(min, max)

Argument Type Description
min integer The lowest value that the random number can be
max integer The highest value that the random number can be

Returns a random INTEGER value between min and max.

This method is generally better than Python's built-in functions because it is distributed. Other players can check that you don't cheat while choosing the number.

num = rnd(3, 6)
print num
>>> 5

Due to rnd()'s distributed nature, it had become a popular work-around to several of OCTGN's bugs and issues, such as #412 and #110. It can force a delay at a specific point of a script's execution, to allow OCTGN to 'catch up' with the script execution. However, the update() function has been recently written to more effectively address this issue.

## webRead(url, timeout = 0)
Argument Type Description
url string The URL of a web page
timeout integer (OPTIONAL) The length of time (in milliseconds) to wait before timing out.

Reads the contents of a web page

Returns a tuple (contents, code) where STRING contents is the contents of the web page, and INT code is the HTTP code of that page (currently supports 200, 403, 404, 500).

contents, code = webRead('http://www.mysite.com/test.php', 5000)
print contents
>>> 'Welcome to my webpage!'
print code
>>> 200

NOTE: The intended purpose of this method is to allow python to read simple text web pages hosted online, to allow more dynamic scripting without having to force game definition updates. There may be many other uses as well.

## openUrl(url)
Argument Type Description
url string The URL of a web page

Opens the user's default web browser to the URL given. It will always ask for the user's permission first, to allow for URL verification. Please be responsible when using this method.

openUrl('http://www.octgn.net')
## turnNumber()

Read-only: Returns the current turn number as an INTEGER (from the internal turn counter).

turn = turnNumber()
print turn
>>> 7
## currentGameName()

Read-only: Returns the name that the hosting player gave to the currently hosted game.

name = currentGameName()
print name
>>> "Beginners Game: No Pros!"
## confirm(message)
Argument Type Description
message string a customized message to display in the dialog box.

Displays a dialog window with the message, and YES/NO buttons as inputs.

Returns True if the user chooses 'YES', False if the user chooses 'NO', and None if they close the window.

choice = confirm("Do you want to play {}?".format(card.name))
print choice
>>> False
## askInteger(message, defaultAnswer)
Argument Type Description
message string a customized message to display in the dialog box.
defaultAnswer integer the default number to display in the input box.

Displays a dialog box with the message, and an input box to enter in a POSITIVE INTEGER value.

Returns the inputted INTEGER, or None if the user closes the window instead.

count = askInteger("Draw how many cards?", 10)
if count == None: return
print count
>>> 10
## askString(message, defaultAnswer)
Argument Type Description
message string a customized message to display in the dialog box.
defaultAnswer string the default word to display in the input box.

Displays a dialog box with the message, and an input box to enter in a STRING value.

Returns the inputted STRING, or None if the user closes the window instead.

name = askString("What is your name?", "Bob")
if name == None: return
print name
>>> "Greg"
## askMarker()

Displays a dialog box with all markers defined in the game, so that the user can choose a marker and quantity.

Returns a tuple (guid, quantity), where STRING guid is the GUID of the chosen marker, and INTEGER quantity is the chosen quantity. (None, 0) will be returned if the user doesn't choose a marker (closes the window).

marker, qty = askMarker()
if qty == 0: return
card.markers[marker] += qty
print marker
>>> '19663776-58c4-431e-850b-70f3f05118dc'
print qty
>>> 4
## askChoice(message, buttonList, colorList, customButtons = [])
Argument Type Description
message string a customized message to display in the dialog box.
buttonList list<string> A list of STRING values specifying the labels of each choice button.
colorList list<string> a list of STRING values specifying the color of each button's background. The color values MUST be in the #HEX color format.
customButtons list<string> (OPTIONAL) A list of STRING values specifying the labels for custom buttons at the bottom of the window.

Displays a multiple-choice dialog box with a list of buttons that the user can choose from. Optional customButton confirmation-style buttons can also be defined which returns a special case.

Returns 0 if the window is closed, or an INTEGER value (starting with 1) corresponding to the chosen button's placement in the window. If customButtons are defined, then clicking one of those will return a negative number, (starting with -1) ordered similarly to buttonList.

(NOTE: that the returning integer will always be 1 greater than the index of that label in the original choice List)

choiceList = ['Heart', 'Diamond', 'Spade', 'Club']
colorsList = ['#FF0000', '#FF0000', '#000000', '#000000'] 
choice = askChoice("Pick a suit:", choiceList, colorsList, customButtons = ["Nah I'm good"])
print choice
>>> 2

NOTE: The colors list must be the exact same length as the choice list, as they correspond to the same indexes. If the lengths are different, then the colors will not appear.

## askCard(properties = {}, operator = None, title = "Choose card") / askCard(cardList, question = None, title = "Choose card")

IMPORTANT: askCard() is now an overloaded method which behaves differently depending on if you pass a List or a Dictionary as its first parameter. This API documentation will detail both cases individually.

METHOD 1: Dictionary of property values

Argument Type Description
properties dictionary<string:string> A dictionary of property:value pairs that filter the viewable cards in the window.
operator string (OPTIONAL) Only accepts "and" or "or", as operators for the filtered list.
title string (OPTIONAL) A custom title to give to the dialog box.

This function is case insensitive

Displays a dialog so that the user can choose a card type and quantity. Cards are pulled from the card database and filtered based on property matches listed in the dictionary.

Returns a tuple (guid, quantity), where STRING guid is the GUID of the chosen card, and INTEGER quantity is the chosen quantity. (None, 0) will be returned if the user doesn't choose a card (closes the window).

The properties parameter should follow the proper Python syntax for dictionaries. The dictionary Keys are STRINGs of the card properties you want to match. You can use any custom property defined in the game, or you can also query card "Name" or "Model" (GUID).

Dictionary Values are the property value you wish to match. They can be a STRING, or a LIST of STRINGS. If a List is used, askCard will match any of the strings in the list (using OR operator).

The optional operator parameter defines how multiple properties are filtered, and only accepts "or" and "and". It will default to "and" if no operator is given.

The optional title is a STRING title given to the dialog box. The default value is "Choose card".

Example: Shows only cards where Color == Red and Rank == Queen

card, quantity = askCard({"Color":"Red","Rank":"Queen"}, "and")
>>> choices are [Queen of Hearts, Queen of Diamonds]

Example: Shows all cards where Suit == Heart or Rank == Queen

card, quantity = askCard({"Suit":"Heart","Rank":"Queen"}, "and")
>>> choices are [Ace - King of Hearts, Queen of Hearts, Queen of Diamonds, Queen of Spades, Queen of Clubs]

Example: Shows only cards where Color == Red and Rank == Queen or King

card, quantity = askCard({"Color":"Red","Rank":["Queen", "King"]}, "and")
>>> choices are [Queen of Hearts, Queen of Diamonds, King of Hearts, King of Diamonds]

METHOD 2: List of card objects

Argument Type Description
cardList List A list of Card objects to select from
question string OPTIONAL text to display inside the dialog box.
title string (OPTIONAL) A custom title to give to the dialog box.

Creates a dialog box displaying images of all the cards in the ordered List cardList.

If a question is specified, that text will display in the dialog box, above the displayed card images.

The optional title is a STRING title given to the dialog box. The default value is "Choose card".

Returns the Card object of the selected card.

WARNING: The dialog box will ignore any cards in the list that the player does not have visibility of. Make sure you force visibility of all cards in the list before executing this function.

Example:

card = askCard([c for c in me.Discard], "These cards are in your discard pile:", "Select a Card" )
return card
 >> "Three of Hearts"
## getPlayers()

Returns a list of all Player objects currently connected to the game. Note that this list is UNSORTED, that is, the local player (You) is always first in this list.

This method is different from the players constant because it is dynamic, and will change if a player leaves or joins the game. players will always return the original list of players when the game started.

## version

Returns the STRING version of OCTGN that the user is using.

print version
>>> "3.1.82.510"
## gameVersion

Returns the STRING version of the game definition that the user is using.

print gameVersion
>>> "1.0.2.0"
## resetGame()

Reset the game.

## getGlobalVariable(name)

(see this link for more information on OCTGN's GlobalVariable system.)

Argument Type Description
name string The name of a game-defined Global Variable

Returns the STRING stored data that is defined in the Game Definition as **.

NOTE: name is stored in OCTGN as a STRING, and will probably need to be converted back into its original type. You can do this with Python's eval(var) method.

cards = eval(getGlobalVariable("cardList"))
print cards
>>> ["Queen", "Jack", "10"]
## setGlobalVariable(name, value)

(see this link for more information on OCTGN's GlobalVariable system.)

Argument Type Description
name string The name of a game-defined Global Variable
value string The value to store into the Global Variable

NOTE: The variable MUST be converted to a STRING before it is stored via setGlobalVariable(). You can do this with Python's str(var) method.

cards = ["Queen", "Jack", "10"]
setGlobalVariable("cardList", str(cards))
## setSetting(name, value)
Argument Type Description
name string The name of a game setting
value any type A variable object to store into the named setting

Stores a variable as a local game setting, identifiable by its name. All standard python object types are supported (string, int, list, etc...) EXCEPT DICTIONARIES (see note below). Game settings are stored permanently and are retained when a game is closed, but are only readable by the local player.

examples of use:

setSetting("MaleGender", True) // Stores a boolean True/False, in this case to store the player's gender.
setSetting("PlayerAge", 25)  // Stores an integer value

NOTE!!! Python dictionaries currently break the settings file. If you want to store a dictionary object as a setting, you MUST convert it to a .NET dictionary first! When you use getSetting, it will return as a Python Dictionary.

example of conversion:

   pythonDict = {"key": 3, "anotherkey": 73}
   netDict = Dictionary[str,int](pyDict)
## getSetting(name, defaultValue)
Argument Type Description
name string The name of a game setting
defaultValue any type A default value to return, if the setting doesn't exist yet

Retrieves a previously-stored Game Setting with the specified name. A defaultValue must be included, in the case where that Game Setting has not yet been created or stored, and should match the object type that would be expected.

Warning: Keep in mind bug #968

examples of use:

age = getSetting("PlayerAge", 20) // Will return the stored variable, else default to 20.

## playSound(name)

(see this link for more information on OCTGN's Sound system.)

Argument Type Description
name string The name of a game-defined Sound

Plays a sound with name as defined in the game definition.

playSound('beep')
## remoteCall(player, function, arguments)
Argument Type Description
player [Player](OCTGN python api reference#player-class) The player who will end up invoking the function
function string The name of the function that will be invoked
arguments list A list of arguments (of any object type) that will be passed to the remote player's function

Invokes a specific function on another players game. This is the recommended way to interact with objects(cards, piles, groups, tokens, etc) that are not controlled by the player calling this method.

This is the only safe way to manipulate objects not controlled by the local player (me) and other methods will be deprecated in the future.

Examples

# This is a function that exists inside one of your definitions python files
def soundOff(id, play):
  notify("[{}]Sounds off {} (Started by {})".format(me,id,play));

# this is the call you would make to make all the players sounds turn off
def invokeSoundOff()
  i = 0
  for p in players
    remoteCall(p,"soundOff",[p._id,me])
    i = i+1

# if you run it
invokeSoundOff()

#You would get the results

# [player1]Sounds off 0 (Started by player1)
# [player2]Sounds off 1 (Started by player1)

Note: You have to pass the arguments list even if the remote function will have no argument. In this case simply pass an empty list object

e.g. remoteCall(p,"functionName",[])

## update()

This function forces any networked based functionality executed by previous lines of code to complete. This is a useful way of forcing OCTGN to 'catch up' for certain processes to finish. Examples of issues which may be remedied by this function can be found here: #412 and #110.



# PLAYER CLASS

All API functions in the Player Class require a Player object to be specified. Player objects are indexed in OCTGN by their INTEGER _id value, which is assigned whenever the Player object is created.

Python can return the Player object using Player(_id), making the _id integer value useful for storing player information with functions such as setGlobalVariable().

The Player class provides case-insensitive dynamic properties as shortcuts to game-defined piles and counters, assuming their names contains some invalid symbol such as a dot or a space)

    me.deck  --> me.piles['Deck']
    me.score --> me.counters['Score']

players is an unordered list of all Player objects that existed when the game was created. players[0] is ALWAYS the local player, and is shortcutted by using me as the player object. For example, players[0].name == me.name == "your name". Note that a player that leaves the game will still retain their Player object in players, and will cause errors when the list is used.

When scripts are to refer to the local player, ALWAYS use me.

FUNCTION DESCRIPTION LAST REVISION
_id Returns the unique identifier for the player
color Returns the color associated with that player
counters Returns dictionary of all the player's counters and their values
getGlobalVariable() Returns the value of a player's game-defined global variable
hand Returns the player's HAND object for further manipulations
hasInvertedTable() Returns TRUE if the player is on the "inverted" side B of a two-sided table.
isActivePlayer Returns TRUE if it's currently the player's turn (Active Player)
name Returns the player's name.
piles Returns dictionary of all the player's piles and their OBJECTS for manipulations
setActivePlayer() Passes the Active Turn status to another player.
setGlobalVariable() Sets the LOCAL PLAYER ONLY's game-defined global variable.
## player._id

Returns the unique INTEGER identity value assigned to the Player object. This identifier is generated by OCTGN when the Player object is created. The player with _id of 1 is always the hosting player.

id = player._id
print id
>>> 1
## player.name

Returns the STRING nickname of this player.

name = player.name
print name
>>> "Bobby86"
## player.color

Returns a STRING representing the color assigned to the player, in #HEX notation (i.e. #000000).

color = player.color
print color
>>> "#3A3A00"
## player.hand

Returns the player's Hand object, or None if this game doesn't use hands.

hand = me.hand
print hand[0].name
>>> "Ace of Spades" #the name of the first card in my hand
## player.counters

{INCOMPLETE}

Read-only; dictionary containing this player's counters. Keys are names (case-insensitive); Values are Counter object, that have two properties: name and value (settable). If the counter name is a valid Python identifier, its value can be accessed directly from the Player object.

      me.Score = 10
      me.counters['Score'].value += 1
## player.piles

{INCOMPLETE}

Read-only; Returns dictionary containing this player's piles. In this dictionary, the keys are pile names (case-insensitive); the values are the Pile object for that pile name.

NOTE: shared.piles will return a dictionary of all shared piles.

## player.hasInvertedTable()

Returns a boolean value determining if the player has an inverted table; True if the player is on the "inverted side" (side B) of a two-sided table.

Will always return False if the table is not two-sided.

isInverted = me.hasInvertedTable()
print isInverted
>>> True
## player.isActivePlayer

Returns a boolean value determining if it is the player's turn (if it is currently that player's turn);

isActive = me.isActivePlayer
print isActive
>>> False
## player.setActivePlayer()

Will pass the turn to the indicated player. This function works identically to clicking the green "end turn" buttons on the player tabs, and will do nothing if you try to pass to the player who is already the active player.

NOTE: You cannot use this to take control of the turn, so me.setActivePlayer() will NEVER DO ANYTHING!

For 2 player games, you can use players[1].setActivePlayer() to pass the turn to your opponent (since they will always be the [1] index of the players list).

players[1].setActivePlayer()
notify("{} passes the turn to {}.".format(me, players[1]))
>>> "Hugo passes the turn to Vincent."
## player.getGlobalVariable(name)

(see this link for more information on OCTGN's Player GlobalVariable system.)

Argument Type Description
name string The name of a game-defined Global Variable

Returns the STRING stored data that is defined in the Game Definition as **.

NOTE: name is stored in OCTGN as a STRING, and will probably need to be converted back into its original type. You can do this with Python's eval(var) method.

score = eval(me.getGlobalVariable("Score"))
print score
>>> 12
## player.setGlobalVariable(name, value)

(see this link for more information on OCTGN's Player GlobalVariable system.)

Argument Type Description
name string The name of a game-defined Global Variable
value string The value to store into the Global Variable

Stores the value into the Player's game-defined GlobalVariable. NOTE: You can only set your own Player GlobalVariable, all other players are READ-ONLY.

NOTE: The variable MUST be converted to a STRING before it is stored via player.setGlobalVariable(). You can do this with Python's str(var) method.

score = me.counters['Score'].value
me.setGlobalVariable("Score", str(score))


# GROUP CLASS

All API functions in the Group Class require a Group object to be specified.

In OCTGN, the Group class includes the Table object, Hand object, and all Pile objects. Group classes behave like read-only collections. You can count the number of cards len(table), access a specific card me.Deck[3], take a slice me.hand[2:5] or iterate them for c in table.

Note that you can't modify this collection directly, use card.moveTo() and card.moveToTable instead.

The``` game action defined by the game definition will pass the Group object that the action is executed from as a parameter. However, the bulk of these calls get filtered down to either the Table class, Hand class, or Pile class, depending on what group the function was executed from.

FUNCTION DESCRIPTION LAST REVISION
name Returns the group's name.
player Returns the owner of the group.
random() Returns a random card inside the group.
controller Returns the active controller of the group. 2013/09/12 3.1.92
setController() Sets the active controller of the group. 12/09/2013 3.1.92
visibility Return the visibility of the group 3.1.127 ??/??/?? (Implementing Soon)
setVisibility Sets the visibiliy of the group 3.1.127 ??/??/?? (Implementing Soon)
viewers Returns a list of players who can see the group 3.1.127 ??/??/?? (Implementing Soon)
[addViewer()] (#groupaddviewer) Show group cards to a player 3.1.127 ??/??/?? (Implementing Soon)
[removeViewer()] (#groupremoveviewer) Hide group cards from a player 3.1.127 ??/??/?? (Implementing Soon)
## group.name

Returns the name of the Group.

name = group.name
print name
>>> "Hand"
## group.player

Returns the Player object of the owner of this Group.

owner = group.player
notify("{} owns this card.".format(owner))
>>> "Marcel owns this card."
## group.random()

Returns a random Card object inside the group, or None if the group is empty.

card = group.random()
card.moveToTable(0,0)
notify("{} randomly chose {}'s {} and moves it to the Table.".format(me, card.owner, card))
## group.controller

Returns the player who is currently controlling (note: not owning) that group.

## group.setController(player)
Argument Type Description
player Player object The player to pass control to.

Sets the active controller of the group to the specified Player object.

## group.visibility

Returns the visibility of the pile (none, all, custom, me, or undefined)

## group.setVisibility(visibility)
Argument Type Description
visibility string The value to set the visibility to.

Sets the visibility of the group to the specified value. Valid arguments are 'all', 'none', 'me', or 'undefined'.

## group.viewers

Returns a list of players who are allowed visibility for the cards in the group.

## group.addViewer(player)
Argument Type Description
player player The player object to grant visibility to.

Adds the player to the list of players who can see the cards in the group.

## group.removeViewer(player)
Argument Type Description
player player The player object to deny visibility to.

Removes the player from the list of players who can see the cards in the group.

## group.create(guid, quantity = 1)
Argument Type Description
guid string The GUID of the card you want to create
quantity integer (OPTIONAL) The number of cards to create (defaults to 1)

This method will create a card in the group with the specified arguments. It also returns the Card object (or list of Card objects if quantity is greater than 1) of the newly-created card(s).

Cards created through group.create() will always persist when moved out of the group. Use card.delete() to delete the card if necessary.

If the GUID doesn't exist in the database, or quantity is 0, this method will return None instead.

NOTE: to create cards on the table, use table.create() instead.

cards = me.hand.create('dfa86825-5f00-414f-89ae-d5745a4efc8e', quantity = 2)
for card in cards:
    notify("{} created {}.".format(me, card))
>>> "James created Bossdude."
>>> "James created Bossdude."


# TABLE CLASS

All API functions in the Table Class require the Table object to be specified.

The <groupaction> game action defined by the game definition will pass the Table object to the python function as a parameter, if the action is being executed from the Table.

FUNCTION DESCRIPTION LAST REVISION
create() creates new cards onto the table, then Returns those cards
offset() Returns a new tuple (x,y) slightly offset from the input (x,y)
isTwoSided() Returns TRUE if 'Use Two-Sided Table" was enabled.
isInverted() Returns TRUE if if the table is inverted at the given y coordinate
setBoardImage() Changes the Board Image of the table 2013/08/17 3.1.69
## table.create(guid, x, y, quantity = 1, persist = False)
Argument Type Description
guid string The GUID of the card you want to create
x integer The table's x-coordinate to place the card
y integer The table's y-coordinate to place the card
quantity integer (OPTIONAL) The number of cards to create (defaults to 1)
persist boolean (OPTIONAL) Specify if the card should still exist after being moved off the table (defaults to False)

This method will create a card on the table with the specified arguments. It also returns the Card object (or list of Card objects if quantity is greater than 1) of the newly-created card.

As long as persist is False, the cards will vanish from the game when they leave the table via any method.

NOTE: If the GUID doesn't exist in the database, or quantity is 0, this method will return None instead.

cards = table.create('dfa86825-5f00-414f-89ae-d5745a4efc8e', 6, 100, quantity = 2, persist = False)
for card in cards:
    notify("{} created {}.".format(me, card))
>>> "Zack created Cakeman."
>>> "Zack created Cakeman."

Use this function in tandem with askCard() if you want the player to choose a card to create from a filtered list of the card database.

guid = askCard({'Type': 'Token', 'HP': '25'}, 'and')
card = table.create(guid, 0, 0, 1)
notify("{} created {}.".format(me, card))
>>> "Bruce created Cakezilla."
## table.offset(x, y)
Argument Type Description
x integer The x-value of the card
y integer the y-coordinate of the card

Returns a tuple (x,y) of INTEGER coordinates, slightly offset with respect to the input x and y parameters.

This method does a non-trivial work as it takes into account whether the table is two-sided, if y is in the inverted zone and the size of the cards.

{needs an example}

## table.isTwoSided()

Returns True if the table was set to two-sided mode, else False.

if table.isTwoSided():
    notify("The table is two-sided.")
else:
    notify("The table is NOT two-sided.")
>>> "The table is NOT two-sided.")
## table.isInverted(y)
Argument Type Description
y integer a y-coordinate on the table

Checks to see if the local player's Table is inverted at the specified y-coordinate, and will return True if it is inverted, else False.

{practical example needed}

## table.setBoardImage(path)
Argument Type Description
path string the path of the board image to switch to

Changes the board image for the local player. For example, if your game wants to flip the board image upside-down depending on certain game conditions.

When writing the string for the path, a few important rules to keep in mind:

  • double backslashes \ must be used as path separators.
  • If the image is bundled in the game definition, a relative path can be used. Do not start the string with backslashes (i.e. use table.setBoardImage('Board\\board2.jpg') )
  • Although not recommended, you can also target images on the drive (i.e. table.setBoardImage('c:\\imagepath\\image.png') )


# PILE CLASS

All API functions in the Pile Class require a Pile object to be specified.

All Piles are specifically defined in the Game Definition, and none are included with OCTGN. The Hand and Table are not considered to be piles.

The <groupaction> game action defined by the game definition will pass the Pile object to the python function as a parameter, if the action is being executed from a Pile.

FUNCTION DESCRIPTION LAST REVISION
top() Returns top Card object in the pile if count = None, else a list of top 'count' cards.
bottom() Returns bottom Card object in the pile if count = None, else a list of bottom 'count' cards.
shuffle() Securely shuffles the pile.
collapsed Get or set the collapsed status of the pile. 3.1.127 ??/??/?? (Implementing Soon)
lookAt() Open a window to look at the top (or bottom) X cards of the pile. 3.1.127 ??/??/?? (Implementing Soon)
## pile.top(count = None)
Argument Type Description
count integer (OPTIONAL) Specifies how many cards from the top of the pile to select (default None)

Selects count number of cards from the top of the deck, and returns an Array of those cards as Card objects.

If count is None, or not specified, it will return the top Card object of the pile (not an Array).

Will return None if the pile is empty.

card = me.Deck.top()
card.moveTo(me.hand)
cards = me.Deck.top(10)
for c cards:
    c.moveTo(me.Discard)
## pile.bottom(count = None)
Argument Type Description
count integer (OPTIONAL) Specifies how many cards from the bottom of the pile to select (default None)

Functionally similar to pile.top(), except it starts from the bottom of the pile instead of the top.

## pile.shuffle()

Securely shuffles the pile.

me.Deck.shuffle()
>>> "Clark's Deck is shuffled"
## pile.collapsed

Returns a boolean value representing the collapsed status of the pile in the interface.

It can also be used to change the collapsed status of the pile

print me.piles['Discard Pile'].collapsed
>>> False
me.piles['Discard Pile'].collapsed = True
print me.piles['Discard Pile'].collapsed
>>> True
## pile.lookAt(count, isTop)
Argument Type Description
count integer Specifies how many cards to look at. (default All)
isTop boolean (OPTIONAL) Look at the top (True) or bottom (False) of the pile. (default True)

Opens a card selector dialog with the top (or bottom) cards from the deck. Specifying a negative number will display all of the cards in the deck. Specifying 0 will give the local player a prompt of how many cards to look at. This is like using the "Look at" context menu items.



# CARD CLASS

All API functions in the Card Class require a Card object to be specified. Card objects are indexed in OCTGN by their INTEGER _id value, which is assigned whenever the Card object is created.

Python can return the Card object using Card(_id), making the _id integer value useful for storing card information with functions such as setGlobalVariable().

The <cardaction> game action defined by the game definition will pass the Card object to the python function as a parameter, if the action is being executed from a card (in any location).

FUNCTION DESCRIPTION LAST REVISION
_id Returns the unique identity value of the card
name Returns the chat-hoverable name of the card
model Returns the GUID of the card
properties Returns dictionary of all the card's custom properties and their values
[owner](OCTGN #cardowner) Returns the player OBJECT of the card's owner.
controller Returns the player OBJECT of the card's current controller.
group Returns the group OBJECT that the card is currently located in.
markers Returns a DICTIONARY of all markers which can be edited via python.
isFaceUp Returns or Sets the card's visibility status.
alternate Returns the 'type' string (from the set XML) if a card is in an Alternate form, else "".
anchor Anchors the card to the table, preventing players from manually moving it 2015/01/14 3.1.157
size() Returns the name of the card's current custom size 2015/01/19 3.1.159
alternates() Returns a LIST of all Alternate forms of the card, identified by their 'type' string.
alternateProperty() Returns a property value from an alternate form of the card. 2013/05/24 3.1.35
switchTo() Switches a card to the specified Alternate form
highlight Returns or Sets the current highlight color as a string in #HEX color format.
orientation Returns or Sets the current rotation of a card in 90 degree intervals.
position Returns the x,y coordinates of the card.
moveToTable() Moves a card to specified coordinates on the table.
moveTo() Moves a card to a specified group. Top of piles if index = None.
moveToBottom() Moves a card to the BOTTOM of a specified PILE.
arrow() Draws an arrow from the card to another card. active = False will remove the arrow.
setController() Changes a card's controller.
getIndex Returns the current index (z-value) of the card in a group.
setIndex() Sets the current index (z-value) of the card in a group.
select() Adds the card to the current selection.
target() Targets the card, or removes target if active = False.
targetedBy Returns the player OBJECT who is targeting the card.
width() Returns the card's width as defined by the game.
height() Returns the card's height as defined by the game.
sendToBack() Sends the card behind all other cards on the TABLE ONLY
sendToFront() Sends the card in front of all other cards on the TABLE ONLY
peek() Reveals the identity of the card to the local player while keeping it face-down.
delete() Eliminates the card from the game. 2013/09/10 3.1.91
## card._id

Returns the unique INTEGER identity value assigned to the Card object. This identifier is generated by OCTGN when the Card object is created. It is different than the card's GUID, which is used to pull custom properties and image from the card database.

id = card._id
print id
>>> 65528
## card.model

Returns the STRING GUID of the Card object.

guid = card.model
print guid
>>> "dfa86825-5f00-414f-89ae-d5745a4efc8e"
## card.name

Returns the STRING name of the card. This is useful when trying to store the card's name into other variable types, as the Card object only converts to the card's name in notify() and whisper() methods.

name = card.name
print name
>>> "Ace of Diamonds"
## card.properties

Returns the dictionary of all custom card properties as defined by the game definition. In the dictionary, each Key is a property name (case-insensitive); each Value is the value of the property.

The Card class provides dynamic properties to easily access game-defined properties, e.g. card.Type or card.Cost. Those dynamic properties are case-insensitive. If the property name can't be used that way (i.e. it contains some invalid symbol such as a dot or a space), use the long syntax instead: card.properties["Collector Number"].

properties = card.properties
print properties
>>> {'suit': 'Hearts', 'value': 'King', 'color': 'Red'}
print card.Suit
>>> 'Hearts'
## card.owner

Returns the Player object of the player who owns that card. The owner is the player who initially loaded the deck, or created it via create().

owner = card.owner
notify("{} is the owner of {}.".format(owner, card))
>>> "Bill is the owner of Ace of Spades."
## card.controller

Returns the Player object of the player who currently controls that card. The controller is the player who can manipulate the card.

controller = card.controller
notify("{} is the controller of {}.".format(owner, card))
>>> Sam is the controller of Ace of Spades.
## card.group

Returns the specific group (as either a Pile object, Hand object, or Table object) that the card is currently residing in. Note that this will never actually return a Group Object.

Note: since this is read-only, you cannot change a card's location with card.group. Instead, use methods like moveTo() or moveToTable().

group = card.group
if group == table:
    notify("{} is currently in {}.".format(card, group))
>>> Three of Hearts is currently in table.
## card.isFaceUp

Returns a boolean value representing the visibility of the card. Face-up cards are visible to all players, and will show the card's image. Face-down cards are non-visible for all players, showing the card's default back image.

if card.isFaceUp:
    notify("{} is currently face-up.".format(card))
>>> Jack of Hearts is currently face-up.

If the card is face-down, then Python cannot identify the card's name or properties. The card name will not be hoverable.

if not card.isFaceUp:
    notify("{} is currently face-down.".format(card))
>>> Card is currently face-down.

It can also be used to set the visibility status of the card. Setting a card face-down will force Python to "Forget" the card's name and properties.

NOTE: If a card is being flipped face-down, make sure you place the notify text FIRST, otherwise you'll lose the name of the card.

notify("{} flips {} face-down.".format(me, card))
>>> Jen flips King of Clubs face-down.
card.isFaceUp = False
notify("{} flips {} face-down.".format(me, card))
>>> Jen flips Card face-down.
## card.alternate

Returns the STRING Alternate Form that the card is currently in, as defined by the alternate's Type in the set xml. If the card is in its standard Form, it will return a blank string instead.

alternate = card.alternate
print alternate
>>> ''
## card.size()

Returns the STRING identifier name assigned to the card's custom size. If the card is using the default card size, it returns "default".

## card.alternates()

Returns a List of all Alternate Forms of a card, as defined by the alternate's Type in the set xml. If the card has no alternate forms, the list will be empty.

alternateList = card.alternates()
print alternateList
>>> ['altA', 'altB']
## card.alternateProperty(alt, prop)
Argument Type Description
alt STRING The Alternate Form to get the property from.
prop STRING The Custom Property to identify the value of.

Returns the STRING or INTEGER value of a Custom Property belonging to a non-active Alternate Form of that card.

altProperty = card.alternateProperty("A", "Suit")
print altProperty
>>> "Hearts"
## card.switchTo(type = None)
Argument Type Description
type String (OPTIONAL) The Alternate Form to switch to.

This will swap the card to the specified Alternate Form 'type', if one exists.

if no type is specified, the card will revert to its standard form.

card.switchTo('altA')
## card.peek() *New in Octgn 3*

Reveals the identity of the card to the local player while keeping it face-down. This is identical to manually right-clicking and selecting "Peek at Card". An eye icon will appear on the card, and hovering over it will show who is peeking at it.

Peeking at a card will allow Python to access the card's name and properties as though it were face-up.

Peeking at face-up cards does not have any effect.

if not card.isFaceUp:
    card.peek()
    notify("{} is peeking at {}.".format(me, card))
>>> Diane is peeking at Queen of Spades.
## card.setController(player) *New in Octgn 3*
Argument Type Description
player Player object the player to pass control to.

This function mimics the functionality of the "pass control to --> player name" menu option when you right-click a card. The Player object will become the controller of the card.

While it is possible to take control of other player's cards, this will soon be removed from the code base.

card.setController(players[1])   #will pass control to your opponent (in two-player games)
notify("{} passes control of {} to {}.".format(me, card, players[1]))
>>> Joseph passes control of Six of Hearts to Jane.
## card.orientation

Returns the current orientation, or rotation, value of the card as an INTEGER value between 0 and 3. OCTGN has four pre-defined constants that represent each of these values, which are interchangable:

0 = Rot0 1 = Rot90 2 = Rot180 3 = Rot270

rotation = card.orientation
return rotation
>>> 2

It can also be used to SET the orientation of a card.

card.orientation = Rot180
notify("{} rotated {} upside-down.".format(me, card))
>>> Jacques rotated Ace of Spades upside-down.

Note that those constants can be used in mathematical expressions as well:

rotation = card.orientation
card.orientation = rotation + Rot90
notify("{} rotated {} by 90 degrees.".format(me, card))
>>> Jacques rotated Ace of Spades by 90 degrees.
## card.highlight

Returns the color of the highlight that is currently drawn around the card. The returning value is a STRING in HEX (#rrggbb) color format, or None if no highlight is currently on the card.

color = card.highlight
return color
>>> '#33AAFF'

It can also Set a highlight color for the card, replacing any previous color that may already be drawn. To simplify this, it is recommended to declare constants in your script file to refer to specific colors.

AttackColor = "#ff0000" # Red

card.highlight = AttackColor
## card.position

Returns a TUPLE representing the x and y coordinates (as INTEGERs) of the card's position on the table.

position = card.position
print position
>>> (3, 100)
x, y = card.position
print x
>>> 3
print y
>>> 100

NOTE: This will NOT move the card around on the table, use card.moveToTable() instead.

## card.getIndex

Returns an INTEGER of the card's index in the group it is located in. Index's are always INTEGER values of 0 or larger.

In a pile, an index of 0 is the top of the deck.

In a hand, an index of 0 is the left-most card.

On the table, an index of 0 is the card furthest to the back (behind all other cards).

index = card.getIndex
print index
>> 3
## card.setIndex(index)
Argument Type Description
index Integer The index value to move the card to on the table. (Must be 0 or greater)

Moves the card to the specified index value on the table. In OCTGN, a card's index determines the order in which cards are 'stacked' on other cards. A card with an index of 0 is on the 'bottom', behind all other cards.

card.setIndex(5)

NOTE: This function only works for cards on the table. For cards in hands or piles, use card.moveTo() instead.

## card.sendToBack()

Forces the card's index to 0, placing it behind all other cards.

NOTE: This function only works for cards on the table. For cards in hands or piles, use card.moveToBottom() instead.

## card.sendToFront()

Forces the card's index large enough to be placed above all other cards.

NOTE: This function only works for cards on the table. For cards in hands or piles, use card.moveTo() instead.

## card.markers

Returns the Marker Object for the card. This Object is simply a dictionary of markers set on the card. Keys in the dictionary are (name, GUID) tuples, where STRING name is the name assigned to that marker, and STRING GUID is the GUID of that marker. Values in the dictionary are INTEGER quantity representing the number of that specific marker.

The GUID in the Key is used to retrieve a database image for that marker as defined in a Set Definition XML, if one exists. If no match is found for that GUID, a pre-set marker image will be randomly assigned to that marker (see below).

quantity = card.markers[("Damage Marker", "fabd2965-929e-4ee9-b69c-e278e3cd4098")]
print quantity
>>> 3

If two keys contains the same GUID but a different name (or vice versa), OCTGN will treat these as different marker objects. As such, it is HIGHLY recommended to define constants for all of your markers in your python scripts. This makes it easier to reference the marker you wish to use, and prevents unnecessary duplicates of dictionary keys.

damageMarker = ("Damage Marker", "fabd2965-929e-4ee9-b69c-e278e3cd4098")
quantity = card.markers[damageMarker]
print quantity
>>> 3

MODIFYING THE MARKER DICTIONARY

You can add or remove markers from a card by modifying the Marker Object. This can be done by performing mathematical operations on the dictionary's values.

damageMarker = ("Damage Marker", "fabd2965-929e-4ee9-b69c-e278e3cd4098")
# Adding one marker
card.markers[damageMarker] += 1
# Removing one marker
card.markers[damageMarker] -= 1
# Setting the marker to a value
card.markers[damageMarker] = 4
print card.markers[damageMarker]
>>> 4

OCTGN includes its own internal set of marker images, which it will randomly assign to the Marker Object, in the event that the GUID is not found in the database. You may also directly call these markers via the following GUIDs:

  "00000000-0000-0000-0000-000000000001" - white
  "00000000-0000-0000-0000-000000000002" - blue
  "00000000-0000-0000-0000-000000000003" - black
  "00000000-0000-0000-0000-000000000004" - red
  "00000000-0000-0000-0000-000000000005" - green
  "00000000-0000-0000-0000-000000000006" - orange
  "00000000-0000-0000-0000-000000000007" - brown
  "00000000-0000-0000-0000-000000000008" - yellow
## card.moveTo(group, index = None)
Argument Type Description
group Group Object The group where the card is moved to.
index Integer (OPTIONAL) A position within the group that the card is moved to.

NOTE: Only Pile objects and Hand objects can be the targets of the group argument. For the Table object, use moveToTable() instead.

Moves the card to the specified group. If an index is included, then the card will be placed at that index, starting at the top of piles or from the left side of the hand.

The default index is the top of piles, and to the right in hands.

# will move the card 1 below the top card of a deck
card.moveTo(me.Deck, 1)
# will move the card to your hand
card.moveTo(me.hand)
## card.moveToBottom(pile)
Argument Type Description
pile Pile object The pile where the card is moved to.

Moves the card to the bottom of the specified pile. Only Pile Objects can be used for this function, which does NOT include the Hand object or the Table object.

card.moveToBottom(me.Deck)
## card.moveToTable(x, y, forceFaceDown = False)
Argument Type Description
x Integer The x-position to move the card to.
y Integer The y-position to move the card to.
forceFaceDown Boolean (OPTIONAL) Forces the card to move to the table face-down.

Moves the card to the table at the given (x, y) co-ordinates. If the forceFaceDown argument is given as False, the card will be securely moved face-down, preventing players from knowing its identity.

card.moveToTable(300, -150, True)
## card.select()

Adds the card to current selection, or creates a selection if one is not already available. Control+Click on a card will also add the card to a selection.

## card.anchor

Returns True if the card is anchored to the table, preventing players from manually moving it via drag-clicking. This will not prevent Python from moving the card via card.moveToTable(). Will return False if the card is not anchored.

isAnchored = card.anchor
return isAnchored
>>> False

It can also Set the anchor status for the card, by setting it to True. To turn off the anchor status, set it to False.

card.anchor = True

return card.anchor
 >>> True
## card.target(active = True)
Argument Type Description
active Boolean (OPTIONAL) Whether or not to draw a targeting reticle over the card (defaults to True)

Creates a targeting reticule icon on the card. If active is False, it will remove all targets from the card instead.

## card.targetedBy

Read-only, returns the Player object of the player who is targeting this card, or None if the card is not targeted.

if card.targetedBy == me:
   card.markers[ChargeMarker] += 1
## card.arrow(target, active = True)
Argument Type Description
target Card object The card that the arrow will point to.
active Boolean (OPTIONAL) Whether or not to draw an arrow or remove an existing one (defaults to True)

If active is set to True, this will draw an arrow from the card, pointing to the target Card object.

If active is set to False, it will remove all targeting arrows originating from the card (currently, the target card is irrelevant in this case). It will not remove arrows pointing to it.

## card.width()

Returns the INTEGER width value of the card as defined in the game definition.

## card.height()

Returns the INTEGER height value of the card as defined in the game definition.

## card.delete()

Eliminates the card from the game. This works the same way as creating cards through table.create() with persist = False.

Note that this is irreversible, so cards that are deleted cannot be recovered.



# EVENT FUNCTIONS

These are specialized functions that are executed when specific game events are triggered. They all require the game event to be defined in the <events> tag of the game's definition xml. For each event defined in the XML, you MUST include the correspondingly named function in your scripts file(s).

The following events are listed by their XML EVENT NAME, as used in the name attribute in the <event> element. The name of the corresponding Python function is defined as you choose in the action attribute. As an example:

<event name="OnMoveCards" action="moveCards" />

would use the OnMoveCards event, which would pass the appropriate variables to your python function

def moveCards()

NOTE: The variables, if any, are passed IN THE ORDER WHICH THEY ARE LISTED HERE.

EVENT NAME DESCRIPTION LAST REVISION
OnTableLoad Triggers when the table initally loads
OnGameStart Triggers when the table initially loads, and after each game restart
OnPlayerConnect Triggers when a player reconnects to a game
OnPlayerLeaveGame Triggers when a player leaves a game
OnLoadDeck Triggers when a player loads a deck
OnChangeCounter Triggers when a player adjusts one of their counters
OnEndTurn Triggers when a player ends their turn
OnTurn Triggers when a player has interrupted the ending of a turn
OnTargetCard Triggers when a player targets a card
OnTargetCardArrow Triggers when a player draws a target arrow between two cards
OnMoveCards Triggers when a player moves cards
OnScriptedMoveCards Triggers when a player moves cards
OnPlayerGlobalVariableChanged Triggers when a player's global variable changes
OnGlobalVariableChanged Triggers when a global variable changes
OnCardClick Triggers when a player clicks a card
OnCardDoubleClick Triggers when a player double-clicks a card
OnMarkerChanged Triggers when a card's markers change
## OnTableLoad

This event triggers when the table is loaded up for the first time. It will not trigger when you restart a game.

It does not pass any variables.

## OnGameStart

This event triggers when the table is initially loaded, as well as during a game restart. It does not pass any variables.

## OnPlayerConnect
Parameter Type Description
player Player object The player that reconnected to the game.

This event triggers when a player successfully reconnects to the game.

## OnPlayerLeaveGame
Parameter Type Description
player Player object The player leaving the game.

This event triggers when a player leaves the game, either through a disconnection, or by terminating the game window (intentionally or through a crash).

NOTE that since the player is no longer in the game, parts of the Player object's data may be unusable or missing.

## OnLoadDeck
Parameter Type Description
player Player object The player that loaded the deck.
groups list<Group object> List of groups that cards were added to.

This event triggers when a player loads a deck. Note that the event does not know which cards were loaded, just the groups in which cards were loaded into.

## OnChangeCounter
Parameter Type Description
player Player object The player whose counter was changed.
counter Counter object The counter that was changed.
oldValue integer The original value of the counter.

This event triggers when a player's counter is changed. It does not pass the player who performed the change.

Since counter is a Counter object, it can be directly manipulated. For example, to return the the new value of the counter, use player.counter.

## OnEndTurn
Parameter Type Description
player Player object The player whose turn is ending.

This event triggers when the player turn changes, and passes the player who is ending their turn.

## OnTurn

(UNFINISHED, NEEDS VERIFICATION)

Parameter Type Description
player Player object

This event triggers when a player interrupts the ending of a turn by toggling the yellow PAUSE symbol on the player tabs.

TODO: Verify if the event passes the player who is pausing the turn, or the player whose turn is being paused.

## OnTargetCard
Parameter Type Description
player Player object The player targeting the card
card Card object The card being targeted.
isTargeted boolean True if the card was targeted, False if it was de-targeted.

This event triggers when a card is targeted, or de-targeted. This will trigger for both the manual targetting (shift-click the card), and the python card.target() function.

## OnTargetCardArrow
Parameter Type Description
player Player object The player targeting the card
fromCard Card object The card at the base of the arrow.
toCard Card object The card at the point of the arrow.
isTargeted boolean True if the arrow was drawn, False if it was removed.

This event triggers when a target arrow is drawn between fromCard and toCard. This will trigger for both the manual targetting (shift-drag one card to the other), and the python card.targetArrow() function.

## OnPlayerGlobalVariableChanged
Parameter Type Description
player Player object The owner of the global variable
name Player object The name of the global variable
oldValue Player object The original value of the variable
value Player object The new value

This event triggers when a player's global variable gets changed via the python player.setGlobalVariable() function.

## OnGlobalVariableChanged
Parameter Type Description
name Player object The name of the global variable
oldValue Player object The original value of the variable
value Player object The new value

This event triggers when a global variable gets changed via the python setGlobalVariable() function.

## OnCardClick
Parameter Type Description
card Card object The card being clicked
mouseButton integer the mouse button which clicked the card
keysDown list A list of STRING key names

This event triggers whenever a card is clicked. mouseButton is an integer value, with 0 being the left button and 2 being the right button. keysDown is a list of all key names being held while the card is clicked.

NOTE: The 'middle' mouse button (scroll wheel) has reserved usage in OCTGN and will not trigger this event.

## OnCardDoubleClick
Parameter Type Description
card Card object The card being clicked
mouseButton integer the mouse button which clicked the card
keysDown list A list of STRING key names

This event triggers whenever a card is double-clicked. mouseButton is an integer, with 0 being the left button. keysDown is a list of all key names being held while the card is clicked.

NOTE: The 'middle' mouse button (scroll wheel) has reserved usage in OCTGN and will not trigger this event. The 'right' mouse button does not trigger this event either.

## OnMarkerChanged
Parameter Type Description
card Card object The card whose markers are changed
markerName string the name of the marker being changed
oldValue integer The old value of the marker
newValue integer The new value of the marker
isScriptChange boolean True if Python changed the values, False if manually changed

This event triggers whenever a marker's value is changed on a card. Note that markerName is a string and not a Marker object, however the marker object can be returned by

card.markers[markerName]

Note that the isScriptChange parameter can be used to identify if the marker was manually changed by a player, of if Python changed the value.

## OnMoveCards
Parameter Type Description
player Player object The player moving the cards
cards list<Card object> the cards being moved
fromGroups list<Group object> the original groups of the cards
toGroups list<Group object> the new groups for the cards
oldIndexs list<integer> the original z-indexes of the cards
indexs list<integer> the new z-indexes of the cards
oldX list<integer> the old X coordinates of the cards
oldY list<integer> the old Y coordinates of the cards
x list<integer> the new X coordinates of the cards
y list<integer> the new Y coordinates of the cards
highlights list<string> the original highlight colors on the cards
markers list<dictionary> the original marker dictionaries on the cards
faceup list<boolean> the faceup statuses of the card
This event triggers when one or more cards are simultaneously moved from one location to another. As cards in a selection can be moved simultaneously, the parameters cards fromGroups toGroups oldIndexs indexs oldX oldY X Y highlights markers and faceup are all passed as lists in a single trigger. This will require the function to iterate through the lists to match up all values.

An example of iterating through the lists, while matching the variables to the list index of the card:

def moveCardFunction(player, cards, fromGroups, toGroups, oldIndexs, oldX, oldY, X, Y, highlights, markers, faceup):
	index = 0
	for card in cards:
		oldCoords = (oldX[index], oldY[index])
		newCoords = (X[index], Y[index])
		group = toGroups[index]
		highlight = highlights[index]
		notify("{} moves {} to {}.".format(player, card, group))
			>>> "Janson moves Ace of Spades to Deck"
		index += 1

NOTE: the highlight list items will be in a STRING HEX (#rrggbb) color format, or None if no highlight is currently on the card.

The marker list items will be in a STRING equivalent of the Marker object, and will need to be converted to the marker dictionary via eval()

## OnScriptedMoveCards

(see previous)



EXTRA STUFF

Tip: how to select cards

Python has nice comprehensions to select objects. Here's a way to get all Land cards you control on the table:

tableLands = [card for card in table
         if card.controller == me
         and re.search(r'\bLand\b', card.type)]

You can then iterate through them in a loop:

for card in tableLands: card.moveTo(me.Discard)

or count them

notify("You've got {} lands on the table".format(len(tableLands)))

you can even use on-the-fly list comprehensions to reveal cards from a player's hand without having to put them on the table first.

notify("{} is holding the following actions in their hand: {}".format(me,[card.name for card in me.hand if card.Type == 'Action']))

etc...

Re

re is the Regular Expression engine built-into Python, which is very useful to perform text matching. You need to import it first:

    import re

The expression above: re.search(r'\bHero\b', card.type) checks whether the word 'Hero' (\b are marking word boundaries in a RegExp) appears into card.type.