- Download CardEngine from Github
- Unzip the archive inside a newly created and empty Godot project to be safe, or any Godot project if you are confident
- You should find a card_engine folder inside the addons folder
- Copy the file addons/card_engine/interface.gd.tpl to your project as interface.gd and start completing it
- Copy the file addons/card_engine/cards.json.tpl to your project as cards.json and start completing it
- Add your interface.gd in the AutoLoad project settings as a singleton named CEInterface
- Add addons/card_engine/card_engine.gd in the AutoLoad project settings as a singleton named CardEngine
- Activate the plugin in the project settings
- CardEngine is ready to be used
If this seems not clear to you, the framework comes with a demo, more info here.
Understanding the file structure
Inside addons/card_engine, you can find:
- folder demo: contains all the files related to the demo, more details here
- folder icons: contains the icons used in the Godot UI to expose CardEngine functionality
- folder widgets: contains the visual part of CardEngine
- file widget_card.gd: displays a card
- file widget_grid.gd: displays cards in a grid with configurable number of columns
- file widget_hand.gd: displays cards as they were held in a hand
- file card_container.gd: base class for all classes storing cards
- file card_data.gd: holds the data for a card
- file card_deck.gd: holds all the cards available for a game
- file card_engine.gd: singleton keeping track of the CardEngine's state
- file card_hand.gd: holds the playable cards during a game
- file card_library.gd: holds all the cards loaded from the database
- file card_pile.gd: holds all the cards not playable during a game
- file card_rng.gd: allows to have multiple self-contained random number generator running at the same time independently
- file cards.json.tpl: template for the database
- file interface.gd.tpl: template for the interface
- file plugin.cfg: plugin configuration
- file plugin_main.gd: plugin entry point
Creating a custom card
Creating a custom card is designed to be as simple as possible and to use Godot's normal workflow, here is the steps:
- Create a new and empty scene
- Add a child node of type CardWidget (under Node2D)
- Your card is ready to be customized
The whole customization concept behind is based on node name convention and is designed for flexibility. A CardEngine card is composed of 3 types of elements:
- Images: refers to the "images" database entry. They are represented by a Sprite node in the scene. The name convention is img_<picture type>
- Numerical values: refers to the "values" database entry. They are represented by a Label node in the scene. The name convention is lbl_<value id>
- Texts: refers to the "texts" database entry. They are represented by a Label or a RichTextLabel node in the scene. The name convention is lbl_<text id>
From here every other functionality of Godot can be used to customize your card to your liking. If this is not clear you can always take a look at the demo to find a practical example.
In the image above you can see how information is transferred from the JSON database to the rendered card through the scene, in the demo.
CEInterface is a singleton where CardEngine expect to find functions which allows you to integrate the framework in your game without having to hack internal code. CardEngine provides a template you can find under addons/card_engine/interface.gd.tpl which provides stubs for all required functions. Below you can find a description of those functions:
- database_path(): this function must return a string containing a path to the card database's JSON file.
- card_image(img_type, img_id): this function must return a string containing a path to an image. img_type should be used to determine the path to return based on the image type field of the database. img_id should be used to determine the path to return based on the image id field of the database.
- calculate_final_value(card_data, value): this function must return a numerical value to which potential buffs or debuffs could be applied. card_data contains is the data of the card from where the value is taken. value is the name of the value being calculated. If you just want to return the value without any change just use return card_data.values[value].
- card_instance(): this function must return an instance of the scene of your custom card (see "Creating a custom card"). If you don't need anything special leave the function as is and modify the member var _custom_card to adjust the path to the scene.
For an example of implementation, take a look at the demo.