Slay the Spire Clone Godot 4 Tutorial: Card Dragging & State Machines (02/08)

Welcome to the second installment of the "Slay the Spire Clone in Godot" series using the powerful Godot engine! 🎮
In this beginner-intermediate tutorial, we'll continue our game development journey by implementing the main card dragging mechanic for our game. Let's dive in!
🚀 Part 2 - Card Dragging Mechanic & State Machines
00:00 - Slay the Spire demo
00:40 - End result
01:29 - Creating the CardUI Scene
08:23 - Adding CardDropArea and Hand to the Battle Scene
13:06 - State Machine explanation
15:43 - Basic CardUI and CardState base class scripts
18:47 - Coding the CardStateMachine
21:06 - Adding Nodes and Scripts for the 4 States
23:00 - Coding the Base State
25:09 - Coding the Clicked State
26:21 - Coding the Dragging State
30:27 - Coding the first version of the Released State
30:55 - Hooking up all the systems, fixing bugs
42:10 - Using the CardDropArea do detect if we should reset the CardUI
46:27 - Fixing one last bug and wrapping up
👩‍💻 Source code for Season 1 on GitHub:
github.com/guladam/deck_build...
🎓 Learn More About Godot:
Godot Docs:
docs.godotengine.org/en/stabl...
docs.godotengine.org/en/stabl...
Heartbeast:
• Godot 4 Tutorial - Hea...
Card Fanning Tutorial by Bramwell:
• How I Fan 3D Cards in ...
☕ If you want to support me, buy me a coffee at:
ko-fi.com/godotgamelab
🔥 Connect with Me:
Instagram: / adamgulacsi
Twitter: / adam_gulacsi
Mastodon: mastodon.gamedev.place/@guladev
#godot #godotengine #2d #tutorial #godotgamelab

