Giter VIP home page Giter VIP logo

db0 / godot-card-game-framework Goto Github PK

View Code? Open in Web Editor NEW
849.0 24.0 89.0 8.88 MB

A framework which comes with prepared scenes and classes to kickstart your card game, as well as a powerful scripting engine to use to provide full rules enforcement.

Home Page: http://dbzer0.com/projects/godot-card-game-framework/

License: GNU Affero General Public License v3.0

GDScript 99.71% GAP 0.03% HTML 0.26%
card-game godot framework godot-engine gamedev

godot-card-game-framework's Introduction

Godot Card Game Framework 2.2

GUT

Godot Card Game Framework preview image

This framework is meant to provide well designed, statically typed, and fully commented classes and scenes which you can plug into any potential card game to handle typical behaviour expected from cards in a game in a polished manner.

Pull requests are more than welcome ;)

Provided features

  • Complete card text and rules enforcement capacity, via provided Scripting Engine! (see scripting engine features, below)
  • Tween & GDScript-based animations that look good for card movements.
  • Customizable card highlights
  • Supports Rich Text for card text, including embedded images.
  • Choice between Oval or Straight hand shape
  • Automatic focus-in on cards when moused over in-hand.
  • Automatic re-arranging of hand as cards are added or removed.
  • Drag & Drop of cards on table and between containers
  • Supports having multiple hands and piles.
  • Piles of cards represent their size visually.
  • Larger image of card when moving mouse cursor over it
  • Pop-up buttons for predefined functions on cards and card containers
  • Option to look inside the piles and choose cards to move out
  • Cards can rotate on the table
  • Cards can attach to other cards and move together as a group.
  • Cards can target other cards with a draggable arrow
  • Can flip cards face-down and view them while in that state
  • Can add tokens on cards. Tokens expand in the own drawer for more info.
  • Ability to define cards in standard dictionaries
  • Ability to split card definitions into sets
  • Automatically resizing text inside cards to fit the card size.
  • Supports resizing the window, in all stretch modes (including disabled stretch)
  • Can select layout of your CardContainers from a simple drop-down menu.
  • Automatic and manual Grid-based, or Free-form placement on the board, or a combination of both, on a per-card-type basis.
  • Functions from saving/loading settings from disk.
  • Caching mechanisms to reduce loading and instancing times.
  • Collecting game statistics
  • Easy customization via Themes. Dark Theme used in Demo, provided by Mounir Tohami
  • A functional and customizable Card Library.

Godot Card Game Framework card library preview image

  • A functional and customizable Deck Builder.

Godot Card Game Framework deck builder preview image

Scripting Engine Features

  • Can define card scripts in plain text, using dictionaries.
  • Can set cards to trigger off of any board manipulation.
  • Can filter the triggers based on card properties, or a special subset.
  • Can define optional abilities.
  • Can define multiple-choice abilities.
  • Can calculate effect intensity based on state of the board during runtime.
  • Can request simple inputs from the player during execution.
  • Tag-marking scripts which can be filtered by scripts triggering off of them.
  • Can store results from one script to use in another.
  • Can be plugged into by any object, not just cards.

All of the above while being very easily extensible to your own game's special requirements through simple dictionaries.

Easy Customization

The classes provide some easy customization options, such as the card size, how the card move, where they appear etc.

Check the Behaviour Constants of CFConst.gd for detailed information on what each does.

For more fine-tuned customization than that, you'll need to modify the code manually

Easy to Upgrade

This Framework has been designed with the idea that it can easily be upgraded to receive new features. Look at the Upgrade section within the Install guide for more info.

Usage

Most of the card manipulation functionalities work without any extra work, as long as the relevant scenes have been setup correctly (see Installation). For example, the code which handles moving cards around or focusing on them etc should work out of the box.

However some effects require some trigger, such as targeting of cards etc. The method calls to perform these are available to use and some demo functions have been provided to understand how it works, but it is expected that each game will provide their own logic in their own scripts to call the relevant methods.

You can find documentation about all the provided methods in the wiki

Demonstrations

Card Manipulation buttons

Hover over the card to reveal its manipulation buttons.

Targeting

Right-click and hold on a a card to begin dragging a targeting arrow. Release right-click on top of a card to target it.

Attachments

Click on the "Enable Attachment" toggle to make all cards act as attachments and therefore allow them to attach to others.

Card Rotation

Click on either the 'T' or '@' buttons. Click again the same button to revert to 0 degrees.

Tokens/Counters

Click on the 'O' Button, to start adding one of four random tokens to the card.

Click on the +/- buttons next to each Token to add/remove that token specifically

Card Flip Face-Up/Face-Down

