Godot Version
4.3
Question
Right now I have done two different approaches of structuring my game data (individual cards with custom effects, starter decks, etc.), and I still don’t feel like I have reached a good structure and use everything like it’s intended. The hardest topic for me is how to build a system where card effects are functions that can be overwritten. Another thing is how I can work with this system in the editor without having to create like 200 scenes (for each card type one).
A brief overview:
Approach 1:
- One general Scene and Node class for the card
- a general card resource that holds an array of effects, an effect consists of a string defining the type of action and a value defining the specific effect value for that card
- Whenever a new card is created in the node tree I have to assign a resource to it and whenever the resource changes, all the initial values get copied into the actual node instance
- A big “Card Resolver” global that has one big resolve function matching the effect type, and executing specific lines of code
The big problem here in my opinion is that all the main logic is centralized in a big global, so whenever I add a new card or want to change an effect, I have to find the specific places in the code that handles the logic, rather than working inside a individual card script file.
Approach 2:
- One general Scene and Node class for the card
- a general card resource that holds all initial and runtime data and has all the functions needed for resolving effects (
on_draw
,on_play()
and such) - a subclass of the resource class for each type of card that then overwrites the effect functions
The big problem I have here is that Resources in general don’t seem to be build to handle instance data. Numerous times I had bugs caused by resources having a shared instance and a value change on one node caused all other nodes with that resource to change. Even if I manually call set_local_to_scene(true)
for each resource, it doesn’t seem to work.
The other problem is that it’s then super hard for me to know if the data I want to change or the function I want to call is inside the node class or the resource class, so I have code like card.card.on_play()
, because sometimes I have the Array of nodes, but sometimes I have the array of resources.
Since card games in general are quite a common genre, I’m guessing there must be some “best practices” for those type of games in Godot. Can you guys give me an idea of how you would approach such a game or maybe do you know some good tutorials on that matter?
The second approach I got from this “Slay the spire” copy tutorial (https://www.youtube.com/playlist?list=PL6SABXRSlpH8CD71L7zye311cp9R4JazJ), but again, having everything inside the actual resource seems wrong to me.