Logo

Braindead.bzh

Game Dev Hobbyist

A blog about my game dev hobby and various stuff.

Menu
Logo

Braindead.bzh

Game Dev Hobbyist

A blog about my game dev hobby and various stuff.

Stores

Overview (AbstractStore class)

res://addons/cardengine/store/abstract_store.gd (source)

Stores help you managed the card in-memory. Contrary to a database, a store can have multiple copy of the same card and modify them on the fly, thanks to CardInstance (learn more here). In addition, stores keep meta-information on cards.

Typically, stores is what you will be using in your scripts to manipulate cards to create your gameplay. CardEngine offers specialized stores like deck, pile and hand, for basic gameplay features which are common to most card games.

Signals

As store are usually used in coordination with visual objects to display their state, either be a Container or other Node, it is a good idea to use signals to keep the visual updated (Containers do it automatically). You have two choices on how you want to manage this, you can used the specialized signals card_added, cards_added, card_removed, cards_removed, filtered or sorted. Or you can use the generic changed signal which is always emitted for every change made to the store.

Properties

Stores have the following properties:

  • save_id: String contains the ID of the store as saved on disk (read-only)
  • save_name: String contains the name of the store as saved on disk (read-only)

Adding

You can add cards to a store using either the "add" functions or the "populate" functions:

  • Use "add" functions if you already have CardInstance objects on hand, you can use add_card(CardInstance) or add_cards(CardInstance[]). Tip: you can use CardInstance.duplicate() if you want modification to the added instance to not affect the original instance
  • Use "populate" functions to create new CardInstance objects from database entries, you can use populate(CardDatabase, ID[]) or populate_all(CardDatabase), the first creates an instance for each ID of the list, the second creates an instance for each database entry

Utility

Stores offer some basic utility functions:

  • count() returns the number of cards in the store (affected by the filter)
  • cards_count() returns a Dictionary with the number of cards per ID, IDs being the keys and numbers the values
  • count_for(ID) returns the number of card with the given ID
  • is_empty() returns true if there is no card in the store (affected by the filter)
  • has_card(reference) returns true if the store contains an instance with the given reference (affected by the filter)

Saving and loading

See this page

 

Retrieving

You can retrieve cards using the following functions:

  • cards() returns all the cards as an array of CardInstance (affected by the filter)
  • get_card(int) returns the card at the given index or null if the index is out of bound (affected by the filter)
  • get_first() returns the first card in the store or null if the store is empty (affected by the filter)
  • get_last() returns the last card in the store or null if the store is empty (affected by the filter)

Finding

You can find cards using the following funtions:

  • find(ID) returns an array of CardInstance with the given ID or an empty array if not found
  • find_first(ID) returns the first CardInstance with the given ID or null if not found
  • find_last(ID) returns the last CardInstance with the given ID or null if not found

Removing

When it comes to removing cards you can use the following functions:

  • clear() removes all the cards and the filter
  • remove_card(reference) removes the card with the given reference
  • remove_first() removes the first card
  • remove_first(ID) removes the first card with the given ID
  • remove_last() removes the last card
  • remove_last(ID) removes the last card with the given ID
  • keep(int) only keeps the first given N cards

Transferring

You can transfer cards between stores either by moving them or by copying them.

Moving

Moving cards means that the cards will be removed from the store once transferred:

  • move_cards(AbstractStore) moves all the cards from one store to the other
  • move_card(reference, AbstractStore) moves a card instance with the given reference from one store to the other
  • move_random_card(AbstractStore) moves a random card from one store to the other

Copying

Copying cards means that the cards transferred to the other store will be different instances:

  • copy_cards(AbstractStore) copies all the cards from one store to the other
  • copy_card(reference, AbstractStore) copies the card instance with the given reference from one store to the other
  • copy_random_card(reference, AbstractStore) copies a random card from one store to the other

Filtering

As seen above some functions are affected by a filter. You can set a filter on your store, with apply_filter(Query), so only some cards remain accessible without removing them from the store. Look at Query below to learn how to write a filter.

Sorting

Store can be sorted using one or more criteria at once. You can sort your store by calling sort(Dictionary). You build your sort criteria as a GDScript Dictionary following this rules:

  • For categories the entry key is of the form "category:<meta-category>" and the value is an array of categories in the order you want them to appear, example: sorting["category:rarity"] = ["common", "uncommon", "rare", "mythic_rare"]
  • For values the entry key is of the form value:<value ID> and the value is boolean where true is for ascending order and false is descending order, example: sorting["value:mana"] = true
  • For texts the entry key is of the form text:<value ID> and the value is boolean where true is for ascending order and false is descending order, example: sorting["text:name"] = true