Click on the 'F' button to exchange between these two states

Grid-placement

The demonstration board has been setup with two different grid placements you can use. Try drag & dropping a card to either "PlacementGridDemo" or "This Grid has a modified label".

Card Scripts

The first four cards you will draw from your deck each have different prepared automations. Their text explains these effects.

You can double click any of them in the hand or board to see their scripts in action.

Some of them have also effects that trigger off of other effects.

Mind that their script effect change, depending on whether they're in the hand or board, so make sure you move them to the board first if you want to see those scripts in action.

Installation

Please see the Install Guide

Scripting Engine

One of the most powerful features of this framework, is the possibility to easily script each individual card's abilities from start to finish, so that a player only needs to double-click on a card and your code will handle the proper execution. This allows games to very easily create complete rules enforcement of all card abilities, from the simplest to the most tricky ones.

Please see the [ScriptingEngine](SCRIPTING_ENGINE] and ScriptDefinitions documentation for more details.

The game comes with some sample scripted cards which can be found under res://src/custom/cards/sets.

Getting help, talking dev, or general chat

You can join us on Matrix (https://matrix.to/#/!UdtRNwYEDJcLdQigxS:matrix.org) or Discord (https://discord.gg/AjZMFY7jD4)

Contributing

Please see the Contribution Guide

Support

If you wish to support the development of the Card Game Framework, consider becoming a patron via liberapay

Credits

Some initial ideas were taken from this excellent Godot Card Game Tutorial video series. This framework uses some of the concepts but also attempts to create better quality code in the process.

License

This software is licensed undel AGPL3. However an addendum has been added to allow distribution via Steam and integration with Steamworks SDK.

Games Made with CGF

godot-card-game-framework's People

Contributors

croconut avatar db0 avatar easternmouse avatar fengjiongmax avatar markp3rry avatar richhl avatar stevosaurus avatar trillyc avatar vmjcv avatar zombiecraig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

godot-card-game-framework's Issues

Implement all tasks needed in the ScriptingEngine

Tasks to add to the ScriptingEngine:

  • Rotate Card
  • Flip Card
  • Move Card to CardContainer
  • Move Card to Board
  • Spawn Card
  • Move Card from CardContainer to Container
  • Move Card from CardContainer to Board
  • Shuffle CardContainer
  • Mod Card Tokens
  • Attach card to other card
  • Tutor a card by name
  • Tutor a card by properties
  • Request int input for player
  • Modify card property/label

Highlight gets stuck if mouse enters card on table directly on top of a button

On very rare occasions, the player's mouse will move at a speed an angle where it will enter a card on the board exactly on top of one of its ManipulationButtons. If the mouse exits at the same speed without passing over a non-button part of the card, the on_button_mouse_exited() will finish its yield after on_Card_mouse_exited() which will thus never clear the card's focus until a card is focused again.

Very rare situation, with very easy solution, which is caused by the workarounds I implemented against godotengine/godot#16854.

For a permanent fix, I do not see an easy solution. 2 options

  1. Moving the buttons further in the card rect (which would look ugly) so that the mouse always has a chance to move over the $Control rect before exiting.
  2. Checking if the mouse cursor is still inside the card after exiting the button. This would take quite a calculations to achieve, especially with the viewport shenanigans in relation to mouse position.

Given the low impact, I'm leaving as is. If it becomes too bothersome, I'll revisit.

Create a way for a card to target another card

Some abilities require the player specifying targets. When those activate, it would be good to have some arrow being dragged by the mouse to select the target. Alternatively make the mouse a targeting reticle on first click, to signify you're selecting targets.

Create discard function and area

An area where cards will go when discarded by dragging them there

Add a discard fuction which can trigger on a 'del' keypress while a card is focused

Implement all signals needed in the ScriptingEngine

Some basic or typical triggers for effects in card games.

  • card_rotated
  • card_flipped
  • card_viewed
  • card_moved_to_board
  • card_moved_to_hand
  • card_moved_to_pile
  • card_token_modified
  • card_attached
  • card_unattached
  • card_targeted

Allow ScriptingEngine to handle cost effects

Currently all the scripts in the ScriptingEngine are only final effects. We do not have the concept of costs. I need to implement a deinition so that the ScriptingEngine stops executing scripts in the pipeline, if one of more scripts marked as cost cannot be implemented.

This would require us implementing a way to "dry-run" effects to see if they would be able to execute.

Allow cards to change orientation once they're placed on the table

Once a card object has been moved to the play area, the player should be able to turn it 90 degrees sideways though some function.

By default that function should be assigned to double-clicking the card.

Provide code in the library to change the orientation further (e.g. 180 degrees) or add more orientation options with other shortcuts/calls

Allow ScriptingEngine to handle signal-based automation

Currently the scripts trigger on player activation (double-click to be exact), but a lot of card effects are also reactive. E.g. "When this card is drawn, discard a card", or "When a card is destroyed, draw a card".

I have to figure out a way to trigger card scripts based on signals defined in their code. This needs to work in parallel with the state-based limit, as a script might require a signal and a specific state.

One way to do this, is to make various common actions trigger signals. I can think of a few generic ones

  • Card Drawn(source pile)
  • Card Discarded(source container)
  • Card Rotated
  • Card Flipped

etc.

Those signals would be caught by a central point (the board? cfc? some new signal coordinator node? not sure yet) and then will call some sort of parser, to see if there's any other cards who are listening for those signals.

I think I should go through a central coordinator node as I don't think it makes sense to connect each card to each other card just in case.

Implement Token-based scripting

In a lot of games, tokens themselves might add extra effects or execute things depending on a trigger

I need to have a way where a token can include scripts that will initiate the ScriptingEngine

slay the spire?

I like this game very much. Is this a game framework similar to the slay the spire?

Create a way to link two cards together visually

This wouldn't affect the cards mechanically like #16, but rather it would simply serve as some sort of visual representation for the player.

This link would be stored in the card object however and available to be exploited by developers if needed.

Dragging cards shouldn't warp the mouse

Currently I'm using a warp_mouse() workaround to avoid the card teleporting when first grabbing onto it to move around, I warp the mouse to the card location (which effectively moves it to the card's local Vector2(0,0)).

