Tool for defining and spawning custom cards and decks purely from scripting. Create decks or single cards for your mod from code, maintain or update them by simply changing a few lines instead of manually creating/moving/splitting decks. Change any card/deck images in the script instead of re-importing all of it again.
-- Use and IDE plugin supporting require or paste decker.ttslua code there
local Decker = require('Decker.Decker')
-- open in browser to see what these links depict
local cardFaces = 'https://i.imgur.com/wiyVst7.png'
local cardBack = 'https://i.imgur.com/KQtQGE7.png'
-- define a new asset from face/back links, add width/height (since these default to 1x1)
local cardAsset = Decker.Asset(cardFaces, cardBack, {width = 2, height = 2})
-- define cards on the asset, skipping three because we can (would be row 2, column 1)
local cardOne = Decker.Card(cardAsset, 1, 1) -- (asset, row, column)
local cardTwo = Decker.Card(cardAsset, 1, 2)
local cardFour = Decker.Card(cardAsset, 2, 2)
-- define a deck of cardFour, two cardOne's and two cardTwo's
local myDeck = Decker.Deck({cardFour, cardOne, cardOne, cardTwo, cardTwo})
-- so far, all of the above are just scripting definitions, nothing is spawned
-- e.g. if I decided game is balanced better with just one cardTwo in the deck, I can just remove it
-- from above code and leave rest of the code unchanged (still using myDeck below)
-- same goes for changing art on cards (just replace links from Decker.Asset definitions)
-- let's do some testing when any chat message is sent
function onChat()
-- spawn two of our decks (e.g. for each player), one flipped
myDeck:spawn({position = {-4, 3, 0}})
myDeck:spawn({position = {4, 3, 0}, rotation = {0, 0, 180}})
-- spawn a single card
cardFour:spawn({position = {0, 3, 6}})
-- see below for a bit more functionality Decker offers
advancedExample()
end
function advancedExample()
-- all :spawn methods return a regular object - proceed like with anything
local someDeck = myDeck:spawn({position = {0, 3, -6}})
someDeck.highlightOn({0, 0, 1}, 10)
someDeck.setName('this is some deck')
-- for convenience, stuff like name/description/xmlui can be assigned to stuff before spawning
-- to avoid calls like setName above - see spawnParams in full reference section of docs
-- we can use DeckerDeck methods to modify it
-- let's remove both cardOne's from it (index 2 and 3)
myDeck:removeMany(2, 3)
-- now let's swap first and last card so it's {cardTwo, cardTwo, cardFour} and spawn it
-- negative index (anywhere in methods) means counting from the end down
myDeck:swap(1, -1):spawn({position = {0, 3, 0}})
-- we can swap assets on decks after creation
-- this new asset switches card fromnts and backs
local weirdAsset = Decker.Asset(cardBack, cardFaces, {width = 2, height = 2})
-- to leave myDeck as-is, we'll be working on a copy
-- you can have many replacements at once, [oldAsset] = newAsset
myDeck:copy():switchAssets({ [cardAsset] = weirdAsset }):spawn({position = {12, 3, 0}})
end
function onLoad()
broadcastToAll('Post any chat message to execute example code', {1, 1, 1})
end
Note: if an arg name has (something) next to it, it is the default value if not provided. Decker does not do extensive assertions on passed arguments and will probably cause weird runtime errors when misused.
Decker.Asset(string faceLink, string backLink, table params)
faceLink
, backLink
: strings with links to images like you would use for a custom deckparam
(optional) table of:width (1)
: integer, how many columns of cards on image(s)height (1)
: integer, how many rows of cards on image(s)uniqueBack (false)
: bool, if backLink
is also a sheet and not a single imagehiddenBack (false)
: bool, should backs be hidden in handsasset
Decker.Card(asset cardAsset, int rowNum, int colNum, table commonParams)
DeckerCard
object that defines a single cardcardAsset
: asset created using Decker.Asset
to be used fo this cardrowNum (1)
, colNum (1)
: integers which row/column from the asset this card iscommonParams
(optional) table of object properties, see Common Params Tablesideways (false)
: bool, if the card be oriented sidewaysDeckerCard
objectDecker.Deck(table cards, table commonParams)
DeckerDeck
object that defines a deckcards
: table of DeckerCard
this deck consists, also see Indexing and ordercommonParams
(optional) table of object properties, see Common Params TableDeckerDeck
objectDecker.AssetDeck(asset deckAsset, int cardsNum, table commonParams)
DeckerDeck
object that defines a deck from single asset (skipping Decker.Card)deckAsset
: an asset used for cards in this deckcardsNum (assetSize)
: number of cards in this deck (goes sequentially over cards in asset, row by row)commonParams
(optional) table of object properties, see Common Params Table sectionDeckerDeck
objectDecker.RescanExistingDeckIDs()
true
if a potentially clashing deck was found, false
otherwiseDeckerCard:spawn(table spawnParams) and DeckerDeck:spawn(table spawnParams)
spawnParams
: table of parameters
for spawnObjectJSON or spawnObjectDataDeckerCard:setCommon(table commonParams) and DeckerDeck:setCommon(table commonParams)
commonParams
: table of object properties, see Common Params Table sectionself
for chaining methodsDeckerCard:setAsset(asset newAsset)
newAsset
: new asset to be set on the cardself
for chaining methodsDeckerCard:getAsset()
asset
associated with this cardDeckerDeck:insert(DeckerCard card, int index)
DeckerCard
into a DeckerDeck
card
: DeckerCard to be inserted in the deckindex (lastInDeck)
: index at which the card is inserted (shifting others up), also see Indexing and orderself
for chaining methodsDeckerDeck:remove(int index)
DeckerDeck
index (lastInDeck)
: index at which a card is removed (shifting others down), also see Indexing and orderself
for chaining methodsDeckerDeck:removeMany(int index1, int index2, ...)
DeckerDeck
so you don't have to keep shifting down indices in mindindexN
: indices at which cards are removed (shifting others down), also see Indexing and orderself
for chaining methodsDeckerDeck:swap(int indexOne, int indexTwo)
DeckerDeck
indexOne
, indexTwo
: indices at which cards positions are swapped with each other, Indexing and orderself
for chaining methodsDeckerDeck:reverse()
DeckerDeck
card order (basically swapping cards end-to-end)self
for chaining methodsDeckerDeck:sort(sortFunction)
DeckerDeck
based on a provided comparison functionlog(soemCard.getData())
self
for chaining methods DeckerDeck:getAssets()
asset
s on cards in this deckDeckerDeck:switchAssets(table assetMap)
assetMap
: table keyed with assets-to-be-replaced with values being assets-to-replaceself
for chaining methodsDeckerDeck:copy()
self
(same contents but can be modified separately)DeckerDeck:cardAt(int index)
DeckerCard
from a DeckerDeck
at particular positionindex
: index of the card to getDeckerCard
objectWhen creating decks using Decker.Deck
, cards go in order of
top-to-bottom when looking on a face-down deck (placed so a card back is visible on top of it).
In Decker.Deck({card1, card2, card3})
, card1
will be one with exposed back and card3
will be one with exposed face.
Stuff called "index" in Decker functions means a positive number counting from top of the deck (back-visible card is index 1), negative numbers means counting from the other end (front-visible card is index -1).
Both Decker.Deck
and Decker.Card
take a commonParams
table as last parameter. It can be used to set some
common object properties like name, description, lock status etc so you don't have to do it every time you spawn the thing.
Setting any key outside of the range listed below (plus sideways
for Decker.Card
) will set key/value directly on the resulting object JSON. You can use this to set JSON fields not handled by Decker directly per table below.
commonParams
table can consists of keys:
name
: string, name of the object, default emptydesc
: string, description of the object, default emptyvalue
: string, value of the object, default 0tags
: table of strings, tags of the object, default empty tablelocked
: bool, if the object is locked when spawned, default falsescript
: string, lua script on the object, default emptyxmlui
: string, XML UI code of the object, default emptytooltip
: bool, if the tooltip on object is shown, default truescriptState
: string, saved state of the script, default emptyguid
: string, GUID this object will try to have, default 'deadbf'hands
: bool, if the object should go into player hands, default true for cards, default false for decks
Keep in mind guid
field will be ignored (TTS does this, not me) if it's invalid or if an object of this GUID already exists.