Hey everyone - I know that five videos is a lot to go through before we actually get to coding some of the main parts of our gameplay. I'm sorry for the slow start, but thanks for sticking with it, and I promise video 6 will kick off really diving into the gameplay. Enjoy!
@Azurantine813 жыл бұрын
Any semi-experienced programmer knows that the footwork has to be done before the fun stuff can come, sadly, people of varying skill levels and patience are sometimes unable to recognise this.
@WayFinder422 жыл бұрын
building blocks/stepping stones are the key to good learning!
@aaparky703911 ай бұрын
Sound approach matey. Coming from an enthusiast C, python and php background I actually appreciate this approach. For me the hardest part of Godot has simply been navigating the IDE so this series has been really well paced to help with that. Oh and also trying to work out the differences between Godot 3 and 4. Thanks for the valuable information!
@mgc8888 Жыл бұрын
In Godot 4, the "export" has been made an annotation. The line needs to be: "@export var max_lines_remembered := 30"
@bensdecoypoondummy1189 Жыл бұрын
Saved me again dude
@van.nevar47 Жыл бұрын
thanks bro
@corot92837 ай бұрын
Thanks!
@Creddiam5 ай бұрын
doing the lords work here
@mosh_dev5707 Жыл бұрын
In Godot 4, it seems like checking to see if the text is empty should use the function is_empty() instead of empty()
@jmbiv_dev10 ай бұрын
Thanks for providing a 4.x update!
@lspence8123 жыл бұрын
I love these tutorials and your explanations are perfect for Godot beginners like me. I did add to the if statement which prevents empty lines from being added though. I added an additional check so that the user could not just enter an empty space and have it accepted. My if condition is if new_text.empty() or new_text.begins_with(" "): return
@jmbiv_dev2 жыл бұрын
That's a great extra check to add, thanks for mentioning it! I'm sure others will find it helpful.
@hamzasibai1983 Жыл бұрын
I thought about a situation where the user accidently puts a space before typing out their response. In that case I updated my if condition to the following (Note: .empty() is now .is_empty() in Godot 4.0) : if new_text.is_empty(): return elif new_text.begins_with(" "): input_response.set_text(new_text, "Please don't start a command with a space.") history_rows.add_child(input_response) else: input_response.set_text(new_text, "This is where our response would go") history_rows.add_child(input_response) This way if someone types 'Kill monster' but with a space, they will still see their input, but will be asked to type it out again without the space.
@mgc8888 Жыл бұрын
@@hamzasibai1983 I'd rather recommend this: new_text = new_text.strip_edges() if not new_text.is_empty(): (...) This way, you avoid the unnecessary "return", as well as the user-unfriendly error messages, while accepting commands with or without spaces at the same time, and dropping "empty" whitespace ones, all in one go.
@frogfrogfrogd9 ай бұрын
@@mgc8888 works well! thank you
@jayciechance2 ай бұрын
this actually solved an issue I was running into! Thank you!!!
@ichorHomunculus10 ай бұрын
I'm one of those people who pivoted to Godot from Unity after their pricing fiasco and I feel like this series has been one of the better ones I've found to learn the basic principles of the engine. It's been an invaluable learning experience to follow along and convert everything you did into C# since I'm pretty new to programming in general, too! Thanks jmbiv!
@jmbiv_dev10 ай бұрын
That's awesome to hear! I hope it hasn't been too much of a challenge converting this into C# (and, probably also into 4.x since I made this series in Godot 3). If you ever need help along the way, drop a comment or join the Discord!
@dreamhollow2 жыл бұрын
I love how comprehensive this series is. I wouldn't even have thought of trying to free the previous actions and freeing up the memory. Thanks for this.
@jmbiv_dev2 жыл бұрын
So glad that the videos have been helpful for you!
@erniecooper4 ай бұрын
Thanks for this series. I'm watching/writing it the second time. Small challenge converting it to Godot 4 but not bad. My end goal is to make a game similair to 'Vagrus the riven realms'. Its mostly text, clicking on maps, simple combat scenes.
@tomasvicente7738 Жыл бұрын
Man, you must work as teacher of this. You explain sooo good and the content is didactic, great work !
@andrewpliakis12 күн бұрын
You can also add an if to give a clear screen functionality to the player. if new_text == "clear": for n in history_rows.get_children(): history_rows.remove_child(n) n.queue_free() Can also be tied to a button with signals, too.
@SWORDMA2 жыл бұрын
This series is awesome, thank you! I'm still really new to gamedev, but I've drawn a lot of knowledge and inspiration from your channel.
@jmbiv_dev2 жыл бұрын
That's great to hear! I'm really glad that these videos have been helpful - it's always encouraging to hear, so thanks for sharing. If you ever have a question or need some assistance as you're still learning game dev, we'd love to help out in the Discord server.
@DirtyDan71327 Жыл бұрын
I have been having a blast following along with this series so far! It has me really excited to finally be learning all of this.
@aboodispam3 жыл бұрын
These tutorials are extremely helpful thanks
@jmbiv_dev3 жыл бұрын
No problem! Glad you're finding them helpful.
@paulovitor1592 жыл бұрын
man this comment section is pure gold xD. Thank you for this great series. Help a lot
@jmbiv_dev2 жыл бұрын
Haha yea a lot of good stuff going on 😂 I'm so grateful that people reply/ask questions but I always end up writing an entire novel to answer, so I need to work on that. Glad the series has been helpful for you!
@MaliciousTachyons Жыл бұрын
Again, for new devs doing this in Godot 4.x, the export line is replaced by: @export var max_lines_remembered : int = 30
@joaorobalo75943 жыл бұрын
Isn't this unnecessarily complicated? I just did: if history_rows.get_child_count() > max_lines_remembered: history_rows.get_child(0).queue_free() This seems to work the same way, as after all, the if will always get triggered as soon as the max_lines_remembered is smaller than the amount of rows, so you really only need to remove the first one, which will always be at index 0, making the for loop and the creating of the "rows_to_forget" variable unnecessary. Am I missing some use case? Worked for me.
@jmbiv_dev3 жыл бұрын
Good question, thanks for your comment. Yes, your way works fine for how we've done lines so far and is a bit simpler than what we did in the video. The reason we did it a bit differently and used "rows_to_forget" is to handle the case where we might add multiple rows/children to our text history at the same time (rather than having an response scene that bundles the input and the response all into one "row"). However, we haven't actually done that yet, and I'm not sure we will, so your way is a great and simpler alternative! I just wanted to present something that would work automatically for multiple rows.
@joaorobalo75943 жыл бұрын
@@jmbiv_dev I figured you had a logical reason to go that route. Thanks for the explanation and good luck with the rest of the project, it's been very useful to me.
@jmbiv_dev3 жыл бұрын
@@joaorobalo7594 no problem, thanks for asking and including a simpler way. Glad to hear that you've found it helpful!
@ricpelo3 жыл бұрын
Thank you very much!
@jmbiv_dev3 жыл бұрын
No problem! Thanks for watching.
@The_Foreman2 жыл бұрын
If I had a dime for every time I got nullpointerexception because I deleted something in a list of some type and it shortened the length of list I was for looping through, I could have paid for a formal education. Queue free sounds like a god send.
@pompyproductions56442 жыл бұрын
jmbiv, thanks for the great series, really inspiring to go back to developing! ♪ though i must ask, wouldn't a while loop be better in the history_rows.get_child_count() statement? as in: (pseudocode) while current line count > max line count: queue free oldest line this still accounts for the possibility of having various lines pop up at once, right?
@jmbiv_dev2 жыл бұрын
No problem, glad that you're enjoying it! And yea, a while loop like you mentioned would also work and be a bit more concise. Whatever you prefer! I have a (somewhat irrational) avoidance of while loops whenever I can haha, but it would be a great option here.
@LSSTmusic Жыл бұрын
man there's enough differences in Godot 4 that it makes following this tutorial pretty frustrating at times.
@mosh_dev5707 Жыл бұрын
In Godot 4 export has been renamed to @export
@mosh_dev5707 Жыл бұрын
Also, it seems you no longer need to add (int)
@jmbiv_dev10 ай бұрын
That's correct! Like you mentioned, too, you no longer provide type hints in parentheses, but now in Godot 4.x you explicitly type the export variable itself. So, the new line should look like: @export var your_variable_name: int = 100 # replace 100 with whatever value you want
@mgc8888 Жыл бұрын
Here's a question -- what are the limits for the ScrollContainer if we do not implement history pruning? New devices (including mobile) have gigabytes of RAM, so a bit of text will never really fill it up; but do we run into some weird texture size limitations that lead to crashes or black boxes? I've had that problem with other frameworks, and it's quite frustrating since dealing with multiple platforms, they all have different ranges. If Godot can handle essentially "unlimited" here, it would be grand!
@jmbiv_dev Жыл бұрын
I think the limits here are probably higher than you’ll ever hit in a single game session, like you said. I’ve never pushed scrollcontainer super far, but Godot can definitely handle “unlimited” input even if some of it has to be taken out of the scroll container and stored elsewhere. What I would probably do instead of deleted old input is to just save it to a text file - that way, if the player ever needs or wants to look at old input, it’s on disk, but it doesn’t have to actually be saved in memory unless the player explicitly asks for it (for example, like a “view past messages” button the player can press to see input older than, say, 100 previous commands).
@mgc8888 Жыл бұрын
@jmbiv Thank you, that makes sense. I'm interested in this because I want to implement a sort of "history" in my app, where text is added from the bottom, but the user should always be able to get back to the beginning. I don't mind having to do some save/load of chuncks myself if needed, but if Godot could take care of that automatically and be only limited by RAM, it would save some effort (the best code is no code, after all ;) ). I was able to ascertain that ScollContainer inherits from CanvasItem, but there's nothing in the docs about the limits of that canvas. Other objects like Image have stated maximums of 16384x16384, thus my question...
@richard_aodell57092 жыл бұрын
Hi sorry I tried to comment in the correct video but.. in the game.gd (game script we used onready var history_rows .. then in func onready(): we have history_rows.add_child(input_responce) if we have say have a script on the carrot label could add a func _ready(): and then use history_rows.add_child(input_responce)
@jmbiv_dev2 жыл бұрын
I'm not sure I fully understand - are you asking whether you can call history_rows.add_child(...) within a script on your carot? If so, the answer is yes, but you'll have to get a reference to your HistoryRows node (which might mean calling get_parent(), which I would avoid unless you have to use it).
@yuli38732 жыл бұрын
I don't get any auto completion hints after writing "new_text.", why would that be? Thanks!
@jmbiv_dev2 жыл бұрын
It's most likely because it isn't typed. Wherever you declare "new_text" or other variables (I don't remember exactly where that comes from in this video), make sure to use the colon operator (:) to give it a type, either implicitly or explicitly (like "var new_text: String = "..."). Hopefully that helps!
@tuckertcs2 жыл бұрын
at 8:30 you can simplify the code by doing: while history_rows.get_child_count() > max_lines_remembered: history_rows.get_child().queue_free()
@northbound6937 Жыл бұрын
When I try your suggested implementation, it expects me to add an index input to the get_child() call. I tried also to always free the first child 'get_child(0)', but it hangs my game after I submit more lines than max_lines_remembered. Any insight on how to solve this? Thanks Edit: for those stuck on this, another commenter posted a working implementation: if history_rows.get_child_count() > max_lines_remembered: history_rows.get_child(0).queue_free()
@YammoYammamoto11 ай бұрын
export has been changed to @export. I.e @export var max_lines_remembered := 30