You can combine as many criteria as needed, they will be treated in the order you add them.

Meta-information

Stores also keep data about what kind of data its cards have:

  • About categories: with categories() you get all the different meta-categories and how many cards have it, and per meta-categories you get all the categories and how many cards have this category as a Dictionary, with get_meta_category(String) you get the same information but just for one meta-categories
  • About values: with values() you get all the different value ID as an Array
  • About texts: with texts() you get all the different text ID as an Array

Example:

# Print the number of cards with a rarity meta-category
var categs = store.categories()
print("Count %d" % categs["rarity"]["count"])
# Or
var rarity = store.get_meta_category("rarity")
print("Count %d" % rarity["count"])


# Print all the different rarity categories
var rarity = store.get_meta_category("rarity")
for categ in rarity["values"]:
  print("Category %s" % categ)


# Print the number of cards with a common rarity
var rarity = store.get_meta_category("rarity")
print("Count %d" % rarity["values"]["common"])


# Print all the different value IDs
var values = store.values()
for value in values:
  print("Value %s" % value)


# Print all the different text IDs
var texts = store.texts()
for text in texts:
  print("Text %s" % text)

Card Deck (CardDeck class)

res://addons/cardengine/store/card_deck.gd (source) (API not finished)

A deck is usually a list of cards which the player is building before or during a game by selecting cards from a database.

Card Pile (CardPile class)

res://addons/cardengine/store/card_pile.gd (source) (API not finished)

A pile is usually a list of cards from which the player can draw cards. Piles also have the ability to be shuffled, that will change the order the cards are drawn.

  • draw() removes the last cards from the store and returns it (emit the card_drawn signal)
  • shuffle() randomizes the order of the cards in the store (emit the shuffled signal)

Card Hand (CardHand class)

res://addons/cardengine/store/card_hand.gd (source) (API not finished)

A hand is usually a list of cards from which the player choose the card to play.

  • play_card(reference, AbstractStore) removes the card instance with the given reference and move it to the other store if present (emit card_played signal)

Query (Query class)

res://addons/cardengine/database/query.gd (source)

Queries have 2 uses, selecting cards from a database or filtering a store, but in both cases they are built the same way. There is 3 types of statements:

  • From statements to select the cards by categories
  • Where statements to select the cards by values
  • Contains statements to select the cards by texts

You build your query around arrays of comma separated statements, such that each element of the array will be interpreted as logical or statement, and each comma separated as logical and statement.

Building from statements

A from statement is built using the following structure <meta-category>:<search string>. The search string can contain * and ? as wildcards for respectively a string and a single character.

Building where statements

A where statement is build using the following structure <value ID> <comparison operator> <number>. There is 5 comparison operators supported: =, <=, <, >= and >. The number is any integer, positive or negative.

Building contains statements

A contains statement is build using the following structure <text ID>:<search string>. The search string is case insensitive.

Examples

# Cards must be of "class" "creature" and the "creature_type" must start with "human_", or the "class" must be "sorcery"
var q = Query.new()
q.from(["class:creature,creature_type:human_*", "class:sorcery"])


# Cards must have a "mana" value superior or equal to 2 and strictly inferior to 5
var q = Query.new()
q.where(["mana >= 2,mana < 5"])


# Cards "name" must contain "time" or "master"
var q = Query.new()
q.contains(["name:time", "name:master"])


# You can combine all statements in one line
var q = Query.new()
q.from(["class:creature,creature_type:human_*", "class:sorcery"]).where(["mana >= 2,mana < 5"]).contains(["name:time", "name:master"])


# You can use the query to populate a store from a database
var db = CardEngine.db().get_database("main")
var q = Query.new()
var store = CardPile.new()

var result = q.from(["class:creature,creature_type:human_*", "class:sorcery"]).where(["mana >= 2,mana < 5"]).contains(["name:time", "name:master"]).execute(db)

store.populate(db, result)


# You can use the query to filter a store
var db = CardEngine.db().get_database("main")
var q = Query.new()
var store = CardPile.new()

store.populate_all(db)

q.from(["class:creature,creature_type:human_*", "class:sorcery"]).where(["mana >= 2,mana < 5"]).contains(["name:time", "name:master"])

store.apply_filter(q)