Пікірлер: 184

  • @godotgamelab
    @godotgamelab6 ай бұрын

    Hey Everyone! Thanks for the overwhelming support you showed with this series so far! :) I just wanted to let you know that I added timestamps and chapters for my videos so hopefully it's easier for you to navigate if you want to. (you can also find them in the video description) Keep on cookin' and Cheers!

  • @AbsolutelyMindBlowin
    @AbsolutelyMindBlowin6 ай бұрын

    I like how much in depth you are going with the architecture.

  • @godotgamelab

    @godotgamelab

    6 ай бұрын

    Thanks, I appreciate it! I believe breaking it down is a good way to learn these things!

  • @jmh6559
    @jmh6559Ай бұрын

    I really loved the part that explained the principle and function of the object to be implemented step by step by taking the elevator as an example before working on the code, which most tutorials didn't put in even its the simplest and most central part as a "tutorial". So much appreciate for a great video and series!

  • @godotgamelab

    @godotgamelab

    Ай бұрын

    Thanks, glad you like it!

  • @LuizMoratelli
    @LuizMoratelli6 ай бұрын

    So good to see a series with good code / architecture!

  • @godotgamelab

    @godotgamelab

    6 ай бұрын

    Glad you like it! :)

  • @nandomax3

    @nandomax3

    5 ай бұрын

    Right? I'm a little bit tired of tutorials with messy code and zero architecture thoughts

  • @Nerobyrne

    @Nerobyrne

    3 ай бұрын

    @@nandomax3 "Vomit on his IDE already, code spaghetti!"

  • @718Outdoors
    @718Outdoors3 ай бұрын

    I love how you show the final result of the episode at the beginning

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    Glad you like that!

  • @marcelburdon9795
    @marcelburdon97952 ай бұрын

    I really appreciate how you run the program multiple times, and take little breaks going "this should work, right?" only to show us what we're missing, instead of just dumping all the correct code on the viewer right away. Explaining what is missing, or why it is necessary makes me understand the components a lot better. Also interesting to do input-mapping so late into the tutorial, usually KZreadrs knock that away in the first few minutes, without ever really elaborating on it, whilst you do the code first, and the mapping second, makes me actually understand just a little bit better. Despite having previous programming experience, GDscript is still a little tough on me, but I'm slowly learning, and hopefully after a few more videos I'll be comfortable adding my own additions! (like the 3D card fan, switching out the assets and themes, etc. and eventually adding my own non-StS gameplay mechanics) The Godot interface is still rather overwhelming, it's as if PhotoShop and Excel had a baby, with the sheer amount of menus and buttons, but your calm way of guiding the viewer through it is making it a bit more comprehensible. I'll try to maybe get a tutorial or two done daily (though I might be lazy in the weekends) and hopefully by the time I'm done I can get a little creative with the code! Statemachines are still a little scary, but I think I'm getting a hang of the logic, although the code formatting and syntax itself is somewhat complicated.

  • @marcelburdon9795

    @marcelburdon9795

    2 ай бұрын

    Ah! I've got a bug I can't seem to figure out! Moving the cards, changing states, all works seemingly fine. The cards can enter BASE, CLICKED, DRAGGING, and return to BASE... But when I release a card it remains in DRAGGING rather than changing to RELEASED... I've looked through the code multiple times, and everything seems to be in order, I've got no idea where I went wrong...

  • @NanoXzil

    @NanoXzil

    8 күн бұрын

    @@marcelburdon9795If your problem is not yet solved: I also had this problem and it was because I forgot the "not" in the first if statement in card_base_state.gd.

  • @Ocdib
    @Ocdib6 ай бұрын

    One comment: when pasting code (esp. for signals, e.g.: signal transition_requested(from: CardState, to: State), it would help if you explain the thought process behind each function or signal a bit slower. EDIT: e.g.:18:10 onwards Thank you!

  • @Ocdib

    @Ocdib

    6 ай бұрын

    Having a really hard time understanding 18:47 - Coding the CardStateMachine, even though I generally understand signals and nodes :-( what do you suggest I do?

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Hey I can try to clear it up for you a bit: The State machine does two things really: 1. Keeps track of which state we are currently in 2. Manages transitioning from one state to another. To help code the states themselves (base state, clicked state etc.) we also delegate callbacks like input_event() and mouse_entered() so the state can handle those events individually. The transition_requested() signal is used to provide a way for the CardStates to send a message to the State machine saying hey bro: I'm a base state but I want you to go into the clicked state when the user clicked on the card. When transition from one state to another two things happen: We call the exit() function of the old state, Then we call the enter() function of the new state. Does that help? I hope so, let me know if there's anything I can do to clear it up!

  • @nandomax3

    @nandomax3

    5 ай бұрын

    @@godotgamelab good explantion. I understand why you implemented the _on_transition_requested(from, to) signal now. At the moment only the CardStateMachine is listening to this event, but in the future we could attach other script to it to play sound, trigger other actions, and so on. I think I'm going to start a new study project here based on the space invaders theme and i'll use the knowledge you shared with us in this tutorial. I want a simpler base project to consolidate my learning, I'll create a simple FSM with three states move, fire states for the ship and a FSM for the enemy with just move and death states. I'll try to sketch it first and return to the tutorial just to clarify doubts about how you implemented yours

  • @Soroosh.S83
    @Soroosh.S835 ай бұрын

    You don't know how much it helps when you add chapters. The tutorial itself is great I love how you maintain to teach us with patience and good quality I'm more excited to see more of this series ❤

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Thank you so much for your kind words, glad to have you with us! 🧪🥼

  • @lexsdragon1554
    @lexsdragon15545 ай бұрын

    omg this series is exactly what I needed! Thank you so much!

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Thanks for joining the Lab! 🥼🧪

  • @aaronsommers9078
    @aaronsommers90784 ай бұрын

    Great video! Thanks for creating this content that allows beginners to see some more complex code that is explained well, as well as well-organized! Knowing how to organize code efficiently is something that I have been struggling with, but these videos are a great example!

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    Glad to have you with us! ☺️👌

  • @ahmadmuazmohaspa5106
    @ahmadmuazmohaspa51062 ай бұрын

    Im not trying to do this, but once i got watching, im pretty convinced that im gonna watch the whole series for the sheer amount of knowledge ur spilling. thank you!

  • @Ocdib
    @Ocdib6 ай бұрын

    Very clear. Found you through your reddit post. I love your pace!

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Thanks, I appreciate it 😊

  • @reIMAGEN
    @reIMAGEN15 күн бұрын

    This is a great series. Wonderful work mate.

  • @godotgamelab

    @godotgamelab

    15 күн бұрын

    Thanks mate! Glad you like it 😌

  • @yogiwiguna9602
    @yogiwiguna96026 ай бұрын

    Thanks for the tutorial keep it going. It's help me to learn about the State Machine more , still a little bit confused but i try to watch it over and over again.

  • @godotgamelab

    @godotgamelab

    6 ай бұрын

    Hey, happy to help! If you're still confused about state machines I recommend checking out @TheShaggyDev 's channel, he makes some awesome content on the topic! 👌

  • @yogiwiguna9602

    @yogiwiguna9602

    6 ай бұрын

    @@godotgamelab Thank you so much, i will check it. I try make the card game, this video really helped me with the implementation of the dragging and the others.

  • @nandomax3

    @nandomax3

    5 ай бұрын

    ​@@yogiwiguna9602 I also had some difficulties learning how to implement state machines, but after copying the simples exemple from the ShaggysDev, I could bootstrap my learning curve

  • @421LIZO
    @421LIZO6 ай бұрын

    thank you. keep it going!

  • @attilasipos3481
    @attilasipos34814 ай бұрын

    Kúltúrált és megfelelő technológiát használ az úr! Emellett értelmes kódot ír!!!

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    Hoppá hoppá! Köszönöm uram! 😍

  • @nandomax3
    @nandomax35 ай бұрын

    Amazing content. I was wandering how to expand the concepts tought by the shaggy dev on the Advanced State Machine video to use signals to change states too. Your implementation looks really similar to mine, although I don't like the request_transition(from, to), it's a nice way to organize those piece of code

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Thanks, I'm glad you like it. As it's often the case in programming, there are many different ways to implement FSMs but I felt like using signals is a very "Godot way" to do it. In the end, I believe that for your own project, you should use a method that makes the most sense to you. But it's always a good thing to keep an open eye and open mind! 👀

  • @kevintrueblood1057
    @kevintrueblood10575 ай бұрын

    This is an amazing series so far and I look forward to watching the rest of it. I think you're doing a great job of keeping concepts at the beginner / intermediate level. I am someone who knows more or less what the nodes are meant to do and has cobbled together a few small projects. Especially without a computer science background, knowing design patterns or game architecture is invaluable, and is teaching me stuff I didn't even know I needed to learn. You're doing a great job of explaining the "why" as well as the "what".

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Glad you are enjoying it, nice to have you here with us! 😊 Thank you for the feedback, I'm happy to see you're learning new stuff!

  • @derekc.7689
    @derekc.768913 күн бұрын

    I'm around episode 5 now, but I went back to this state machine and I have a few questions: - I can't help but think the "clicked" state is redundant. Even looking at the season 2 code, it doesn't seem to do anything other than go straight to dragging. Why not simplify so that base goes straight to dragging? - What's the difference between on_input and on_gui_input? Around 20:00 we add both of them, and it seems like we sometimes use one and sometimes the other. From what I can tell they're not built-ins, so I don't really see why both are needed. Thanks for making this series! I have some background in programming but game dev is new to me - it's been a great help!

  • @lukelearley

    @lukelearley

    8 күн бұрын

    i am also curious why there is a need for a "clicked" state. i was able to remove it in my game and go straight to the dragged state, but needed to increase the "DRAG_MINIMUM_THRESHOLD" variable to avoid transitioning directly to released. maybe it has something to do with that?

  • @vexave

    @vexave

    5 күн бұрын

    I'm only at episode 2, but I think I can answer your second point. You're correct with the fact that the "on_input" and "on_gui_input" method in "card_state_machine.gd" and "card_state.gd" aren't built-in. But they get called from "card_ui.gd" through "_input" and "_on_gui_input", and those are built-in signals. In terms of difference, I think "_input" always accepts the input while "_on_gui_input" only accepts the input if the cursor is on the CardUI. For example, if you change the "on_gui_input" in the "card_base_state.gd" to "on_input", you end up dragging all cards at once wherever you click.

  • @godotgamelab

    @godotgamelab

    5 күн бұрын

    Hey everyone, Thanks @vexave for explaining, you summed it up nicely! If you want to read more on Input, here's the relevant Docs page: docs.godotengine.org/en/stable/tutorials/inputs/inputevent.html On the gui_input signal itself: docs.godotengine.org/en/stable/classes/class_control.html#class-control-private-method-gui-input In terms of the ClickedState, here's my two cents: - it's an easy concept to understand when you list all the States you can have: Base, Clicked, Dragged, Released. Pretty intuitive if you ask me. - It can happen, that you click on the card but don't move your mouse. In my mind that is clicking and not dragging if I don't move the mouse. There's no way to handle this seperately if you instantly transition into dragging. - UI is always the part of a game that changes the most during development. IF you want to do anything in the future ONLY when you are in a clicked state it's much easier to implement then blending those 2 states together. I would argue that it's so simple to implement that you don't lose a lot of time, it's more flexible and it even makes more sense to me as it's easier to draw the StateMachine's possible transitions. That said, if you feel like it's superfluous you can always go directly into the dragging state instead! Do whatever makes sense to you! :) Hope that helps!

  • @underscorerx
    @underscorerx3 ай бұрын

    amazing tutorial. here's some engagement to bump it up in the algo

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    thanks, glad you like it! :))

  • @ciaala
    @ciaala23 күн бұрын

    Hi Adam, thanks for this video, I love your content. Please continue! I would also like to leave my comment to suggest an improvement for this episode since I found it hard to follow and I perceived it as rushed. I would have preferred to have an intro to the Input system of Godot either here or a link to another video, because it was hard to follow the part about propagation. I Would have change the way you present the state transition by first creating Base -> Drag and then presenting the full architecture and in the end write the rest of the code. I am a programmer and the code and the state machine principle were not the problem. What I found hard was that I had to follow you switching between signals, direct reference in the code, some other mechanism of reference by group. I was also not expecting to find the state machine implemented as sub nodes instead of just class instances. I will re-watch the video a second time. Love your content !

  • @godotgamelab

    @godotgamelab

    23 күн бұрын

    Hi, thanks for the kind words and the suggestions. I agree with most of what you've said. At the same time, this course was created for people who are already somewhat familiar with Godot. I tried to strike a balance of not over explaining because the videos are quite long already. But you are a 100% right, this comes at a cost of sometimes having less structured explanations. Hopefully you'll find the other episodes clearer!

  • @TheCamulous
    @TheCamulousАй бұрын

    Hey, first I want to say this is an absolutely amazing series! I just have one problem I can't solve for the life of me. Everything is working with the exception of snapping the cards back to hand if you right click or play outside the play area. I've set up debug checks to see where it is going wrong. According to those everything is running and it seems that the child.reparent(self) call in hand.gd is running but simply not reseting the position of the card. I would love any direction on where to keep looking for issues!

  • @TheCamulous

    @TheCamulous

    Ай бұрын

    Turns out the child.reparent(self) call was retaining the position of the child. To work around this I just replaced the reparent call with child.get_parent().remove_child(child) and self.add_child(child). It's not pretty but it works.

  • @lukebichard7762

    @lukebichard7762

    Ай бұрын

    @@TheCamulous I had a similar issue, so tried this workaround. However it appears that should you release the first card, then exit a move with your second card, it snaps back all cards, including the previously released card. Any ideas? Did you get similar behaviour?

  • @TylerAlbers01
    @TylerAlbers01Ай бұрын

    Wonderfully done, and exactly the series I need as a jumping-off point! minor note: the naming format you're using is called snake case, not pascal case snake = my_variable_name pascal = MyVariableName

  • @godotgamelab

    @godotgamelab

    Ай бұрын

    Yeah I keep messing that up, even in season 2 😂 I swear I know the difference but bruh. For some reason, speaking English messes up my brain sometimes I guess 🐍

  • @TylerAlbers01

    @TylerAlbers01

    Ай бұрын

    @@godotgamelab The fact that you're putting out such quality content in a second language is hella impressive

  • @godotgamelab

    @godotgamelab

    Ай бұрын

    @@TylerAlbers01 thanks, that means a lot me! Glad you like it 😊

  • @seanwade7824
    @seanwade78245 ай бұрын

    Really getting a lot out of this - thank you for taking the time to put this together! Hoping you can help give some direction - the drop point detector for releasing cards seems to be triggered based on the bounds of the CardUI itself, not the mouse pointer. Is there any way to base that drop point snapping back to hand functionality on where the mouse is at when releasing, rather than where the bounds of the cards are? Because the way it's currently implemented, a card enters 'RELEASED' state on confirm even if just the very top of the card border has entered the card drop zone.

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Hey, sure. That shouldn't be too hard to change. Here's a soluition from the top of my head: 1, in the CardUI change the DropPointDetector's collision shape to a smaller rectangle, like 10x10. 2, update the CardDraggingState code, and change the card_ui.drop_point_detector.global_position to the mouse position when you start dragging the card 3, in the CardBaseState reset the card_ui.drop_point_detector.global_position to it's original position and you should be good to go! :)

  • @Soroosh.S83
    @Soroosh.S835 ай бұрын

    I love slay the spire I actually finished 1 playtrough with each character except watcher. I didn't defeat heart but even tho the experience was fun 😊

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Come on, you can beat the heart, you got this! Just need a sprinkle of luck and a great deck! 🍀💪

  • @dommychi
    @dommychi7 күн бұрын

    Just started with Godot and I'm loving this tutorial! Just got a question: When releasing the card outside of the card drop area, what input event is activating the on_input function to make it return to the base state? Edit: I printed the event as text and it came back as a Mouse motion event. So when I drag the card by holding down the left mouse button then I release the card by releasing the left mouse button, how come a mouse motion event gets triggered after I release the card?

  • @RafaMartinelli
    @RafaMartinelli6 ай бұрын

    Loving this, I've always wanted to create my own card game! Quick question: What's the difference between func name(): and func name(): -> void? Is the -> void part absolutely necessary after each func or is it redundant?

  • @godotgamelab

    @godotgamelab

    6 ай бұрын

    Hey, thanks for the feedback, glad to have you with us! 😌 As for the void return value I'll give you a pros and cons how about that? Pros: - easier to read to code at a glance (you see that it won't return a value right away) - using static typing makes GDscript a tiny bit faster (though might be insignificant in this case) - keeps the code consistent (I try to use static typing everywhere) Cons: - more verbose - takes more to time to write for *seemingly* no reason - you might consider it to be redundant In this case, I think the pros outweigh the cons but it's really up to you and your personal preference. Hope I answered your question! 😌

  • @XenoFect
    @XenoFect4 күн бұрын

    Awesome indepth series! Thanks for sharing! When you connect the signals how did you have the -> void: show up automatically? was that the magic of editing?

  • @godotgamelab

    @godotgamelab

    4 күн бұрын

    Not magic actually! You can turn on static typing as an editor setting: Quoted from the docs: "If you prefer static typing, we recommend enabling the Text Editor > Completion > Add Type Hints editor setting. Also consider enabling some warnings that are disabled by default." docs.godotengine.org/en/stable/tutorials/scripting/gdscript/static_typing.html Super useful! Also, thanks for the kind words 😌

  • @XenoFect

    @XenoFect

    4 күн бұрын

    @@godotgamelab Awesome! Thanks for the info and the super quick response!

  • @muxecoid
    @muxecoid5 ай бұрын

    Thanks for the training. Just a small note, the part with if from!=current state, should be with an assert, not just if.

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Absolutely, you can use asserts if you want to generate error messages. Thanks for the tip!

  • @alexdoessudokus
    @alexdoessudokus4 ай бұрын

    First of all thank you for this series, I'm just watching it through the first time to get to grips with the concept before coding along side on my second watch to make sure I understand what's going on. However I noticed something in this episode (sorry if you address it later): You take the CardUI out of the hand immediately on drag state, and then reparent it on release if it needs to go back - doesn't that change the order of the cards instead of restoring them to the original order? I know in Slay and Monster train at least - cards always snap back to their original position in the hand, which will be important for mechanics like random discard and exhaust. Just wanted to check and make sure I'm getting this right! I'm thinking when I approach this part I'll only take CardUI out of the Hand on release - but I don't know if that would cause other issues?

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    Glad you started doing the series! Don't worry, we'll fix this down the road. Nice catch!

  • @alexdoessudokus

    @alexdoessudokus

    4 ай бұрын

    @@godotgamelab Awesome thanks! I’m not surprised that you’re covering it later, considering how well you pick up the quirky bugs at the end of the episodes, and then providing great explanations and solutions to them. Really great way of teaching - since bugs are generally more memorable and it’s a good way of really getting students to remember it in the future. Thank you for doing this series and I’m looking forward to more :)

  • @Lander_Calcoen
    @Lander_Calcoen2 ай бұрын

    Hi, @godotgamelab. I have a error: Error at (18, 9): Cannot call non-static function "enter()" on the class "CardState" directly. Make an instance instead. What do i do?

  • @lukelearley
    @lukelearley8 күн бұрын

    not sure if this is a bug or working as intended, but due to the way the "dragging" state only updates 'on_input', if you click and hold the left mouse button on a card, release it outside of the 'card_drop_detector_area' (in the hand or lower part of the screen), but do not move the mouse or click anything else, the card will float as though it is still in the "dragging" state until you do either move the mouse or click something. i was able to fix it by changing the 'on_input' function to a '_process' function, but i'm not sure how that will effect performance or interact with other systems down the line. oh, and thanks a ton for this series! i've been binging it over the past few days and really appreciating so many aspect of your presentation style.

  • @godotgamelab

    @godotgamelab

    7 күн бұрын

    Hey, Thanks for pointing this out. Someone reported a very similar issue to this. We fix it later down the line!

  • @FaceofFrequency
    @FaceofFrequency2 ай бұрын

    I would've liked if you went back to the state machine graphic at the end and overlayed the script names we created to relate them all back to the concept. Also, I couldn't reproduce the click error at the very end (Godot Version 4.2.1). Followed those steps of course anyway! Likely gonna go through again and comment my code so I get what it does. It very much feels like to me like this is real properly written code with very good practices and things. Thanks!

  • @godotgamelab

    @godotgamelab

    2 ай бұрын

    Good idea, thanks for the feedback! :)

  • @davidReyGD
    @davidReyGD5 ай бұрын

    You have to grouw up with more subscriptors, I'm very boring to see always the same platformer series :) thnx! that's really hepful.

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Thank you so much! Glad to have you with us! ☺️

  • @itadaimasu
    @itadaimasuАй бұрын

    Hi, great tutorial. I have an issue, I « cannot call « non static function « is_node-ready » on the class « CardUI » directly. Make an instance instead. » does anyone know why and how to fix it? Thanks

  • @txeemo6946
    @txeemo694627 күн бұрын

    Curious, my cards are not showing as base but I cannot find any errors that could guide me to the issue. Can you tell me what lines or functions I need to check to find the issue.

  • @MuseDoes
    @MuseDoes2 ай бұрын

    Hey, love the videos so far, but I am having an issue with the CardStateMachine node. The class CardStateMachine doesn't appear in the Inspector window for me. I'm unable to change its default state to Base. All of the children within the CardStateMachine have the CardState class and I can select their States. Just not their parent node. Is there a way to fix that?

  • @godotgamelab

    @godotgamelab

    2 ай бұрын

    Have you created the script for it? Make sure you attach the CardStateMachine script to that parent node. If you have the proper code for that class, the export variable will appear in the inspector!

  • @Mech_rat
    @Mech_rat4 ай бұрын

    Great series! I have a bit of a question in the adding nodes and scripts for the 4 states section. I am unable to assign any states to the 4 nodes some reason. When I click assign state in the inspector tab, every node or choice is greyed out. I was only able to set a default state for the CardStateMachine node. How can I fix this? Godot 4.2.

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    Hey, it seems like the Editor doesn't recognize your state nodes as state type nodes. Make sure to: - assign scripts to those nodes - in their assigned script, don't forget the "extends CardState" line so they inherit all their properties from the base CardState class. If both of those are are done you should be able to pick them in the inspector. If still not, try Project --> Reload Current Project from the menu after checking both of them. Let me know how it goes!

  • @EvanGSinclair

    @EvanGSinclair

    4 ай бұрын

    @@godotgamelab I'm having a similar issue. Followed all your steps above but I don't even see the CardState option in the window, I can only see Node

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    @@EvanGSinclair If you didn't forget to attach the script to the nodes and followed all the steps, you might want to reload the editor. Go to Project --> Reload Current Project. Sometimes it solved issues like this to me. I guess these inconveniances are still expected with Godot 4. Lemme know if that helps!

  • @EvanGSinclair

    @EvanGSinclair

    4 ай бұрын

    @@godotgamelabworks now, I think the issue was something to do with the "Template" selected when making the initial scripts. Yours were "Object: Empty" mine were "Node: Default" . That's the only difference I could find.

  • @LiinksGaming
    @LiinksGaming10 күн бұрын

    Hi i followed the guide and i dont ran into an error where the cards state dont change into BASE automatically and i cant hold them would you perhaps know the reason?

  • @dmsys6516
    @dmsys65165 ай бұрын

    func on_input(event: InputEvent): I assume that this function will be triggered when any input is given? since there are no process function i assume that's how these system works But wait this is a ui node and i dont know much about them right now, so am i correct? If i am then are they triggered on every input set up in project's input map?

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    If you don't know much about how Godot handles input I recommend reading the docs: docs.godotengine.org/en/stable/tutorials/inputs/inputevent.html In short: _input(event: InputEvent) is called whenever an input event occurs. We can filter it out for our own desired inputevents we want to handle. In this game there are three: - left click (defined in the InputMap project settings) - right click (same) - moving the mouse while in the clicked state (it is called InputEventMouseMotion)

  • @TheDonValerianos
    @TheDonValerianos5 ай бұрын

    Thanks for great tutorial. Thing became much cleaner for me. Especially when you point on issues and show how to address them. One thing I didn't catch up - why do we need and exit_state function? Looks like it does nothing for a current step of tutorial. So whats the purpose of it?

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Glad to hear that! At this point, we don't really use it but sometimes we might. Later we use that logic, let me give you an example: When we start aiming with a single targeted card (i.e. go to the aiming state) we will notify another node (the CardTargetSelector) that we started aiming so we can display an arc and select an enemy. But when we finish aiming, we want to notify that same node that we finished the aiming process so it can hide the arc and turn off the target selector mechanic. However, we can finish aiming for 2 reasons: - we canceled it or selected an invalid target (we go back to the base state) - we selected a valid single enemy (we play the card) If you think about it, it doesn't really matter which happens because we want to turn off the target selector in both cases. For that reason, we can use the exit() function so whenever we leave aiming (for whatever reason) we can notify the CardTargetSelector that the aiming process has ended. Hope that makes sense and helps! :)

  • @nicecatch8646
    @nicecatch8646Ай бұрын

    There is an issue here. If you move the mouse and then click on the card, the card immediately transitions from the 'Clicked' state to the 'Dragging' state. This is likely because the previous mouse movement event was also captured. How can one implement the action of moving the mouse, clicking, and then staying in the 'Clicked' state, only transitioning to the 'Dragging' state upon subsequent mouse movement?

  • @Ichthyoid
    @Ichthyoid4 ай бұрын

    Just started this series, thanks for putting it up! I noticed a small bug towards the end of the video (don't know if it'll get fixed later): If you click on a card without releasing the left mouse button, drag it over to the side (not inside the play area target), and then release WITHOUT moving the mouse, it'll go into the release state, but still stay stuck in its position. Then, only if you then provide any input, it'll snap back to the hand/base state. I think this may be a consequence of the input function being the only thing that transitions the release state back to base state?

  • @Ichthyoid

    @Ichthyoid

    4 ай бұрын

    I eventually fixed this through the dragging confirm code, checking for the target area there (if target area isn't empty, it goes to released, if not, it goes back to base). Hope this doesn't break any code down the road 😅

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    That's a good point, thanks for pointing it out. I'll look into it ☺️

  • @Ichthyoid

    @Ichthyoid

    4 ай бұрын

    @@godotgamelab the series is really great so far! I especially love how it’s not for beginners, since there are a lot of those kinds of tutorials. Going through and reading and thinking about the code you’re using is really helping me expand my knowledge of gdscript and coding in general! Thanks!

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    glad you like it and thanks for your kind words! :) @@Ichthyoid

  • @longuemire748
    @longuemire7485 ай бұрын

    Thank you for this tutorial, it's very interesting. but what is the purpose of the "on_gui_input" function in the script CardState (17:57)?

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Thanks, glad to have you here. Great question! We provide 4 callback functions for the different States in our StateMachine which they can override. gui_input() is for GUI nodes specifically. We'll override this in the BaseState latern where we prevent any kind of interaction for that card when its disabled and shouldn't be interacted with. Hope it makes sense!

  • @longuemire748

    @longuemire748

    5 ай бұрын

    @@godotgamelab Sorry, I just saw the message, thanks for the explanation.

  • @muxecoid
    @muxecoid5 ай бұрын

    In this example what guarantees on_input of released state to be called? In my tests it is mouse motion, but it feels a bit ugly to wait for input to return to base state. Checking the list of targets when getting out of dragging state feels so much cleaner.

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    I'm not sure what you mean by that. on_input() is called when whatever input event is registered for the card: this can be mouse motion, mouse clicks, actions pressed, anything really... Input-based cancels can only happen when we right click to cancel out the dragging, I don't see the problem of using the input callback for this. But use whatever you think is clean :)

  • @tinypixel343
    @tinypixel3435 ай бұрын

    I am really enjoying this series, I just did not really like the last part with the lambda function, your code is so well structured and the lambda parte made it look like it was rushed. I am changing that last part for a timer nested inside CardDraggingState node, when CardDraggingState enters, the timer starts and then connects to a function without a lambda function, it felt cleaner to do it this way. But then I caught myself asking, ok so he is very organized, is there any advantage to use that lambda? Maybe something I haven't learned yet...

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Hey, I'm glad you like it so far. I think it's up to personal preference. If the timer + timeout feels cleaner to you do it that way by any means. Don't really see any advantage picking one over the other 🤔

  • @lassepoulsen7591
    @lassepoulsen75915 күн бұрын

    Hello! i'm currently experiencing issues with the snapping back to the original position on right click, i can see from the text on the card that it does go back to base state, but it doesn't get the base state position

  • @godotgamelab

    @godotgamelab

    5 күн бұрын

    Hey, you need to reparent it to the Hand so it goes back. When the game is running, you can use the remote SceneTree to check if the raparenting actually happens!

  • @K0ll7n
    @K0ll7n21 күн бұрын

    After adding CardStateMachine node and code for card states, i started getting next error: Invalid get index 'state' (on base: 'Control (CardUI)'), after tring to run the game, wich references line card_ui.state.text = "BASE" in card_base_state.gd script. Does abybodyhave some suggestions maybe? EDIT: I had a typo as always, namely wrote label incorrectly in card_ui script.

  • @UnstoppableTigra
    @UnstoppableTigra5 ай бұрын

    hi. what is the purpose of line "var card_ui := child as CardUI" (in hand.gd). Is it for code readability ?

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Sure, In your example we are referencing the CardUI node which is a Control Node in the SceneTree. The truth is that the code works perfectly fine without using the "as CardUI" bit. Let's see what is does. When we type "as CardUI" we cast it from a Control Node to a CardUI type. This way, when we use the variable's name in the script, we'll get auto-complete (intellisense) based on the CardUI class. The result is that you don't need to remember property names and functions precisely and it's easier to code while also it's less error-prone because you make less typos. Also, this is we use "class_name CardUI" at the top of our scripts! So we can use CardUI as our own custom type (class) You can try this if you start typing card_ui. in your code and press ctrl+space. You'll see all the suggestions correctly but if you delete the "as CardUI" bit, you'll only get suggestions based on the built-in Control Node class. I hope that clears it up a bit! If you want to refer to the docs, you should look up the reference page for GDScript itself: docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#casting

  • @UnstoppableTigra

    @UnstoppableTigra

    5 ай бұрын

    @@godotgamelabthanks for the detailed answer. Your tutorial rocks.

  • @RedCocoon
    @RedCocoon22 күн бұрын

    Megacrit saw this and thought We could make this better

  • @godotgamelab

    @godotgamelab

    22 күн бұрын

    oh mate, I wish I had that kind of influence 😅 can't wait for the StS 2 though!

  • @sprooc
    @sprooc2 ай бұрын

    Hello, on the "card_dragging_state" and "card_clicked_state" I am getting an error saying that the identifier "transition_requested" is not declared in the current scope. From this error I have actually found a lot of stuff I missed trying to figure out what I did wrong but now everything looks like yours and it still says it is not declared in the current scope.

  • @godotgamelab

    @godotgamelab

    2 ай бұрын

    Hey, does your base CardState class exist? If so make sure that the CardDraggingState and CardClickedState actually extend that class where we defined that signal. Then, it should work!

  • @PeteReborn
    @PeteReborn18 күн бұрын

    I've got a Mac with a trackpad. Unfortunately, I can't test a right click action.

  • @jimdangle7213
    @jimdangle72134 ай бұрын

    @GodotGameLab I am getting an Error within the card_base_state script: "card_ui" not declared in the current scope. where in the tutorial did you declare this? is it still uptodate or am I doing something wrong? hope you still read these comments!

  • @jimdangle7213

    @jimdangle7213

    4 ай бұрын

    Wow i am dumb, i typed in a previous script: vi instead of ui, that v really looked like an u :D

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    Happens to the best of us 😅 glad you fixed it!

  • @deftmute
    @deftmute4 ай бұрын

    When i enter the lines that are highlighted at 33:08, it tells me that an argument is expected for lines 24 and 28. I've triple checked my syntax and can't see any differences. Any idea what's up?

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    which lines you have problems with? there is no line 28 at 33:08

  • @deftmute

    @deftmute

    4 ай бұрын

    ​@godotgamelab it's the card_state_machine.on_mouse_entered and exited. They both say that they expect an argument. Sorry, I think my timestamp may have been the last frame it was on screen, but it was where I had it paused while rereading. Edit: I finally got some time and just started over. Pretty sure I figured out where I messed up. Everything is working and I am progressing now. Thank you for your time.

  • @Sal333k
    @Sal333k4 ай бұрын

    Hiya! I'm getting Parse Error: The function signature doesn't match the parent. Parent signature is "enter() -> void". This happens with the "initial_state.enter()" in the card_state_machine script. Not sure how to deal with it since i've been pretty much copying everything. Any advices or explanation would be awesome :)

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    Can you send me a pastebin link of your card_state_machine.gd and card_state.gd? It's hard to answer without seeing the code

  • @cobysuk-3294

    @cobysuk-3294

    3 ай бұрын

    @@godotgamelab I seem to have a similar problem, as there is an error stateing "Identifier "initial_state" not declared in current scope" on the "if initial_state:" line. I have been copying everything, so any help would be appreciated.

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    ​@@cobysuk-3294 sounds like you don't have the initial_state variable declared at the top. Here's the CardStateMachine class's final version from GitHub: github.com/guladam/deck_builder_tutorial/blob/5bad93421de9c0e1978ec842de31342f7f7e4137/scenes/card_ui/card_state_machine.gd Hopefully you can find what's wrong by comparing them. For the CardState and derived classes you can check this folder to see what's going sideways: github.com/guladam/deck_builder_tutorial/tree/5bad93421de9c0e1978ec842de31342f7f7e4137/scenes/card_ui/card_states Cheers, Adam

  • @GameUISchool
    @GameUISchoolАй бұрын

    🤩

  • @fvhaudsilhvdfs
    @fvhaudsilhvdfs4 ай бұрын

    38:32 Could someone explain this part to me? Why does adding this variable fix anything? It doesn't seem like the variable name is being referenced anywhere so why would this prevent the crash that was just happening...?

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    Hey, I'll try my best: - this is a dependency for the CardStates because they might want to do stuff like animating the CardUI, calling methods on the CardUI and so on. - we declare this variable here to make sure that each and every CardState will have a card_ui available. - you're right: in itself it does nothing. However, in the CardStateMachine class, we will actually assign the parent (the CardUI node itself). - later in the video, when we code the CardStateMachine class we'll have az init() function where we set this variable. Hope this makes sense, cheers!

  • @fvhaudsilhvdfs

    @fvhaudsilhvdfs

    Ай бұрын

    @@godotgamelab oh shit. i think i missed that the individual card state scripts *are* already referencing the drop_point_detector var. so that makes sense why the crash was happening then. thanks for the explanation and the video(s)

  • @thetiphon
    @thetiphon4 ай бұрын

    What kind of input event we're handling in on_input function in release state 44:20? I assume that we are already handled release event in dragging state. We are just waiting for random event to happen? This code is weird for me

  • @godotgamelab

    @godotgamelab

    4 ай бұрын

    I think you're a bit confused about what get_viewport().set_input_as_handled() does. From the docs: "Stops the input from propagating further down the SceneTree." That means if we click with the LMB to confirm releasing the card, no other Node can pick up that left click. Omitting this can lead to some unexpected behaviour. For example, you start dragging a Card and you move it above another Card in your Hand. If you click with the LMB again, that SAME InputEvent (left click) can be picked up by the other Card. That's not what you want because in general you want one click to do one thing right? So if you click to release the first card it gets released. If you decide to pick up and drag another you want to click AGAIN for that which should be a new InputEvent. Does that make sense?

  • @thetiphon

    @thetiphon

    3 ай бұрын

    ​@@godotgamelab Actually not, this is not what makes me confused. My question is in what event case we are entering "on_input" function inside card release state? What event makes transition from release state to base state?

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    @@thetiphonOh, I see sorry. That was a misunderstanding from my part. Here, really ANY kind of InputEvent makes the card to go back to the base state because the enter() function gets called first when we enter the state. The on_input() callback function can only trigger AFTER the enter() function has already finished its execution. We have a flag called played which can be either true or false depending on whether we successfully played the card or not. In our on_input() callback we check this flag. If it's false AND we received ANY KIND OF InputEvent this card can get (left click, right click, releasing the card or just moving the mouse over the card for example) we can transition back to the base state because it means we couldn't play the card as we had no valid target. Does this help? If you're curious what event triggers this, put a print(_event) before the transition_requested signal and when you play the game you can see which event triggered this but it doesn't really matter.

  • @thetiphon

    @thetiphon

    3 ай бұрын

    @@godotgamelab yes, thanks. Your code architecture is great. Pleasure to see

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    thanks, happy to help! @@thetiphon

  • @tars9063
    @tars9063Ай бұрын

    I hope to find an answer by myself in a few hours, but I have this problem, where only thing that's being processed by the game is first click. All the cards together go orange and @clicked", but no dragging or anything. Any ideas?

  • @XxKagarwaxX

    @XxKagarwaxX

    16 күн бұрын

    I do have the same problem. Have you found a solution already by any chance or does anyone else have an idea? no matter where you click, it will permanently change the state of all cards to "CLICKED"

  • @tars9063

    @tars9063

    16 күн бұрын

    @@XxKagarwaxX I believe I did. Will Get to the PC and check for you

  • @XxKagarwaxX

    @XxKagarwaxX

    15 күн бұрын

    @@tars9063 you are my hero

  • @tars9063

    @tars9063

    15 күн бұрын

    @@XxKagarwaxX didn't find it then, found now. Check card_state_machine script, func on_input, if you have "current_state.on_input(event)" or on __gui__input

  • @XxKagarwaxX

    @XxKagarwaxX

    15 күн бұрын

    @@tars9063 thank you for checking back! Sadly I already have the current_state.on_input(event), so there is likely another mistake I have made. from the card_state_machine-script func on_input(event: InputEvent) -> void: if current_state: current_state.on_input(event) func on_gui_input(event: InputEvent) -> void: if current_state: current_state.on_gui_input(event)

  • @dimtool4183
    @dimtool41835 ай бұрын

    so at 38:50 when starting to click and drag, when clicking anywhere at all, all three cards display "CLICKED", and nothing else happens at all. No errors either. Godot 4.2, Compatibility. But before this, when testing and hooking up, I didn't get exactly the same no-error or errors at same time as in tutorial.

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    Hey, haven't tried it with 4.2 but everything should be working I think. Make sure to double check these: - code for the State machine itself - code for the individual states - in the card UI scene, the state nodes should have their correct enum value type set as their export variable, - double check if you set the mouse filter options correctly for the Control nodes in the card UI script. Hopefully you can find what's causing this behaviour.

  • @dimtool4183

    @dimtool4183

    5 ай бұрын

    @@godotgamelab tested with 4.1, and also Mobile mode, same issue, also looked at most code and stuff (not all maybe, and probably missed something), can't find any mistakes yet, will report if I fix it.

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    @@dimtool4183 yeah it's probably in the code. If you can't find the mistake, you can zip the project and send it to me, so I can try to help. You can find my email in the channel page

  • @dmsys6516

    @dmsys6516

    5 ай бұрын

    I am also on godot 4.2 and this works like a charm

  • @Youngdeff1

    @Youngdeff1

    5 ай бұрын

    in the card_ui script make sure that the input function is "_input" and not "on_input" had the same issue and this fixed my problem also make sure to check the scripts that @godotgamelab mentioned

  • @nicholasmoreno6358
    @nicholasmoreno63583 ай бұрын

    My cards will transition to the base state, but no matter what I do, I cannot get them to transition to “clicked”. I’ve double and triple checked and everything should be working. It seems to either be something in my settings or something where the base state does not emit its signal correctly I can’t seem to fix it.

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    Hmm, there are a lot of ways this can go wrong... Did you connect the signals in the editor too? You need to connect the CardUI nodes signals to their corresponding functions.

  • @nicholasmoreno6358

    @nicholasmoreno6358

    3 ай бұрын

    ​@@godotgamelab I got it all the way to the Dragging State. It will return to the base state on a right click. It will set to input_as_handled on a right click. However it will not register a mouse release nor will it transition to the Released state. The only difference in code is that I used on_gui_input instead of on_input.

  • @nicholasmoreno6358

    @nicholasmoreno6358

    3 ай бұрын

    ​@@godotgamelabOkay, I went back and redid the video. There was a tiny error in my card_state_machine

  • @marcelburdon9795

    @marcelburdon9795

    2 ай бұрын

    @@nicholasmoreno6358 Hi! I've got the same problem where the card will enter CLICKED and DRAGGED, and return to BASE, but won't enter RELEASED, just staying in DRAGGED. I've looked through the code many times and can't seem to see any issue, what was your problem, maybe I'm experiencing the same?

  • @onreadyvar
    @onreadyvar2 ай бұрын

    I should have missed something, but let me leave here my experience: moving position of cards in _gui_input might not work when your card is too small. _gui_input only sees what happens on the control, so it may lose the cursor if it moves quickly.

  • @godotgamelab

    @godotgamelab

    2 ай бұрын

    I don't really get it. I use pretty small cards too (20*30 pixels). Can you move them faster than the input event registers? That seems a bit weird but I need to test this.

  • @onreadyvar

    @onreadyvar

    2 ай бұрын

    ​@@godotgamelab Thanks, you indeed got a point, this may not be a general bug but system-specific. I noticed my get_global_mouse_position() returns different coordinates every call.

  • @Lander_Calcoen
    @Lander_Calcoen2 ай бұрын

    Does this part of the tutorial work in godot 4.2.1 to?

  • @godotgamelab

    @godotgamelab

    2 ай бұрын

    Yes, it should!

  • @Lander_Calcoen

    @Lander_Calcoen

    2 ай бұрын

    Thanks! @@godotgamelab

  • @is_game_maker
    @is_game_maker2 ай бұрын

    Invalid call. Nonexistent function 'on_input' in base 'Nil'.。。。。。thats why?

  • @is_game_maker

    @is_game_maker

    2 ай бұрын

    If I press CTRL+INIT() and so on, I can jump to the function I wrote before in card_state_machine.gd, but I still get an error

  • @Xipheos_
    @Xipheos_Ай бұрын

    Idk what I did wrong but I get "Cannot call method 'is_node_ready' on a null value. Im not able to fix it :c

  • @Xipheos_

    @Xipheos_

    Ай бұрын

    Fixed it

  • @itadaimasu

    @itadaimasu

    Ай бұрын

    Hi, how did you fix it?

  • @Xipheos_

    @Xipheos_

    Ай бұрын

    The hierachy was wrong in the CardStates, basically I make the Drag, Click and so on inherit from the Battle node instead of the CardStateMachine or however you called it like

  • @Xipheos_

    @Xipheos_

    Ай бұрын

    ​@@itadaimasuIf I have not explained myself good enough lemme know

  • @BarcelonaMove
    @BarcelonaMoveАй бұрын

    I tried to follow this tutorial with C#, but the reparenting and signals part is getting out of hand. I think I will stick to gdscript even if i dont like it much...

  • @godotgamelab

    @godotgamelab

    Ай бұрын

    There is someone in the comments who did the whole thing in C# under one of the videos... Maybe you can try to contact them?

  • @codypagunsan
    @codypagunsan3 ай бұрын

    hi, I'm new to this series; great content so far! i'm making a deckbuilder myself and I approached the drag and drop using the built-in functions instead: _get_drag_data, _can_drop_data, _drop_data. do you have any thoughts/opinions on using them instead of your apprach? i feel like it can avoid the need for state machines here's what I followed: kzread.info/dash/bejne/e5V108qCc5iqkaw.html my cards call the _get_drag_data function my card drop areas call the _can_drop_data and _drop_data functions

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    Hey! That works fine too, but I find it a bit too limiting for this game so I opted for a different solution. The Godot built-in version only works on Control nodes, and you have to set a preview which shows below the cursor. I feel like having more control over the dragging for a Card game is a worth trade-off if you have to / want to change things up later. If the built-in solution works for you however, I recommend sticking to it because it's actually much much easier then implementing it on your own like we do :) Cheers!

  • @codypagunsan

    @codypagunsan

    3 ай бұрын

    @@godotgamelab well said! i'm going to try the built-in route as i follow along your course. props to your solution though, it really gives much more freedom to do what's needed. thanks for your perspective

  • @kardrasa
    @kardrasa5 ай бұрын

    Your channel icon kinda looks like Godot givin me the middle finger..

  • @godotgamelab

    @godotgamelab

    5 ай бұрын

    It's supposed to be a lab bottle. Nothing personal, promise 😅

  • @monamibob
    @monamibobАй бұрын

    Great series so far! I'm a bit stuck unfortunately, I'm getting type errors in _on_transition_requested when I click my cards. E 0:00:01:0988 card_base_state.gd:14 @ on_gui_input(): Error calling from signal 'transition_requested' to callable: 'Node(Card_State_Machine.gd)::_on_transition_requested': Cannot convert argument 1 from Object to int. core/object/object.cpp:1140 @ emit_signalp() card_base_state.gd:14 @ on_gui_input() Card_State_Machine.gd:26 @ on_gui_input() card_ui.gd:18 @ _on_gui_input() However my card_state.gd seems fine: What could cause my transition requested to consider my from variable as an int? ------------------------------------ class_name CardState extends Node enum State {BASE, CLICKED, DRAGGING, AIMING, RELEASED} signal transition_requested (from: CardState, to: State) @export var state: State var card_ui: CardUI func enter() -> void: pass func exit() -> void: pass func on_input(_event: InputEvent) -> void: pass func on_mouse_entered() -> void: pass func on_mouse_exited() -> void: pass ------------------ class_name CardStateMachine extends Node @export var initial_state: CardState var current_state: CardState var states := {} func init(card:CardUI) -> void: for child in get_children(): if child is CardState: states[child.state] = child child.transition_requested.connect(_on_transition_requested) child.card_ui = card if initial_state: initial_state.enter() current_state = initial_state func on_input(event: InputEvent) -> void: if current_state: current_state.on_input(event) func on_gui_input(event: InputEvent) -> void: if current_state: current_state.on_gui_input(event) func on_mouse_entered() -> void: if current_state: current_state.on_mouse_entered() func on_mouse_exited() -> void: if current_state: current_state.on_mouse_exited() func _on_transition_requested(from: CardState.State , to: CardState.State) -> void: if from != current_state.State: return var new_state: CardState = states[to] if not new_state: return if current_state: current_state.exit() new_state.enter() current_state = new_state

  • @godotgamelab

    @godotgamelab

    Ай бұрын

    Hey, Check for the signature of your _on_transition_requested function: The first parameter should be CardState (you have CardState.State instead), and the second one is CardState.State (the enum)! That should do it

  • @monamibob

    @monamibob

    Ай бұрын

    @@godotgamelab Thank you so much!!

  • @718Outdoors
    @718Outdoors3 ай бұрын

    at 32:52, I've typed: ------------------------------------------------------ func _ready() -> void: card_state_machine.init(self) ------------------------------------------------------- I get an error.......Invalid Call. Nonexistent function 'init' in base "Nil' The init function seems to be set up in Card Machine script correctly. ---------------------------------------------------- func _init(card: CardUI) -> void: for child in get_children(): if child is CardState: states[child.state] = child child.transition_requested.connect(_on_transition_requested) child.card_ui = card if initial_state: initial_state.enter() current_state = initial_state ------------------------------------------------ I have very little experience with coding. so issues are harder to logically figure out in many cases.

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    this means that the card_state_machine node is not found. You need to make sure ifthe CardStateMachine node with the script actually exists in the CardUI scene AND in the cody your @onready var reference to the CardStateMachine node is correct.

  • @718Outdoors

    @718Outdoors

    3 ай бұрын

    Thank you for you reply....again, a little lost!. The CardStateMachine node, with script, is in the CardUI scene....not sure what you meant by "AND in the cody". I assume cody is code, but if so not sure what that means.

  • @godotgamelab

    @godotgamelab

    3 ай бұрын

    @@718Outdoors I meant that you need to reference the state machine as an onready variable like so: @onready var card_state_machine: CardStateMachine = $CardStateMachine Please note that this course isn't really meant for beginners. What I'm saying is you can expect a lot of struggle and bumps because this is aimed at intermediate users. Hope that helps nevertheless!

  • @is_game_maker

    @is_game_maker

    2 ай бұрын

    @onready var card_state_machine: CardStateMachine = $CardStateMachine as CardStateMachine func _ready() ->void: card_state_machine.init(self) ,,,,,, but still had Invalid call. Nonexistent function 'on_input' in base 'Nil'. @@godotgamelab

  • @is_game_maker

    @is_game_maker

    2 ай бұрын

    That's what I wrote, but it's still the same mistake as him.​@@godotgamelab