#Trouble with card resources

173 messages · Page 1 of 1 (latest)

neon bronze
#

Details to follow

grand idol
#

Thanks

#

CardSpawner.gd

extends Node

var card = preload("res://card.tscn")
var cards_per_deck := 52
var deck_of_cards : Array = []

func _ready() -> void:
    for i in cards_per_deck:
        var card_instance = card.instantiate() # instance each card
        card_instance.card_stats.number += 1 # starts at 1 and increments
        deck_of_cards.push_back(card_instance) # pushes card into array
        add_child(card_instance)
        
        if (card_instance.card_stats.number == 14): # every 14 cards
            card_instance.card_stats.number = 1 # starts a new set of cards at '2' again
            card_instance.card_stats.suit_number += 1 # starts a new suit
        
        if (deck_of_cards.size() == 52): # if array is filled with cards
                for x in cards_per_deck: # for every card
                    print(deck_of_cards[x].name_label.text + " of " + deck_of_cards[x].suit_label.text) # print array info

Card.gd

extends Control

@export var card_stats : Resource

@onready var name_label = $NameLabel
@onready var suit_label = $SuitLabel

func _ready() -> void:
    set_card_labels()
    set_card_suits()

func set_card_labels() -> void:
    if (card_stats.number == 11):
        name_label.text = "Jack"
    elif (card_stats.number == 12):
        name_label.text = "Queen"
    elif (card_stats.number == 13):
        name_label.text = "King"
    elif (card_stats.number == 14):
        name_label.text = "Ace"
    else:
        name_label.text = str(card_stats.number)


func set_card_suits() -> void:
    if (card_stats.suit_number == 1):
        suit_label.text = "Hearts"
    elif (card_stats.suit_number == 2):
        suit_label.text = "Clubs"
    elif (card_stats.suit_number == 3):
        suit_label.text = "Spades"
    else:
        suit_label.text = "Diamonds"

card_stats resource

extends Resource
class_name Card_Stats

@export var number := 1
@export var suit_number := 1
#

Had some extra copy and paste int here

subtle ivy
#
func _ready() -> void:
    
    var number = 2
    var suit = 1
    
    for i in cards_per_deck:
        var card_instance = card.instantiate() # instance each card
        card_instance.card_stats = card_instance.card_stats.duplicate()
        card_instance.card_stats.number = number # starts at 1 and increments
        card_instance.card_stats.suit_number = suit
        deck_of_cards.push_back(card_instance) # pushes card into array
        add_child(card_instance)

        if number == 14:
            suit += 1
            number = 2
        else:
            number += 1
#

@grand idol lmk if that works

#

oh wait

#

there

grand idol
#

Nem, I want to be honest here, Not really looking for a solution to the project. Moreso wondering whats goin on with my current one. Why it looks like it is working, and why childing to GridContainer changes things.

I seem to have some big gaps in understanding and am trying to fill those in

subtle ivy
#

sure

#

well it really should make 0 difference what the instanced nodes parent is

#

what did you find when u check the remote scene tree at runtime?

#

what were the values of the cards card_stats resource?

grand idol
#

both values on resource were showing as 1 on each card instance

#

but all text values were correct, both number and suit

#

Which I don't get

#

I can see how, if the resource is shared, my line 17 reset the card_stats.number back to 1 at the last for-loop statement. but the card_stat.suit_number never gets reset in code, so it makes me believe they never actually change.

subtle ivy
#

ok so I imagine what was happening was that after each add_child call

#

that nodes _ready function ran

#

and at that time, the resource stats were incremented

#

so your labels were being set with the correct values

grand idol
#

I uploaded the project to github if it helps

subtle ivy
#

ya sure you can link it but I dont think it's necessary

grand idol
subtle ivy
#

you were running each cards _ready function with a shared resource that you were incrementing

#

thats the gist of why it seemed to work

grand idol
#

How does suit_number end up as 1 tho?

#

on the resource. If it incremented correctly, how did it reset

subtle ivy
#

thats the only mystery

#

are u setting that resource value somewhere else

grand idol
#

What about the GridContainer mystery lol.

Only in the resource itself.

#

And incrementing in that for loop Like Ive shown

subtle ivy
#

lol there is no GridContainer mystery

dry bough
#

What's your issue? Happy to take a quick look at the project

grand idol
subtle ivy
#

what changed when you switched to GridContainer as the parent

grand idol
# dry bough What's your issue? Happy to take a quick look at the project

The gist is this:

I have 4 Nodes:

Main
CardSpawner
GridContainer

and a seperate Card scene not in the scene tree.

I have a CardSpawner script
and a Card script, The Card script uses a simple resource for 2 values. The number of the card, and the suit number of the card

I am trying to create a full deck of 52 cards. It seems to be working when adding Card instances as children to CardSpawner. It breaks when making GridContainer the Parent

grand idol
#

The original error that spurred this whole learning adventure.

subtle ivy
#

so you werent getting that error when adding to the spawner?

grand idol
#

Correct, yea, it all seemingly works with 'labels' and the such

#

When adding directly to the CardSpawner

#

Even though the resource values both show as 1

dry bough
#

Works for me

grand idol
subtle ivy
#

it might just be because your spawner was a node

#

and not a canvas item

#

change the node to a node2d

#

and see if you get the error

dry bough
subtle ivy
#

lol

grand idol
subtle ivy
#

I think its a matter of update order for a non canvas item node

#

so I think you'll get the text error on any node that is a canvas item

#

like node2D or control or anything that draws to the screen

