-
Notifications
You must be signed in to change notification settings - Fork 130
OCTGN Python 3.1.0.2 API Reference
This document outlines the Python API version 3.1.0.2 used by OCTGN's scripting engine. Previous API versions are no longer documented or officially supported by OCTGN.
A list of functional changes to API from 3.1.0.1 can be found here: https://gist.github.com/brine/cd5d674a06c98ead1404#file-3-1-0-2python
DESCRIPTION | |
---|---|
Global Class | Generic functions |
Player Class | Require a Player object to be passed |
Group Class | Accepts Table 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 |
Event Override Functions | Special functions that change the default behavior of common OCTGN actions |
CHANGES MADE TO API FUNCTIONS
DATE | CHANGE | DESCRIPTION |
---|---|---|
2022-12-28 | card.defaultProperty() | NEW |
2020-11-27 | table.refit() | NEW |
2020-11-27 | table.reset() | NEW |
2020-11-22 | card.isSelected() | NEW |
2020-11-22 | softResetGame() | NEW |
2020-07-03 | card.peekers | NEW |
2020-05-21 | card.select() | CHANGED |
2020-05-21 | clearSelection() | NEW |
2020-05-21 | card.hasProperty() | NEW |
2020-05-21 | pile.collapsed | CHANGED |
2020-05-21 | pile.viewState | NEW |
2018-01-29 | choosePack() | API function was added September 2016 but has been undocumented until now |
2018-01-29 | generatePack() | API function was added September 2016 but has been undocumented until now |
2018-01-29 | queryCard() | API function was added July 2017 but has been undocumented until now |
2018-01-28 | rndArray() | NEW |
2017-08-12 | getActivePlayer() | NEW |
2017-08-12 | setActivePlayer() | NEW |
2017-08-12 | getStop() | NEW |
2017-08-12 | setStop() | NEW |
2017-08-12 | nextTurn() | NEW |
FUNCTION | DESCRIPTION | LAST REVISION |
---|---|---|
askCard() | Shows a dialog box of cards from the database matching certain parameters | |
cardDlg() | Creates a dialog box of card objects from a list for the user to choose from | |
askChoice() | Shows a dialog box with multiple buttons that the user can choose from | |
askInteger() | Creates a dialog box to input a number | |
askMarker() | Shows a dialog box so that the user can choose a marker type and quantity | |
askString() | Creates a dialog box to input a string | |
choosePack() | Shows a dialog box to choose a card package | NEW! 2016-09-07 |
currentGameName() | returns the user-defined name for this game | |
currentPhase() | Returns the index number of the current phase | |
setPhase() | Sets the current game phase | |
getStop() | Checks if the local player has a stop set in the defined phase | NEW! 2017-08-12 |
setStop() | Sets a stop in the defined phase | NEW! 2017-08-12 |
nextTurn() | Passes the turn to the defined player | NEW! 2017-08-12 |
getActivePlayer() | Gets the active turn player | NEW! 2017-08-12 |
setActivePlayer() | Sets the active turn player | NEW! 2017-08-12 |
confirm() | Creates a yes/no dialog box | |
gameVersion | Returns the game definition's current version | |
generatePack() | Generates a card package and returns the card GUIDs | NEW! 2016-09-07 |
getGlobalVariable() | Returns the value of a game-defined global variable | |
getSetting() | Returns a saved game setting | |
mute() | Mute's OCTGN's automatic chat log notifications | |
notify() | Sends a notification message to all players | |
notifyBar() | Sends a notification message to all players | |
openUrl() | Opens the URL in your default browser | |
getPlayers() | Returns a list of all players in the game | |
playSound() | Plays a pre-defined sound file | |
queryCard() | Queries the game's card database for all cards matching specified parameters | NEW! 2017-07-07 |
remoteCall() | Invokes a function remotely for a specific player | |
resetGame() | Reset the game | |
rnd() | Generates a single random number between two integers | |
rndArray() | Generates a list of random number between two integers | NEW! 2018-01-28 |
setGlobalVariable() | Sets the value of a game-defined global variable | |
setSetting() | Saves a game setting | |
softResetGame() | Soft-resets the game, reloading the original decks | ** NEW! Nov 2020 ** |
turnNumber() | Returns the internal turn count | |
version | Returns OCTGN's current version | |
webRead() | Reads the contents of a URL and the HTTP status code | |
whisper() | Sends a notification message to the local player | |
update() | Forces the Python engine to wait until OCTGN's queued networking processes are finished. | |
clearSelection() | Clears any active card selections in the game state | NEW! MAY 2020 |
Prevents OCTGN from logging its default messages to the chat log. This will affect all further API calls until the function finishes execution.
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.
Note that mute()
only affects the scope of the executing function, and will not persist outse of the function. By default it will mute all API-based messages from the point it is invoked onwards. To selectively mute a section of code, either break it into it's own function, or use python's with
block syntax.
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..
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."
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.
Argument | Type | Description |
---|---|---|
min | integer | The lowest possible integer to be selected |
max | integer | The highest possible integer to be selected |
Returns a random INTEGER value between min and max, inclusive. The random number is generated by the server instead of the local client, which is more secure but not as fast as a number generated via python's RNG methods.
num = rnd(3, 6)
print num
>>> 5
Argument | Type | Description |
---|---|---|
min | integer | The lowest possible integer to be selected |
max | integer | The highest possible integer to be selected |
count | integer | How many numbers to be randomly generated |
Returns a list of randomly generated INTEGER value between min and max using OCTGN's PRNG method.
Example: Rolling multiple dice
def rollXDice(group, x = 0, y = 0):
dicecount = askInteger("Roll how many dice?", 2)
if dicecount > 0:
return
rolls = rndArray(1, 6, dicecount)
for roll in rolls:
notify("{} rolls a {}.".format(me, roll))
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.
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')
Read-only: Returns the current turn number as an INTEGER (from the internal turn counter).
turn = turnNumber()
print turn
>>> 7
Read-only: Returns the data regarding the current game phase as a tuple (name, index). name
is the STRING name given to that phase, and index
is an INTEGER index value, corresponding to the sequential order of the game phases defined in the XML. The index starts at 1, as 0 is a null default phase.
turn = currentPhase()
print currentPhase
>>> ('Draw Step', 2)
Argument | Type | Description |
---|---|---|
index | integer | the index number of the desired phase |
Sets the current phase to the indexed value corresponding to the sequential order of the game phases defined in the XML. The index starts at 1, as setting 0 will set it to the default null phase.
Note that this function follows the same interactions as manually changing the phase via the Phase Toolbar: Only the active player will be able to change the game phase, and will trigger the pause and prevent changing phases if a player has the current phase paused.
setPhase(1)
>>> It is now Fred's Draw Step
Argument | Type | Description |
---|---|---|
player | Player object | optional, default None, The initial Active Turn Player for the next turn |
force | boolean | optional, default False, tells the server to ignore any active stops |
Passes the turn to the defined player. If player is set to None, then there will be no active turn player set in the new turn. This is functionally similar to clicking the green "Pass Turn" button on the player's tab: Only the active turn player will be able to pass the turn, and if successful it will increment the current turn counter by 1.
NOTE: This call respects any stops set by players in a phase AFTER the current phase, and the end of turn stop. It will stop at the next sequential stopped phase instead of passing to the next turn. If you want to ignore all stops, set force to True.
nextTurn(me, False)
>>> - Turn 1: Dale -
Returns the active turn player. Will return None if there is no active player.
Argument | Type | Description |
---|---|---|
player | Player object | optional, default None, The Active Turn Player |
Sets the active turn player, or removes the active turn player if player is set to None.
NOTE: Only the active turn player can change this.
Argument | Type | Description |
---|---|---|
id | integer | The phase's ID value |
Returns True if the local player has a stop set at the defined phase. If the id is set to 0, it will return True if there's a stop set at the end of turn instead.
NOTE: You can't see the stops set by other players.
Argument | Type | Description |
---|---|---|
id | integer | The phase's ID value |
stop | boolean | The toggle status of the phase's stop |
Sets a stop at the defined phase. If the id is set to 0, it will set an end-of-turn stop instead.
If stop is TRUE, it will set the stop. If FALSE, it will remove the stop instead.
NOTE: You cannot change the stops by other players.
Read-only: Returns the name that the hosting player gave to the currently hosted game.
name = currentGameName()
print name
>>> "Beginners Game: No Pros!"
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
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
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"
Displays a dialog box with all markers defined by the game, so that the user can create a new marker and assign a quantity to it.
Returns a tuple (id, quantity), where STRING id is the unique identifier for 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).
The dialog will save any custom markers created by the user, allowing them to access them again for future uses.
marker, qty = askMarker()
if qty == 0: return
card.markers[marker] += qty
print marker
>>> 'damage'
print qty
>>> 4
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.
FUNCTION; Displays a dialog so that the user can choose a card and quantity. Cards are pulled from the card database and filtered based on property matches listed in the dictionary.
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
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]
FUNCTION; Returns a LIST of GUIDs of cards in the game's database which matches a specified set of properties.
Argument | Type | Description |
---|---|---|
properties | see below | A dictionary of property:value pairs to search for. |
exact | boolean | (OPTIONAL) default False; Forces an exact match to the property's value if True. |
The properties parameter must be a properly formatted Python Dictionary.
- The dictionary Keys are case-insensitive STRINGs of the card properties you want to match. You can use any custom property defined in the game, or the card's
Name
. - Dictionary Values are the property values you wish to match. Most common usage are STRING values. You can also use a LIST containing multiple STRING values, which can be used to match (via an OR operation) multiple possible values for that property.
The optional exact boolean can be used to force exact string matches for every property value. By default it is False, allowing partial matches.
Example: Query for all Red Queen cards
cards = queryCard({"Color":"Red","Rank":"Queen"}, True)
return cards
>>> [a9bf4eaf-389a-48c7-966d-a6c523b903e7, 7302af84-6ea9-43aa-8b50-f9f875854501]
>>> returns GUIDs for [Queen of Hearts, Queen of Diamonds]
Example: Query for all Red Queens or Red Kings
cards = queryCard({"Color":"Red","Rank":["Queen", "King"]}, True)
return cards
>>> [a9bf4eaf-389a-48c7-966d-a6c523b903e7, 7302af84-6ea9-43aa-8b50-f9f875854501, eb7a9dd8-cf5c-4aa3-b945-3c828fbad381, 6da3d68a-cd87-46ba-9d10-6da0da48989e]
>>> returns GUIDs for [Queen of Hearts, Queen of Diamonds, King of Hearts, King of Diamonds]
Class; Creates a cardDlg object defining a customized card selection dialog window. This dialog window can support one or two subgroups (selection boxes) of cards, and can allow players to drag-and-drop cards between the two selection boxes, or re-order the contents of one box. Players can also select one or more cards from a box which will be returned as a list.
Start by initializing a new cardDlg object, by assigning it to a variable and passing a list
of card objects as so:
dlg = cardDlg(list)
To initialize a two-box cardDlg, pass a second list instead (either list can be empty):
dlg = cardDlg(list, bottomList)
The following are optional properties which can be get/set to the cardDlg object to customize the appearance and functionality of the dialog window:
Property | Type | Description |
---|---|---|
title | string | The title label of the dialog window (default is "Choose Card") |
text | string | The contents of the multi-line text box above the card selection boxes |
label | string | The label that appears above the first card selection box (beside the filter box) |
bottomLabel | string | The label on the lower card selection box, if enabled |
min | integer | The min number cards allowed in selection (for single box) or in upper box (for double box) |
max | integer | The max number cards allowed in selection (for single box) or in upper box (for double box) |
list | List<Card object> | The list of cards to appear in the upper selection box |
bottomList | List<Card object> | The list of cards to appear in the lower selection box |
For single selection boxes, min and max are defaulted to 1.
- If both min and max are 1, then the dialog window is in Single Selection mode. While in this mode, players can only select one card. Double-clicking on a card will automatically choose that card and close the window, returning that card as the only item in the list.
- If both min and max are 0, then the dialog window is in Re-order mode. While in this mode, players can only rearrange the cards in the box. Confirming the box will update the contents of the
list
dlg property to the newly rearranged order. - If any other value, the dialog is in Multi Selection mode. While in this mode, players can click to select/unselect multiple cards in the dialog. Confirming the dialog will return a list of all selected cards (in the order they were selected).
For double selection boxes, min is defaulted to 0 and max is defaulted to the total quantity of cards in both boxes. This means that there will be no limitation to the number of cards in either box.
- Setting the max or min to any other value will enforce a maximum or minimum number of cards allowed in the UPPER selection box. If the count of cards in the upper box does not fall between these two values, then the user will not be able to confirm the selection.
- Confirming the selection will update the
list
andbottomList
dlg properties to their new contents. It will also return the selected card (if available) in a list, although this does not have much purpose.
call the show()
function on the cardDlg object to display the dialog window. It will return a list of Card objects that were selected by the dialog window.
cardsSelected = dlg.show()
WARNING: The dialog box will show the card image of all cards in cardList, even if the card is not currently visible to the player (i.e. if it is face-down or in a hidden zone). Ensure that hidden cards are filtered out of the cardList if the player is not supposed to be able to see them.
Example:
dlg = cardDlg([c for c in me.Discard]
dlg.title = "These cards are in your discard pile:"
dlg.text = "Select a Card"
cards = dlg.show()
return cards
>>> ["Three of Hearts"]
(Check out the wiki page for card packs for more information on OCTGN's card packs.)
Opens a dialog box, allowing the user to select a card pack.
Returns a tuple, with the following items:
- The STRING name of the selected pack's Set
- The STRING name of the selected pack
- The STRING GUID of the selected pack
or None if no pack was selected.
Example:
packTuple = choosePack()
print packTuple
>> ("Base Set", "Booster Pack", "2a28ad7d-8559-4d13-b401-371b577dd3d2")
(Check out the wiki page for card packs for more information on OCTGN's card packs.)
Generates a card pack and returns a list of GUIDs for the card contents. This uses the same generation methods as OCTGN's limited deck editor.
Property | Type | Description |
---|---|---|
model | string | the GUID of the desired card pack |
Returns a list of card GUIDs from the pack's contents.
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.
Returns the STRING version of OCTGN that the user is using.
print version
>>> "3.1.82.510"
Returns the STRING version of the game definition that the user is using.
print gameVersion
>>> "1.0.2.0"
Resets the game to its original state, deleting all card objects and returning all player counters to their default values.
Resets the game, returning all player counters to their original values and restoring the previously-loaded decks into their corresponding piles.
NOTE: This function will delete all cards from memory and create new ones for the reloaded decks. Python will treat these as new card objects, so existing script references to the previous game's cards will be lost.
(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"]
(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))
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)
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.
(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')
Argument | Type | Description |
---|---|---|
player | Player object | 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 only safe way to interact with objects(cards, piles, groups, tokens, etc) that are not controlled by the player calling this method (me
).
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",[])
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()
for p in players
remoteCall(p,"soundOff",[p._id,me])
Then, if the host runs invokeSoundOff()
, You would get results like:
[player1]Sounds off 1 (Started by player1)
[player2]Sounds off 2 (Started by player1)
Note: there are no guarantees what order these will appear in, while multiple calls to the same player will arive in order, different players may recive remote calls faster than others.
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.
This function clears any active selections on all cards in the game state. Card selections can occur from ctrl+clicking a card, using a selection box from drag-clicking, or from the card.select()
method.
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
.
PROPERTY | 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 | |
isActive | Returns TRUE if it's currently the player's turn (Active Player) | |
isInverted | Returns TRUE if the player is on the "inverted" side B of a two-sided table. | |
isSubscriber | Checks if the player is a subscriber. | |
name | Returns the player's name. | |
piles | Returns dictionary of all the player's piles and their OBJECTS for manipulations |
FUNCTION | DESCRIPTION | LAST REVISION |
---|---|---|
getGlobalVariable() | Returns the value of a player's game-defined global variable | |
setActive() | Passes the Active Turn status to another player. | |
setGlobalVariable() | Sets the LOCAL PLAYER ONLY's game-defined global variable. |
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
Returns the STRING nickname of this player.
name = player.name
print name
>>> "Bobby86"
Returns a STRING representing the color assigned to the player, in #HEX notation (i.e. #000000).
color = player.color
print color
>>> "#3A3A00"
Sets the player's color, only accepts hex notation (i.e. #000000) NOTE: Only the local player's color can be set this way.
player.color = '#000000'
{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
{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.
READ-ONLY PROPERTY, 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.isInverted
print isInverted
>>> True
READ-ONLY PROPERTY; returns True
if the player is currently set as the active player (if it is their turn).
isActive = me.isActive
print isActive
>>> False
FUNCTION; passes the turn to the 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.setActive() will NEVER DO ANYTHING!
players[1].setActive()
notify("{} passes the turn to {}.".format(me, players[1]))
>>> "Hugo passes the turn to Gamer331."
READ-ONLY PROPERTY; returns True if the player is a subscriber.
(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
(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))
All API functions in the Group Class require a Group object to be specified.
In OCTGN, the Group class includes the Table 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 <groupaction>
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 or the Pile class, depending on what group the function was executed from.
PROPERTY | DESCRIPTION | LAST REVISION |
---|---|---|
controller | the active controller of the group. | |
name | Returns the group's name. | |
player | Returns the owner of the group. | |
viewers | Returns a list of players who can see the group | |
visibility | the visibility setting of the group |
FUNCTION | DESCRIPTION | LAST REVISION |
---|---|---|
random() | Returns a random card inside the group. | |
[addViewer()] (#groupaddviewer) | Show group cards to a player | |
[removeViewer()] (#groupremoveviewer) | Hide group cards from a player |
Returns the name of the Group.
name = group.name
print name
>>> "Hand"
Returns the Player object of the owner of this Group.
owner = group.player
notify("{} owns this card.".format(owner))
>>> "Marcel owns this card."
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))
PROPERTY the player who is currently controlling (note: not owning) that group.
GET
Returns the player object of the group's current controller.
SET
Sets the active controller of the group to the specified Player object.
PROPERTY; the visibility of the pile. There are four available visibility settings available:
-
none
- no player can see the card -
all
- every player can see the card -
me
- only the local player can see the card -
undefined
- the default visibility setting
GET
an additional visibility setting, custom
, can occur if a player has manually added themselves to the list of viewers (via right-click menu).
SET
Will set the visibility to one of the four settings. Note that me
will change visibility exclusively to the player calling the function, removing the other players from visibility.
Returns a list of players who are allowed visibility for the cards in the group.
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.
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.
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."
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.
PROPERTY | DESCRIPTION | LAST REVISION |
---|---|---|
invertBackground | Inverts the background image | |
board | the current game board image layered over the table | |
boards | gets the list of all boards available in the game |
FUNCTION | DESCRIPTION | LAST REVISION |
---|---|---|
create() | creates new cards onto the table, then Returns those cards | |
isTwoSided() | Returns TRUE if 'Use Two-Sided Table" was enabled. | |
refit() | recalculates the table's visible area to fit all cards | NEW! NOV 2020 |
reset() | restores the table's visible area to the original size | NEW! NOV 2020 |
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."
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.")
Recalculates the table's visible area (zoom and position) so that all cards currently on the table are visible.
Resets the table's visible area (zoom and position) to the default settings from the start of the game.
PROPERTY; the inverted status of the background.
GET
Returns True
if the local player's background is inverted, else False
.
SET
If True
, inverts the background for the local player. False
will set the background to its normal orientation.
PROPERTY; the STRING game board name that is currently set on the table, as defined by the game board's Name attribute in the game definition.
The default game board is always denoted as "Default".
GET
board = table.board
print board
>>> 'Default'
SET
table.board = 'altBoard'
NOTE: Changing the game board will network the board change to all other players.
READ-ONLY PROPERTY; The List of all game boards available for the table, as defined by the game board's Name attribute in the game definition.
boardList = table.boards
print boardList
>>> ['Default', 'altBoard']
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 Table is not considered to be a Pile.
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.
PROPERTY | DESCRIPTION | LAST REVISION |
---|---|---|
collapsed | Get or set the collapsed status of the pile. | |
viewState | Get or set the current view state of the pile. | NEW: May 2020 |
FUNCTION | DESCRIPTION | LAST REVISION |
---|---|---|
bottom() | Returns bottom Card object in the pile if count = None, else a list of bottom 'count' cards. | |
lookAt() | Open a window to look at the top (or bottom) X cards of the pile. | |
shuffle() | Securely shuffles the pile. | |
top() | Returns top Card object in the pile if count = None, else a list of top 'count' cards. |
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)
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.
Securely shuffles the pile.
me.Deck.shuffle()
>>> "Clark's Deck is shuffled"
Gets or sets the boolean collapsed state of the pile in the player's view of piles.
True is for the collapsed state. False is for the pile state.
NOTE: As of the May 2020 update, this feature has been deprecated in favor of the new viewState method. pile.collapsed
will return False for both the pile
and expanded
view states, and setting it to False will only set it to the pile
state.
print me.piles['Discard Pile'].collapsed
>>> False
me.piles['Discard Pile'].collapsed = True
print me.piles['Discard Pile'].collapsed
>>> True
NEW for May 2020
Gets or sets the string value representing the current view state of the pile.
The three different states are:
-
collapsed
(the pile is tucked to the right side of the screen, no cards are shown) -
pile
(the pile shows as a single stack of cards) -
expanded
(the cards fan out horizontally and the user can view the entire collection of cards at once.)
NOTE: The expanded
viewState replaces the functionality of the previous Hand groups.
print me.piles['Discard Pile'].viewState
>>> "pile"
me.piles['Discard Pile'].viewState = "expanded"
print me.piles['Discard Pile'].viewState
>>> "expanded"
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.
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).
PROPERTY | DESCRIPTION | LAST REVISION |
---|---|---|
_id | Returns the unique identity value of the card | |
alternate | The card's alternate form. | |
alternates | a LIST of all alternate forms of the card, identified by their 'type' string. | |
anchor | Anchors the card to the table, preventing players from manually moving it | |
controller | the player OBJECT of the card's current controller. | |
filter | the current filter color as a string in #HEX color format. | |
group | Returns the group OBJECT that the card is currently located in. | |
index | the current index (z-value) of the card in the group it is in. | |
isFaceUp | Returns or Sets the card's visibility status. | |
isSelected | Returns the selection status of the card. | NEW! Nov 2020 |
height | Returns the card's height as defined by the game. | |
highlight | the current highlight color as a string in #HEX color format. | |
markers | Returns a DICTIONARY of all markers which can be edited via python. | UPDATED May 2020 |
model | Returns the GUID of the card | |
name | Returns the chat-hoverable name of the card | |
orientation | Returns or Sets the current rotation of a card in 90 degree intervals. | |
owner | Returns the player OBJECT of the card's owner. | |
peekers | Returns the players who are peeking at the card. | **NEW! July 2020 ** |
position | Returns the x,y coordinates of the card. | |
properties | Returns dictionary of all the card's custom properties and their values | |
set | The name of the expansion set that the card belongs to | |
setId | The GUID of the expansion set that the card belongs to | |
size | Returns the name of the card's current custom size | |
targetedBy | Returns the player OBJECT who is targeting the card. | |
width | Returns the card's width as defined by the game. |
FUNCTION | DESCRIPTION | LAST REVISION |
---|---|---|
alternateProperty() | Returns a property value from an alternate form of the card. | |
arrow() | Draws an arrow from the card to another card. active = False will remove the arrow. | |
defaultProperty() | Returns the unmodified property value from an alternate form of the card. | NEW! Dec 2022 |
delete() | Eliminates the card from the game. | |
hasProperty() | Checks to see if a specific property is defined on the card. | NEW! May 2020 |
isInverted() | Checks to see if the card would be inverted at the given y coordinate | |
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. | |
moveToTable() | Moves a card to specified coordinates on the table. | |
offset() | a new coordinate tuple (x,y) slightly offset from the card's current position | |
peek() | Reveals the identity of the card to the local player while keeping it face-down. | |
resetProperties() | Clears all changes made to card properties, restoring their original values | |
select() | Adds the card to the current selection. | |
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 | |
target() | Targets the card, or removes target if active = False. |
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
Returns the STRING GUID of the Card object.
guid = card.model
print guid
>>> "dfa86825-5f00-414f-89ae-d5745a4efc8e"
Returns the STRING name of the card. This is useful when trying to implement the the card's given 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"
NOTE: card.name
abides by the visibility setting of the card to the player accessing it. If the card's identity is hidden to the player, then it will return Card
instead of the card's real name. You can force the access of the card's name by using the Name
custom property (card.properties["Name"] or card.Name, noting the capitalization). See card.properties for more information on this feature.
Property; the dictionary of all custom card properties of the card as defined by the game and set definitions. In this dictionary, each Key is a property name (case-insensitive); each Value is the value of the property for that card.
A card's dictionary of custom properties can be accessed regardless of its current visibility settings, allowing python the ability to read a card's property values without requiring visibility of the card. Care should be taken to ensure that your game scripts do not accidentally reveal the data of cards that may be hidden from the player.
Every card includes the Name
custom property by default, which is a cloned string of the card's name as defined in the set definition. This is made available to allow Python to view the card's given name without requiring visibility of the card.
GET
To get a specific property value from a card, use the standard python dictionary syntax i.e. card.properties["Collector Number"]
or card.properties["Type"]
.
The Card class also has a case-insensitive shorthand notation to more conveniently look up values of card properties that do not have spaces, periods, or other invalid characters in it. For example, you can look up the value of a property named "Type" by using card.Type
, card.type
, or the proper syntax card.properties["Type"]
.
properties = card.properties
print properties
>>> {'suit': 'Hearts', 'value': 'King', 'color': 'Red'}
print card.Suit
>>> 'Hearts'
SET
You can change the properties of a card, which will override the default values given by the set definition. You can use either the full properties syntax, or the shorthand notation (if applicable) to set a card's property.
card.Suit = "Diamond"
print card.Suit
>> "Diamond"
card.properties["Card Value"] = "Seven"
print card.properties["Card Value"]
>> "Seven"
FUNCTION; Removes all changes made to a card's properties, restoring them to their original values (from the set definition).
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."
PROPERTY; the Player object of the player who currently controls that card. Only the controller is able to manipulate the card manually, and Python will return a warning message if a script attempts to manipulate a card its controller does not control.
GET
controller = card.controller
notify("{} is the controller of {}.".format(owner, card))
>>> Sam is the controller of Ace of Spades.
SET
Setting control to a player mimics the functionality of the "pass control to --> " 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.controller = 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.
Returns the specific group (as either a Pile object or a 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.
Returns a boolean value representing the visibility of the card.
Face-up cards on the table are visible to all players, and will show the card's image.
Face-down cards on the table are non-visible to all players, showing the card's default back image.
Face-up cards in piles are visible to the local player.
Face-down cards in piles are non-visible to the local player.
Python can identify the name and properties of face-up cards and their names are displayed when hovered. Names and properties of face-down cards can't be identified this way.
if card.isFaceUp:
notify("{} is currently face-up.".format(card))
>>> Jack of Hearts is currently face-up.
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.
Changing face-up status of a card always updates it for all players.
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.
Returns a boolean value, true if the card is currently in a selection (yellow highlight border).
if card.isSelected:
notify("{} is currently selected.".format(card))
>>> Jack of Hearts is currently selected.
PROPERTY; the STRING Alternate Form that the card is currently in, as defined by the alternate's Type in the set XML.
The card's default Form is denoted as an empty string.
GET
alternate = card.alternate
print alternate
>>> ''
SET
card.alternate = 'alt1'
READ-ONLY PROPERTY; The List of all Alternate Forms available on a card, as defined by the alternate's Type in the set XML. The card's default Form is denoted as an empty string.
alternateList = card.alternates
print alternateList
>>> ['', 'altA', 'altB']
READ ONLY PROPERTY; the STRING identifier name assigned to the card's custom size. If the card is using the default card size, it returns "Default"
.
READ ONLY PROPERTY; the current INTEGER width value of the card as defined by the card's custom size data in game definition.
READ ONLY PROPERTY; the current INTEGER height value of the card as defined by the card's custom size data in game definition.
** NEW! ** May 2020
Argument | Type | Description |
---|---|---|
prop | STRING | The Custom Property to check. |
alt | STRING | (OPTIONAL) Checks the property from a specific alternate on the card. |
Returns a BOOLEAN if the given property exists on the card. A value of FALSE indicates that the property does not exist. This can happen when a property name does not match to any of the ones defined in the game definition xml, or if the card's XML data omitted that property.
If the optional alt
property is set, then it will check the property in that alternate only. If it is not set, then it will check properties from the active alternate of the card.
NOTE: a null property value is different from an empty one. Python will return an empty string for both null and empty property values, so hasProperty is the best way of differentiating between the two.
<card name="Insect Man" id="7cb817d1-b7e4-4a30-aec6-1eef827003a2">
<property name="Rules" value="" />
<property name="Cost" />
</card>
print card.hasProperty("Rules")
>>> True
print card.hasProperty("Cost")
>>> False
print card.hasProperty("Undefined Property Name")
>>> False
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 specified Alternate Form of that card. This uses the current property value, which can be modified through game scripting. To view the default (original) property value instead, see card.defaultProperty().
altProperty = card.alternateProperty("A", "Suit")
print altProperty
>>> "Hearts"
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 specified Alternate Form of that card. This uses the original property value defined in the set XML, and ignores any overrides added via game scripting. To view the overwritten property value instead, see card.alternateProperty().
altProperty = card.defaultProperty("A", "Suit")
print defaultProperty
>>> "Hearts"
READ-ONLY PROPERTY; the STRING name of the expansion set that the card belongs to.
GET
cardSet = card.set
print cardSet
>>> "Base Set"
READ-ONLY PROPERTY; the STRING GUID of the expansion set that the card belongs to.
GET
cardSetId = card.setId
print cardSetId
>>> "6fafefa7-ca00-4a40-9940-4a57d8d26ae1"
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.
Returns a LIST of Player objects who have peek status of the card.
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.
PROPERTY; the color of the filter drawn over the card, affecting the visible tint of the card's image.
Filter colors are formatted as STRING hex values with the convention "#aarrggbb"
, where aa
is the alpha transparency value of the filter (ff
is fully opaque, 00
is fully transparent). A color value of "None"
means there is no filter on the card.
GET
color = card.filter
return color
>>> '#4433AAFF'
SET
Sets the filter color for the card, replacing any previous color that may already be drawn. Setting a value of "None"
will remove the filter from the card.
AttackFilter = "#44ff0000" # Red
card.filter = AttackFilter
PROPERTY; the color of the highlight border drawn around the card.
Highlight colors are formatted as STRING hex values with the convention "#rrggbb"
. A color value of "None"
means there is no highlight on the card.
GET
color = card.highlight
return color
>>> '#33AAFF'
SET
Sets the highlight color for the card, replacing any previous color that may already be drawn. Setting a value of "None"
will remove the highlight from the card.
AttackColor = "#ff0000" # Red
card.highlight = AttackColor
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.
FUNCTION; Returns a tuple (x,y) of INTEGER coordinates, slightly offset with respect to the passed card's position on the table.
This method takes into account whether the table is two-sided, if the y coordinate is in the inverted area of the table, and the dimensions of the cards.
Argument | Type | Description |
---|---|---|
x | integer | OPTIONAL x coordinate to offset from |
y | integer | OPTIONAL y coordinate to offset from |
An OPTIONAL set of x and y coordinates can be passed which will replace the x and y values pulled from the card's position.
FUNCTION; Returns a BOOLEAN value if the card is inverted (upside down) on the table.
Argument | Type | Description |
---|---|---|
y | integer | OPTIONAL y-coordinate on the table |
An OPTIONAL y coordinate argument can be passed. The function will return TRUE if the card would be inverted at the specified y-coordinate.
PROPERTY; the non-negative INTEGER index value of the card in the group it is currently located in.
On the table, an index of 0 is the card furthest to the back (behind all other cards).
In expanded piles, an index of 0 is the right-most card.
In non-expanded piles, an index of 0 is the top of the pile.
GET
cardIndex = card.index
print cardIndex
>> 3
SET
Moves the card to the specified index value on the table.
NOTE: This setter only works for cards on the table. For cards in piles, use card.moveTo() instead.
card.index = 5
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 piles, use card.moveToBottom() instead.
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 piles, use card.moveTo() instead.
Returns the Marker Object for the card -- a dictionary of markers items that have been set on the card. This dictionary can be modified with Python to add or remove markers from the card.
Each Key in the Marker dictionary represents one of the markers displayed on the card. Marker keys are stored as (name, id) tuples, where STRING name is the given name for that marker, and STRING id is the unique identifier for that marker's icon image.
The corresponding Value for each Key is the INTEGER quantity of that marker. This number is displayed next to the marker's icon on the card.
Marker icons are defined in the game definition XML. These ids are used to specify the image used by the marker.
If the specified id is not defined in the game XML, then a randomly-assigned default marker color will be used for that icon. These specific colors can also be accessed by using the following id values:
"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
Example: Using Python to return marker quantities:
quantity = card.markers[("Damage Marker", "damage")]
print quantity
>>> 3
If two Keys contains the same marker id 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 python scripts. This makes it easier to reference the marker you wish to use, and prevents unnecessary duplicates of dictionary keys.
Example: Defining a marker constant
damageMarker = ("Damage Marker", "damage")
quantity = card.markers[damageMarker]
print quantity
>>> 3
Since the Marker object is a Python Dictionary, standard dictionary operations can be used to change its contents. This includes adding new key:value pairs, or applying mathematical operations to change the Value quantity.
Setting a Value to 0 will remove that marker from the card.
Example: Changing the markers on a card
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
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 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 non-expanded piles or from the right side of expanded piles.
The default index is 0 (the top of non-expanded piles and the right side of expanded piles).
# 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)
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 Table object.
card.moveToBottom(me.Deck)
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)
*UPDATED May 2020
Argument | Type | Description |
---|---|---|
selection | boolean | (OPTIONAL) select or deselect the card (default is True) |
Adds the card to current selection, or creates a selection if one is not already available. If the optional selection
parameter is False
, it will deselect the card instead.
This is the same behaviour as CTRL+click on a card or using the drag-click selection box.
BOOLEAN Property, anchors the card to the table, preventing players from manually moving it via drag-clicking. This will not prevent Python from moving the card via card.moveToTable()
.
GET
isAnchored = card.anchor
return isAnchored
>>> False
SET
card.anchor = True
return card.anchor
>>> 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.
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
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.
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.
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="OnCardsMoved" action="moveCards" />
would use the OnCardsMoved event, and passes the arguments as a variable to the action
python function:
def moveCards(args):
cards = args.cards
For events that include arguments, those arguments are passed to Python as a specialized dictionary object. If the event does not pass any arguments (the OnTableLoaded event, for example), then no arguments should be included in the python function.
EVENT NAME | DESCRIPTION | LAST REVISION |
---|---|---|
OnTableLoaded | Triggers when the table initally loads | |
OnGameStarted | Triggers when the table initially loads, and after each game restart | |
OnPlayerConnected | Triggers when a player reconnects to a game | |
OnPlayerQuit | Triggers when a player leaves a game | |
OnDeckLoaded | Triggers when a player loads a deck | |
OnCounterChanged | Triggers when a player's counter value is adjusted | |
OnPhasePassed | Triggers when the current game phase changes | |
OnPhasePaused | Triggers when a player has interrupted the passing of the current phae | |
OnTurnPassed | Triggers when a player ends their turn | |
OnTurnPaused | Triggers when a player has interrupted the ending of a turn | |
OnCardTargeted | Triggers when a player targets a card | |
OnCardArrowTargeted | Triggers when a player draws a target arrow between two cards | |
OnCardsMoved | Triggers when one or more cards are simultaneously moved from one location to another manually | |
OnScriptedCardsMoved | Triggers when a python script moves one or more cards | |
OnPlayerGlobalVariableChanged | Triggers when a player's global variable changes | |
OnGlobalVariableChanged | Triggers when a global variable changes | |
OnCardClicked | Triggers when a player clicks a card | |
OnCardDoubleClicked | Triggers when a player double-clicks a card | |
OnMarkerChanged | Triggers when a card's markers change | |
OnCardControllerChanged | Triggers when a card's controller changes |
Triggers when the table is loaded up for the first time. It will not trigger when you restart a game.
OnTableLoaded passes no arguments.
Triggers when the table is initially loaded, as well as during a game restart.
OnGameStarted passes no arguments.
Triggers when a player successfully reconnects to the game.
Parameter | Type | Description |
---|---|---|
player | Player object | The player that reconnected to 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).
Parameter | Type | Description |
---|---|---|
player | Player object | The player leaving the game. |
NOTE that since the player is no longer in the game, elements of their Player object data may be unusable or missing.
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.
Parameter | Type | Description |
---|---|---|
player | Player object | The player that loaded the deck. |
groups | list<Group object> | List of groups that cards were added to. |
Triggers when a player's counter is changed. This will detect changes made by the local player, as well as other players.
Parameter | Type | Description |
---|---|---|
player | Player object | The player who performed the counter value adjustment. |
counter | Counter object | The counter that was changed. |
value | integer | The original value of the counter, before it was changed. |
scripted | boolean |
True if the counter was changed via a Python, False if it was changed manually via the player tab spinners. |
Since the counter
argument is a Python Counter object, its properties can be accessed or changed via scripting. For example, the current value of the counter can be read using counter.value
, and the owner of the counter can be read using counter.player
.
Triggers when a player interrupts the ending of a turn by toggling the yellow PAUSE symbol on the player tabs.
Parameter | Type | Description |
---|---|---|
player | Player object | The player who toggled the pause. |
Triggers when the player passes the turn to another player.
Parameter | Type | Description |
---|---|---|
player | Player object | The player who is passing the turn. |
turn | integer | The turn number of the previous turn being passed. |
force | boolean | If stops were forced to skip via scripting |
Triggers when a player interrupts the passing of phases by toggling the pause on the phase in the phase toolbar.
Parameter | Type | Description |
---|---|---|
player | Player object | The player who set the pause on the current phase. |
Triggers when the active turn player changes the current phase.
Parameter | Type | Description |
---|---|---|
name | string | The name of the previous phase. |
id | integer | the index value of the previous phase (based on defined position in game XML.) |
force | boolean | If stops were forced to skip via scripting |
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.
Parameter | Type | Description |
---|---|---|
player | Player object | The player targeting the card |
card | Card object | The card being targeted. |
targeted | boolean | True if the card was targeted, False if it was de-targeted. |
scripted | boolean | True if the card was targeted via Python. |
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.
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. |
targeted | boolean | True if the arrow was drawn, False if it was removed. |
scripted | boolean | True if the card was targeted via Python. |
Triggers when a player's global variable gets changed via the python player.setGlobalVariable()
function.
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 |
Triggers when a global variable gets changed via the python setGlobalVariable()
function.
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 |
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.
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 |
NOTE: The 'middle' mouse button (scroll wheel) has reserved usage in OCTGN and will not trigger 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.
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 |
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.
Triggers whenever a marker's value is changed on a card. Note that this event returns a marker's name and ID as separate arguments, not a Marker object.
Parameter | Type | Description |
---|---|---|
card | Card object | The card whose markers are changed |
marker | string | the name of the marker being changed |
id | string | the unique identifier of the marker being changed |
value | integer | The old value of the marker |
scripted | string | True if the marker was changed via Python |
Triggers whenever a card's controller changes to another player.
Parameter | Type | Description |
---|---|---|
card | Card object | The card changing controllers |
player | [Player object}(#playerClass) | The new controller of the card |
value | [Player object}(#playerClass) | The old controller |
Triggers when one or more cards are simultaneously moved from one location to another manually. As cards in a selection can be moved simultaneously, many of the arguments are passed as lists in a single trigger. This will require the function to iterate through the lists to match up all values.
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 |
indexs | list<integer> | the original z-indexes of the cards |
xs | list<integer> | the old X coordinates of the cards |
ys | list<integer> | the old Y coordinates of the cards |
highlights | list<string> | the original highlight colors on the cards |
filters | list<string> | the original filter colors on the cards |
markers | list<dictionary> | the original marker dictionaries on the cards |
faceups | list<boolean> | the faceup statuses of the card |
alternates | list<string> | the original alternate state on the cards |
An example of iterating through the lists, while matching the variables to the list index of the card:
def moveCardFunction(args):
index = 0
for card in args.cards:
oldCoords = (args.xs[index], args.ys[index])
newCoords = (card.position[0], card.position[1])
group = args.toGroups[index]
highlight = args.highlights[index]
notify("{} moves {} to {}.".format(args.player, card, args.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()
Triggers when one or more cards are simultaneously moved from one location to another via a python function. See OnCardsMoved for functionality.
Event Overrides are a subset of Event Function which will interrupt the default OCTGN behavior of their respective events, and pass control over to the defined Python function. Event overrides are performed LOCALLY and do not network any messages to the other clients, although the containing python API calls might do so.
Override Events will not perform the actions they are replacing after the python function is executed. They must be performed within the function via the appropriate python API functions.
Similarly to event functions, they require 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 override 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="OverrideCardsMoved" action="MoveCards" />
would use the OverrideCardsMoved event, and passes the arguments as a variable to the action
python function:
def MoveCards(args):
cards = args.cards
For events that include arguments, those arguments are passed to Python as a specialized dictionary object. If the event does not pass any arguments (the OnTableLoaded event, for example), then no arguments should be included in the python function.
EVENT NAME | DESCRIPTION | LAST REVISION |
---|---|---|
OverrideCardsMoved | Triggers when a card is manually moved via drag-drop | |
OverrideTurnPassed | Triggers when a player clicks the "Pass Turn" button | |
OverridePhaseClicked | Triggers when a player clicks a phase button | |
OverrideGameReset | Triggers when a player resets the game via the menu option |
Triggers when one or more cards are simultaneously moved from one location to another via drag-drop. As cards in a selection can be moved simultaneously, many of the arguments are passed as lists in a single trigger. This will require the function to iterate through the lists to match up all values.
Parameter | Type | Description |
---|---|---|
cards | list<Card object> | the cards being moved |
toGroups | list<Group object> | the new groups for the cards |
indexs | list<integer> | the new z-indexes of the cards |
xs | list<integer> | the new X coordinates of the cards |
ys | list<integer> | the new Y coordinates of the cards |
faceups | list<boolean> | The new faceup state of the cards |
Triggers when the player clicks the green "Pass Turn" button on the player tabs.
Parameter | Type | Description |
---|---|---|
player | Player object | the player the turn is being passed to |
Triggers when the player clicks a phase button.
Parameter | Type | Description |
---|---|---|
name | string | the name of the phase clicked |
id | integer | the index ID value of the phase clicked |
Triggers when the player chooses the Reset Game menu option. This override has no arguments.
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 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.