This has two issues:

  • It sometimes confuses the player who finds their mouse cursor warped.
  • You're still getting a cross-cursor on the top-left of the card, which I often confuse as a targeting reticle. However the truth is that cards find the container to drop into based on their Area2D colisions. So if you try to target the deck using the top right part of the card (where the cross mouse cursor will be while dragging), the card ends up inside the hand, because its Area2D collides with both deck and hand. and hand has a lower node index than the deck and so the automation prioritizes it for a move_to() target.

I think the best solution would be if the mouse cursor was hidden, then it's intuitively more natural to understand where you want to drop the card. I did try with MOUSE_MODE_HIDDEN, but I could not combine it with MOUSE_MODE_CONFINED which is way more imporant (as unclicking the mouse outside the game can break dragging and automation which relies in mouse inputs).

Maybe a solution like suggested here: https://godotengine.org/qa/60675/make-cursor-hidden-in-mouse_mode_confined could work, to temporary replace the mouse cursor with a transparent sprite?

If the mouse cannot be made invisible, another solution would be to keep the dragged card always on the same relative spot on the mouse cursor as in the moment it was picked up. This would mean offsetting the card global placement when dragged to match the local placement of the cursor inside the card. You might still get some jitter/teleportation when picking up a card from a position next to the board edge, (especiually in the hand), but it shouldn't be too bad.

cards get stuck

When you grab a card from the hand, if you move to a screen edge the card gets stuck to the mouse and you're unable to release the card into the board. When this happens, sometimes you can pick up a second card and the second card will release normally on the board.

Store the set name in the card properties somehow

Because many games allow cards with the same name in different sets, using the set should be a way to differentiate.

Technically I could go full geek and just make each dictionary key a UUID or something, but I've used OCTGN which does this method, and it's a PITA to work with.

Make Piles have higher drop priority than Hands

To improve on #53 I should probably figure out a workaround to make Pile have higher priority for card drops, than Hand, when a card's Area2D collides with both, as it's the natural way people expect (to target the hand, they usually move the card to the middle position).

I cannot move the Hand node higher in the node hierarchy, as that would cause the card-draw animation to show the card be picked from the bottom of the pile. This is because I first change parents, then execute the animations, so the relative z_index of the two CardContainer nodes matters.

I am thinking just have the CardDrop logic prioritize cfc.piles over cfc.hands

Create a sample deck area

Instead of a draw card button, the user should need to simply click on the deck button.

Optimally, it should have some sort of algorithmic graphic where it grows "thicker" the more card there are in it

Create a way to specify the board programmaticaly

Currently the existing board has been defined using the Godot visual editor. These of course means that positions and dimentions are hardcoded and don't work well without stretching when changing resolution.

I would like a way for each game to specify the board setup using gdscript.

I'm envisioning something like a game.gd. There the player would specify for each CardContainer its anchor and its size relative to the viewport. They would also specify card_size there as well

Add framework to add hoverable buttons on a card

An idea I got from reddit. A button which appears only when the mouse hovers over that area of a card would be convenient way to do basic things like discard the card. It would also serve as a template to add move varied interactions with cards based on buttons

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.