#

it would likely give you the same error on any control node or Node2D

dry bough
subtle ivy
#

you probably ran the script from the spawner still

#

i imagine he moved the instancing logic into the gridcontainer script?

grand idol
#

My print is still not working, even after adding the children to GridContainer

dry bough
#

Min ei

subtle ivy
#

ok lemme download this project lol

dry bough
#

Oops mine is haha

grand idol
#

Are you switching it around somehow or changing node types

dry bough
#

I made grid container child

#

@onready var grid_container: GridContainer = %GridContainer

grand idol
#

Right, my original OG question was why doesn't it work adding them to GridContainer when it is a sibling to CardSpawner

dry bough
#

How are you getting reference to sibling?

subtle ivy
#

because its an order issue

grand idol
#

Through the $GridContainer?

subtle ivy
#

swap the positions of the nodes

#

in the scene tree

#

and you wont get an error

grand idol
#

Isnt this the reference to the sibling?

dry bough
#

Yeah swap them

#

Container then spawner

subtle ivy
#

ya your reference isnt the issue

#

its the tree order

grand idol
#

?

subtle ivy
dry bough
grand idol
#

Ok I get what ya'll are saying to do, swap the positions. trying to understand why that matters in this context to broaden my knowledge

dry bough
#

I would just have the container as a child tbh

#

I usually have plain parent nodes with scripts that have mutiple child node regs

#

*refs

grand idol
#

Mm....Yea I'll have to do some reading once my head clears a bit. Been alot of back and forth trying to understand this. Appreciate you both. I've read that Tree ready order by kidscancode but clearly need another read.

dry bough
#

Good luck! 😀

grand idol
#

Thanks, you too

subtle ivy
#

feel free to @ me here if you run into anything else funky

#

gl!

grand idol
#

lol

#

I can start to see why the order matters. What about the resource value being 1 for every card?

subtle ivy
#

lemme see now that i have the proj

grand idol
#

Thanks

grand idol
#

its also seems to only show the all the cards at once, once the loop is completely finished. I thought it would show each individual card when added as a child to GridContainer?

subtle ivy
#

its a godot debug issue

#

the resource is 1, 5

#

sorry 5, 1

grand idol
#

did you just use a print statement to figure that out?

subtle ivy
#

yup

#

probably that the remote debug inspector doesnt show actual resource values

#

in this case it seems like it only shows the default resource values

#

oh i wonder

grand idol
#

Ok good to know. And last question for today I swear.

Would you have even used a resource here or just some regular properties on the Card script?

#

I just wanted to understand resources a little bit but doesn't seem like this is a good use case

subtle ivy
#

ahh i think i may know why

#

its not an unreasonable use case

grand idol
#

Argh lol ok. Just inexperience at this point

subtle ivy
#

ok here's why

#

you never actually store the resource in the card

#

you create a floating reference to a resource

grand idol
#

So by me dragging in the resource from the FileSystem into the exported Resource slot, that is just a reference, not the actual resource?

subtle ivy
#

but once i add

#

card_instance.card_stats = Card_Stats.new()

#

for one you dont have to worry about 1 shared resource because that creates a unique one

#

but also

#

notice how the resource is now an actual object

grand idol
#

yea

#

ngl, this flies just a hair over my head atm.

#

I get what you are saying tho

subtle ivy
#

yah it's a lil convoluted

grand idol
#

Did I just get lucky that my implementation used the resource in a way that sharing actually makes it work

subtle ivy
#

yup

#

lol

grand idol
#

eesh

#

gross

subtle ivy
#

yah

#

it be like that sometime

grand idol
#

Yea. Gotta lot to learn.

#

Damn. Thanks for your help

subtle ivy
#

np

#

so for unique resources u can just straight up create a new one after you instance a node

#

card_instance.card_stats = Card_Stats.new()

grand idol
#

So thats calling the ClassName.new() to create a new object of the resource?

subtle ivy
#

and you can also look into _init() where if you're familiar with constructors you can pass the values directly into the .new() function

#

card_instance.card_stats = Card_Stats.new(number, number_suit)

#

correct

grand idol
#

I know of constructors and of things, but understand? No. Clearly not 😂

#

I've used constructor in Unity using c#, understand what they are, but I think my brain is fried from understanding all this for 2 hours

#

Need to practise more OOP

subtle ivy
#

haha it would just look like:

extends Resource
class_name Card_Stats

var number := 1
var suit_number := 1

func _init(number : int, suit_number : int):
    self.number = number
    self.suit_number = suit_number
grand idol
#

Right now my OOP is POOP

subtle ivy
#

and then card_instance.card_stats = Card_Stats.new(number, suit_number)

grand idol
#

Gotcha. So thats a constructor that when you call .new() it would tell you, "hey, make it like this"

subtle ivy
#

ya

#

_init runs before everything else

#

as constructors tend to :p

grand idol
#

lolz

#

Alright...well....Im going to go have a good cry, thanks for your help nem

#

would upvote you if i could

subtle ivy
#

lmao no prob

#

get a good nights sleep and it'll make more sense in the morning

grand idol
#

Think I may wanna do a platformer again to learn Godot's "ways" a bit more before I dive into a more data oritented porject, however simple poker may be

#

Do i close this thread?

subtle ivy
#

I'd recommend just make what you want and overtime you'll learn. That way it feels less like active learning and you dont burn out as easy

#

yah not sure how to close it

grand idol
#

For sure.

#

I know how to close it

subtle ivy
#

take care!

grand idol
#

you too

#

peace