To the top of my favorite Godot tutorials. I'm not trying to make my games faster, I just want to learn C++ creating a game using Godot, and this video solves the most tedious part of learning a new programming language: set up everything. Thanks a lot!
Update for anyone doing this now (3/31/2021): 1. *Problem:* Compiling gdnative_cpp_example gives the following error... _fatal error C1083: Cannot open include file: 'gdnative_api_struct.gen.h': No such file or directory_ *Solution:* Try updating the godot_headers_path in SConstruct to *"../godot-cpp/godot-headers/"* rather than "../godot-cpp/godot_headers/" (dash rather than underscore), if they haven't fixed it by the time you read this 2. *Problem:* Visual Studio still can't find all godot headers after adding include paths... _E1696 cannot open source file "core/CoreTypes.hpp"_ *Solution:* Try adding *..\..\godot-cpp\include* to your include paths as well
UPDATE: As a few people have pointed out, you'll need to rename godot-headers to godot_headers; that was changed in the godot-cpp repository after this tutorial was made. A few other notes: 1. Using entire namespaces as I have (i.e. "using namespace godot;") is risky, and I probably shouldn't have done it in a tutorial. Godot could, for example, add classes that have naming conflicts with my own. As a solo developer aware of this risk, it's easy enough for me to catch and fix such a problem if it arises, but this could be a nightmare for open source or team projects. 2. I forgot to actually use the mine_texture property. If you wanted to apply it to the Mines MultiMeshInstance2D you could add the following to Level::_ready(): mines_node->set_texture(mine_texture); 3. I forgot to mention that you can get or set properties of your GDScript objects by name with the get/set methods on the C++ side; i.e.: hud->set("subs", (int) hud->get("subs") - 1); (However, as-is the number of subs left is updated by calling "sub_destroyed".) 4. The break I added when a mine is destroyed has no noticeable impact on performance because explosions are infrequent; it will not affect most frames. 5. I've pushed an "end-of-tutorial" branch to GitHub with the project as seen at the end of the video, so you can examine a working GDNative example more closely. 6. Sorry about the inconsistent voiceover quality - I had to re-dub parts during editing, and I just didn't have the patience to re-record everything to match better. 7. If you're having trouble reading the code, make sure you're viewing the video in 1080p quality.
You should really put the hypen to underscore change in the description, cause I think that'll catch a lot of people out who don't scroll down. Great tutorial otherwise.
Fantastic work. I appreciate the reasonable line you walk, warning people up front about topics you won't be covering and explaining that steps would be different on a different platform, etc. Your terse and efficient speech helps those of us with engineering minds to avoid distracting details that aren't on the critical path toward the end result. Thanks for your what you've done!
@5:00 If SCons gives you the Error: "'cl' is not recognized as an internal or external command, operable program or batch file. scons: *** [src\gdexample.obj] Error 1 scons: building terminated because of errors." This will happen if you open just a vanilla command prompt. The **Native Tools Command Prompt** you need is part of Visual Studio and can be found in the Start Menu: Start->Visual Studio 2019 -> x64 Native Tools Command Prompt for VS 2019 Good luck everyone!
Thank you! Thank you! Thank you! This is the best GDScript tutorial I've seen. Your pacing is spot on, the structure is very clear and you even added "progress bars" haha. You got yourself a new sub mate :)
This was all i needed thank you so much. I've never used visualStudioCode as I've only ever developed for linux servers and maybe used a linux env on windows. So thank you very much
At the moment I'm making a Game with a generated universe. I really hope the Gdscript will be performant enough but if it isn't I now know how to make it in C++.
In game development it's often necessary to cut corners and find ways to get the result you want with less computation. If you're trying to simulate a huge numbers of objects every single frame, GDScript will probably be too slow. But if you can simulate only nearby objects and do some less-frequent updates on the rest of the universe, you might be fine. It just takes some time to think and experiment.
This is why GM:S or Unreal Engine is still somehow 'better' in terms of user-friendly. They automatically converts their own proprietary programming language (GML for GameMaker, and Blueprint for Unreal) to C++ seamlessly and with good performance. If Godot can take this advantage, it will likely dominates the game development industry in terms of performance, and compete with many others.
@@robbertzzzzz I mean, I need UE to give me some cpp code which is equivalent to some blueprint. This seems not possible unless I do it manually. Anyway, blueprint works well enough for me. If it's not possible, it's still ok. Btw, do you use va or resharper or anything else?
GDNative and the ability to use c++/c is tremendous in Godot! I was doing a simple fill operation on a 600x600 cell TileMap, and that took like 40 seconds. With GDNative/c++ it took less than a second! You probably have gone over this in a previous video, but did you ever consider using C#? If I recall correctly it's in the middle in terms of performance (as in order of magnitude in the middle if that makes sense). Oh, and contrats on 10k subs!! Heres hoping for 100k sometime soon!
Thoughtquake, I feel cSharp is a great middle ground for game development its verbose enough without being c++ (or worse, java) while still being more performant than GDscript. The syntax is very easy to understand and oop is almost required ( see that as you will ) CSharp’s biggest problem is that it has something called the Just In Time compiler (JIT) which it pretty good for everything but game development. Something unity is trying to mitigate with their ‘version’ of cSharp. There is also this language called beef (beeflang.org), developed by an ex ( either ea or popcap, can’t remember :/ ) employee, that can be described as the best of cSharp and c++ combined without the previous mentioned performance issue. You can also look into monogame (monogame.net), an open-source implementation of the Microsoft Xna Framework. Its what I prefer, and is used by games such as Stardew Valley, Axiom Verge, Celeste and, although made with xna and not monogame, Terraria. ( I realize all of those are 2d, monogame can do 3d too )
C# can be pretty close to C++, MSCLR is pretty fast and expressive as an intermediary and it remembers optimizations over multiple runs, but it will never be as fast as native (of course). It's probably better to just stick to one since they can end up being quite similar these days.
Great video! You said a lot of interesting stuff of which others prefer not to talk and this is cool! I wish I saw this video earlier, because it is such a pain, figuring out all this minor details yourself. By this time I've already done all setup, but I did it in a different way. Instead of using scons every time for compiling project, I used it once to generate CMake project in which I set up all I need for the C++ project (things like C++ standard, libraries, dependencies, included, etc.) and than use it for generating my Visual Studio project. I also made Visual Studio replace my GDNative library after successful compilation. This way I can switch from Godot to Visual Studio, make some changes, compile (using Visual Studio), switch back to Godot and start game for testing changes. About what you said at 24:13 about mixed results with variadic function "call". I don't see how it could work differently because under the hood it does exactly what you've been doing in the video -- creates Array and appends it. I guess it might be because of some overloads of this function, but I'm not sure
I suspect there's a bug or undocumented behavior where if one of the arguments is an array it tries to expand it to separate arguments... or something. I haven't spent enough time looking into to say for sure, since it's pretty easy to work around.
Thanks so much for this video! I've been looking for an example of GDNative C++ with a 3D game, and the graphics do look 3D to me (unless I'm mistaken).
UA-camr Feedback: Don't apologize for mistakes ahead of time, as it only serves to undermine your own authority over Godot Engine. It is perfectly fine to be wrong at times and to admit so after you have been proven wrong, but don't pre-ignite it. :)
This GDNative thingy looks 10x harder than Gdscript. As a beginner, I don't understand every single line of codes you typed in this video and makes me reconsider my game dev hobby. I've done the basic c++ just fine, but applying it to the game development like Godot feels like an entire different language :(
Alfian's Dump If you don't need C++ for performance reasons you might actually find it easier to learn GDScript than to use C++ with Godot. There are also other engines that might make it easier to wrap your head around the game specific concepts. Please don't give up because of how complicated this specific approach is
@@Thoughtquake One may want to choose to use GDNative or engine modules for reasons other than performance. Not everything can be done in GDScript. In my project, I have to implement a certain fraction of it in C++, because I need to use some external libraries and because GDScript doesn't support double precision floating point numbers (which I need in my project).
Brilliant tutorial :D Truly one of the best on Godot C++, seriously. I do have a questions though: How would you go about using breakpoints on visual studio to debug the code? I notice that Godot detaches the process once it launches a new project from the initial compiled engine.
Thanks! Godot is FOSS, but are you asking if I'm open-sourcing my games? I'm currently planning to sell them on Steam, because I don't think I can make a living from Patreon/donations alone.
I just realized you probably meant for the music, in which case I'm not. Most of my music has been made in Reason, but I've recently switched to Studio One.
If you're curious about comparing performance between C++ and C# in Godot, here are some benchmarks. Unsurprisingly, C++ yields far better performance than C#: www.royaldonut.games/2019/03/29/cpu-voxel-benchmarks-of-most-popular-languages-in-godot/ github.com/cart/godot3-bunnymark
If you are getting linking errors, even though everything is set up correctly, make sure to use the 64 bit version of the build tool. I by accident used the 32 bit version and that does not work
trying to create a defenition for _register_methods(); is giving me the error "the selected text does not contain any function signatures". But trying to do it on _init(); works fine.
this is really complicated. i wanted to learn C++ with my own projects but i don't have a single clue on whats going on. should i be learning C++ with Godot or should i just not bother with Godot? do i need to set this all up every time i want to make a new project? is there something i can watch to fully understand what is going on?
@@notlineeydupppz43 i figured, i was going in with the thought that it would be similar to other languages but boy was i wrong. maybe I'll come back to this once I'm a bit more experienced.
Great tutorial! A few questions though. 1) How would you target the GDNative to another platform (such as android). Would the command line argument in scons automatically compile your custom C++ for the given platform? Or would you have to do more work to support other platforms? 2) Could you do a video discussing debugging GDNative script? You showed how to generate the PDB, but how would you go about debugging it? Typically I would using the debug feature built into MSVC, however, since you are creating a library that's being called by Godot, it's not clear to me how the two would integrate.
1. So far I've only built for OSX and Windows, but for OSX it's as simple as using "platform=osx" on the command line. 2. Tutorial videos like this take a long time to make so probably not. However, to answer your question about debugging: Just attach the debugger to the Godot.exe process for your running game; just make sure you're not attaching to the editor's process. Also, if it crashes and you have JIT debugging on, you can attach Visual Studio that way.
Could you upload the complete project (after you migrated to C++ from Gdscript) for Visual Studio 2017 or 2019 community edition. That way it is easier for me as a template for my own game. I dont see the project in your listing. Thanks.
Why does none of this make any sense? Can somebody advise me where I can start to actually comprehend this whole meta-programming thing. Like, I've been using Godot for a number of months now and feel really quite comfortable with it, GDScript is super easy now, etc. I have also used C and C++ before, but something about this, like, wtf? xD
Avoiding broken references is a common problem for programming in general, and there are many ways to approach it. In general, I recommend making sure you can account for all references to an object that might be deleted so you can clear those references when it is deleted. For example, you might keep a list of everything that can hold a reference to destroyable game objects, and call a "notify_removal" method on each of them before deleting a game object. Then, the "notify_removal" method can just check for any references to the object being deleted and remove them.
I feel like maybe making a kind of wrapper class that always automatically accounts for it to be able to request the deletion on this wrapper class to make sure it affects all the others might be a good idea
@@SeleDreams I did something similar for my first game - I basically had bi-directional references that can be invalidated on both ends when either side is destroyed. It definitely can be done, but it's not always the simplest approach
@@Thoughtquake I thought about implementing it by having a static std::map that would use the pointer as the key then a struct containing a bool defining if it's been destroyed or not and an int increasing if in a rare case, a valid node ends up instantiated on this same address to make the address valid again but keep the older ones invalid
I got the same thing and it seems like the problem is that you try to download the repository via Git Bash with command _git clone _ , which clones the *master* branch, not the one you've been looking at while copying the link. Why this matters? I don't know but it seems like current *master* branch is missing some of the files you might need. To download the specific branch use _git clone -b _
@Thoughtquake Hey, I see you're using `$Node` in you code in per-frame calls, even in loops in per-frame calls. $Node is a short-hand for get_node(), which is a rather expensive call. I suggest only calling get_node once and save the ref into a script variable. This way you have the get_node overhead just once on ready, and not multiple times each frame. that's precisely what the onready keyword is for. `onready var mine = $Mine` then you can replace all your `$Mine` occurences in the code. that should already give you a slight performance increase.
another tip: when building, you can use `-jX` as additional flag to assign more than one thread for building. I have a 6 core with 12 threads, so I add `-j12`. Building then takes minutes rather than hours. ^^
That was just a bit of laziness on my part - it may be expensive in the context of high-frequency operations, but a few node lookups per frame won't make a perceivable difference. As a test I tried calling get_node 10,000 times per frame with a path 3 levels down in the hierarchy, and the total time per frame averages about 17ms. So, that's about 1.7 microseconds per get_node call.
@@gravitategames1500 I know it's late, but I just solved it!!! Make sure your "godot-headers" file is populated BEFORE!! You build godot-cpp!!! My version of godot-cpp had an empty "godot-headers" file by default, and I had to download the headers and paste them in. If godot-headers is empty when you build, then the gen folder will not be populated and you wont get "sprite.hpp" as well as all the other node headers. So in summary: -clone godot-cpp -Paste in godot-headers contents (if godot-headers is empty) -BUILD godot-cpp, this will populate your include/gen folder -be happy :) Leaving this here in case it helps anyone else in the future
I have the following error: can someone help me? :s C:\users\minix\gdnative_cpp_example-master\src\gdexample.h(4): fatal error C1083: Cannot open include file: 'Godot.hpp': No such file or directory scons: *** [src\gdexample.obj] Error 2 scons: building terminated because of errors.
Sounds like the godot_headers vs godot-headers rename; you'll need to update this path in the SConstruct file. (They changed the name of the directory after I made this tutorial)
@@samuraikina5908 Sorry, taking another look, I see that Godot.hpp should be in the main godot-cpp repository and not the headers submodule. Do you have the file under include/core?
I would love to keep up with the video but next time please make simple example. I only managed to watched half of the video until I became fatigued or exhausted. Great tutorial tho.
Yes, if you're using Visual Studio you can either attach to the process while your game is running and set breakpoints then, or if you dig through the project settings you can configure it to run your project under the debugger when you hit F5. However, if you are also using GDScript you'll need to debug that separately; I don't know of a good way to observe the interactions between the two.
Does anyone else have an error: "LINK : error LNK2001: unresolved external symbol -DllMainCRTStartup" I've spent hours trying to figure this out and I'm at my wits end. I see solutions online but I don't know how to apply them to SConstruct Edit: It does work with the example project though. Something with visual studio? I ended up just modifying the example project
"using namespace" is a pretty terrible thing to do, especially in header files. If godot adds something to their namespace that happens to also be in std or your own namespace and you're "using" all of them, it's almost impossible to know which will be called since it's implementation dependent. For example, if Godot were to add their own "Level" class, some or all of the instances of you referencing your own class could be interpreted as being godot::Level instead, since you're using their namespace globally.
You make a good point. I take this shortcut to save me time, because in most cases this would be easy to catch and address if/when it becomes a problem. Most compilers treat ambiguous symbols as an error, and even in circumstances where that might not happen there would likely be build-breaking mismatches. That said, it's probably a bad idea to do what I did in a tutorial without very clear cautions at the least. I'll try to remember to change this when I eventually update/replace this tutorial.
If you really need to save the characters, instead of `using namespace godot`, I'd recommend namespace aliasing with `namespace gd=godot`. I use it all the time for the absurdly long paths in `std::chrono` since it saves you time and makes the code more readable while keeping namespace safety.
And it's definitely not as big of a problem in smaller projects. I'm used to working in projects with tens or hundreds of thousands of lines across dozens or hundreds of files, so it's not reasonable to just be aware of any potential ambiguity across every library and every function call.
I personally enjoy GNU/Linux more but I can understand that some people might want to stick to MS Windows due to software compatibility (I can run quite an amount of Windows software with Wine, though).
With GDNative you are talking in the same language as the engine itself and you are extending it with code. C# by itself is less performant than C++ but it's also used as a scripting language, meaning you don't talk with the engine directly but through translation. All of that has some impact ONLY if you have a heavy logic case.
@@NeZversSounds I moved to C# from gdscript because I dont think I will be able to learn C++ in a million years. I think the diff between C++ and C# in Godot is minimal so I think it should be good enough.
Nevermind did it using: "includePath": [ "${workspaceFolder}/**", "${workspaceFolder}/../godot-cpp/include/**", "${workspaceFolder}/../godot-cpp/godot_headers/**" ], Not sure the headers folder is correct though
It should be possible, but I haven't tried it. You can have limited per-instance custom data that could be used to select the frame, and a custom shader could determine the UV coordinates using that frame number.
@@kidmosey Not sure why I gave that comment. I am sure I had some reasoning behind it, but I can't remember what it was. C++ should be used when needed, but should not be used when not needed.
@@kidmosey >have you tried to read through the STL I'll admit, I've never read through the entire thing, but it is *possible* to read. Even so, this point cannot be a valid argument because you don't have to read through the STL to use it in a C++ program. You are not the compiler. >Add to that the fact that half of the features in the STL are designed around resolving a tedious memory model or other language deficiencies I'm not sure where you got this from, but you seem to be saying things you don't completely understand. C++11 introduced a standard memory model (regardless of platform or compiler backend) that effectively voids whatever argument was in here, not that there was any argument. If you're not improperly locking a value that you write to, there's nothing to even worry about; the behavior will be the same no matter what even in the land of C++98 (no-man's land.). Besides, the same tediousness will occur no matter what native language you pick, and if you're going to complain about it, maybe you're better off in the land of Java or C# where you "don't have to worry about it" and you get to prance around and say that VM-based languages are the future when they're clearly not and never will be. >C++ is a hard sell to anyone who hasn't been using it for 20+ years. Correction: C++ is a hard sell to **you**. A large chunk of commercial applications that are native use it and aren't going to take the effort to switch overnight to some meme-tier language that's relatively unknown just for muh memory safety, so it's never going to "die" per se, no matter how much you wish it to.
Sure, you could do everything from scratch in C++, but using an engine like Godot saves a ton of time. It gives you a cross-platform graphics engine, physics, audio, and lots more. For most people, I think it's a huge advantage to have all that pre-built and already tested by other people, regardless of what language you use to drive it.
@@cristianinujazznight3044 I used an older version of SDL long ago, but not SDL2. An engine like Godot just does a lot more of the work for you; i.e. you get a collection of useful UI components you can arrange and customize in a visual editor, a well-designed object hierarchy and scene manager, 2D and 3D physics engines, a cross-platform threading solution, etc. You could probably find open source solutions for all of these things elsewhere and piece them together yourself, but that takes more time. And if you're not procedurally generating everything you probably need an editor of some kind for building levels/environments unless you're really determined to do things the hard way. Having one built into the engine makes things way simpler.
To the top of my favorite Godot tutorials. I'm not trying to make my games faster, I just want to learn C++ creating a game using Godot, and this video solves the most tedious part of learning a new programming language: set up everything. Thanks a lot!
Update for anyone doing this now (3/31/2021):
1. *Problem:*
Compiling gdnative_cpp_example gives the following error...
_fatal error C1083: Cannot open include file: 'gdnative_api_struct.gen.h': No such file or directory_
*Solution:*
Try updating the godot_headers_path in SConstruct to *"../godot-cpp/godot-headers/"* rather than "../godot-cpp/godot_headers/" (dash rather than underscore), if they haven't fixed it by the time you read this
2. *Problem:*
Visual Studio still can't find all godot headers after adding include paths...
_E1696 cannot open source file "core/CoreTypes.hpp"_
*Solution:*
Try adding *..\..\godot-cpp\include* to your include paths as well
Thanks for sharing this! I wish I could pin multiple comments.
Thank you!
Thanks, Brother
Thanks!!
UPDATE: As a few people have pointed out, you'll need to rename godot-headers to godot_headers; that was changed in the godot-cpp repository after this tutorial was made.
A few other notes:
1. Using entire namespaces as I have (i.e. "using namespace godot;") is risky, and I probably shouldn't have done it in a tutorial. Godot could, for example, add classes that have naming conflicts with my own. As a solo developer aware of this risk, it's easy enough for me to catch and fix such a problem if it arises, but this could be a nightmare for open source or team projects.
2. I forgot to actually use the mine_texture property. If you wanted to apply it to the Mines MultiMeshInstance2D you could add the following to Level::_ready():
mines_node->set_texture(mine_texture);
3. I forgot to mention that you can get or set properties of your GDScript objects by name with the get/set methods on the C++ side; i.e.:
hud->set("subs", (int) hud->get("subs") - 1);
(However, as-is the number of subs left is updated by calling "sub_destroyed".)
4. The break I added when a mine is destroyed has no noticeable impact on performance because explosions are infrequent; it will not affect most frames.
5. I've pushed an "end-of-tutorial" branch to GitHub with the project as seen at the end of the video, so you can examine a working GDNative example more closely.
6. Sorry about the inconsistent voiceover quality - I had to re-dub parts during editing, and I just didn't have the patience to re-record everything to match better.
7. If you're having trouble reading the code, make sure you're viewing the video in 1080p quality.
You should really put the hypen to underscore change in the description, cause I think that'll catch a lot of people out who don't scroll down.
Great tutorial otherwise.
Ten Thousand Subs... well that took some time to "sink in" 😅
You... I like your style
Fantastic work. I appreciate the reasonable line you walk, warning people up front about topics you won't be covering and explaining that steps would be different on a different platform, etc. Your terse and efficient speech helps those of us with engineering minds to avoid distracting details that aren't on the critical path toward the end result. Thanks for your what you've done!
@5:00 If SCons gives you the Error:
"'cl' is not recognized as an internal or external command,
operable program or batch file.
scons: *** [src\gdexample.obj] Error 1
scons: building terminated because of errors."
This will happen if you open just a vanilla command prompt.
The **Native Tools Command Prompt** you need is part of Visual Studio and can be found in the Start Menu:
Start->Visual Studio 2019 -> x64 Native Tools Command Prompt for VS 2019
Good luck everyone!
This comment is literally a lifesaver. thank you so much. I really could not understand why cl.exe existed but could not be called!
Thanks a lot for this. I was looking for a comment that would solve my problem. Thanks again.
Thank you! Thank you! Thank you! This is the best GDScript tutorial I've seen. Your pacing is spot on, the structure is very clear and you even added "progress bars" haha. You got yourself a new sub mate :)
this is the best tutorial for learning how to use gdnative, thanks to your help, I was able to setup my 100 000 cell real time simulation. Thank you!
Disturbed - Ten Thousand Subs. Thanks for the great video!
I really can't thank you enough for this tutorial. I must have watched it 20+ times while working on my own GDNative code!
This was all i needed thank you so much. I've never used visualStudioCode as I've only ever developed for linux servers and maybe used a linux env on windows. So thank you very much
At the moment I'm making a Game with a generated universe. I really hope the Gdscript will be performant enough but if it isn't I now know how to make it in C++.
In game development it's often necessary to cut corners and find ways to get the result you want with less computation. If you're trying to simulate a huge numbers of objects every single frame, GDScript will probably be too slow. But if you can simulate only nearby objects and do some less-frequent updates on the rest of the universe, you might be fine. It just takes some time to think and experiment.
If they could make ELITE for the C64, with a procedural generated universe, than you can do it with GDScript on a modern PC. ;)
great tutorial, also love the music :)
Thanks alot! Very nice and clear tutorial on a rather complex issue.
This is why GM:S or Unreal Engine is still somehow 'better' in terms of user-friendly. They automatically converts their own proprietary programming language (GML for GameMaker, and Blueprint for Unreal) to C++ seamlessly and with good performance. If Godot can take this advantage, it will likely dominates the game development industry in terms of performance, and compete with many others.
How to convert blueprint into c++ automatically? Thanks. I've searching for this for a while and didn't get anything useful.
@@hanyanglee9018 it happens automatically, you don't need anything to make it work. That's just how Unreal's blueprints work.
@@robbertzzzzz I mean, I need UE to give me some cpp code which is equivalent to some blueprint. This seems not possible unless I do it manually. Anyway, blueprint works well enough for me. If it's not possible, it's still ok. Btw, do you use va or resharper or anything else?
What a wonderful GDNative tutorial...thank you!
GDNative and the ability to use c++/c is tremendous in Godot! I was doing a simple fill operation on a 600x600 cell TileMap, and that took like 40 seconds. With GDNative/c++ it took less than a second! You probably have gone over this in a previous video, but did you ever consider using C#? If I recall correctly it's in the middle in terms of performance (as in order of magnitude in the middle if that makes sense). Oh, and contrats on 10k subs!! Heres hoping for 100k sometime soon!
Thanks! I haven't tried the C# integration yet because I'm less familiar with the language and I just haven't had a good reason to.
Thoughtquake, I feel cSharp is a great middle ground for game development its verbose enough without being c++ (or worse, java) while still being more performant than GDscript. The syntax is very easy to understand and oop is almost required ( see that as you will )
CSharp’s biggest problem is that it has something called the Just In Time compiler (JIT) which it pretty good for everything but game development. Something unity is trying to mitigate with their ‘version’ of cSharp.
There is also this language called beef (beeflang.org), developed by an ex ( either ea or popcap, can’t remember :/ ) employee, that can be described as the best of cSharp and c++ combined without the previous mentioned performance issue.
You can also look into monogame (monogame.net), an open-source implementation of the Microsoft Xna Framework. Its what I prefer, and is used by games such as Stardew Valley, Axiom Verge, Celeste and, although made with xna and not monogame, Terraria. ( I realize all of those are 2d, monogame can do 3d too )
C# can be pretty close to C++, MSCLR is pretty fast and expressive as an intermediary and it remembers optimizations over multiple runs, but it will never be as fast as native (of course). It's probably better to just stick to one since they can end up being quite similar these days.
Great video! You said a lot of interesting stuff of which others prefer not to talk and this is cool!
I wish I saw this video earlier, because it is such a pain, figuring out all this minor details yourself.
By this time I've already done all setup, but I did it in a different way. Instead of using scons every time for compiling project, I used it once to generate CMake project in which I set up all I need for the C++ project (things like C++ standard, libraries, dependencies, included, etc.) and than use it for generating my Visual Studio project. I also made Visual Studio replace my GDNative library after successful compilation. This way I can switch from Godot to Visual Studio, make some changes, compile (using Visual Studio), switch back to Godot and start game for testing changes.
About what you said at 24:13 about mixed results with variadic function "call". I don't see how it could work differently because under the hood it does exactly what you've been doing in the video -- creates Array and appends it. I guess it might be because of some overloads of this function, but I'm not sure
I suspect there's a bug or undocumented behavior where if one of the arguments is an array it tries to expand it to separate arguments... or something. I haven't spent enough time looking into to say for sure, since it's pretty easy to work around.
great stuff! we need more tutorial like this.
the thing I've been looing for all the time. thank you sir.
Thanks. Excellent succinct tutorial with example. Appreciated.
Thanks so much for this video! I've been looking for an example of GDNative C++ with a 3D game, and the graphics do look 3D to me (unless I'm mistaken).
Thanks for this great tutorial! Now to figure out how to build directly from VS...
Great, would like to see updates for newer versions of #Godot and generally more tuts on #cpp!
UA-camr Feedback: Don't apologize for mistakes ahead of time, as it only serves to undermine your own authority over Godot Engine. It is perfectly fine to be wrong at times and to admit so after you have been proven wrong, but don't pre-ignite it. :)
Invaluable resource. Pinned as a permanent reference.
just learning GDNative with Rust yesterday, and C++ version is harder, I think? Because Rust already has Cargo that makes the process easier
Awesome demonstration!
GDNative is the GDExtention for anyone wondering. the same things, just different names
This GDNative thingy looks 10x harder than Gdscript. As a beginner, I don't understand every single line of codes you typed in this video and makes me reconsider my game dev hobby. I've done the basic c++ just fine, but applying it to the game development like Godot feels like an entire different language :(
Alfian's Dump If you don't need C++ for performance reasons you might actually find it easier to learn GDScript than to use C++ with Godot. There are also other engines that might make it easier to wrap your head around the game specific concepts. Please don't give up because of how complicated this specific approach is
@@Thoughtquake I need to start using c++ because my recent game has similar issues to yours and GDscript doesn't help the performance get any better.
@@Thoughtquake One may want to choose to use GDNative or engine modules for reasons other than performance. Not everything can be done in GDScript. In my project, I have to implement a certain fraction of it in C++, because I need to use some external libraries and because GDScript doesn't support double precision floating point numbers (which I need in my project).
@@festerdam4548 Very good points!
视频非常帮!感谢!!
GDScript: My name is GDScript! I am artist! I am perfomance artist!
C++: I show you Who is boss of the Gym!
Brilliant tutorial :D Truly one of the best on Godot C++, seriously. I do have a questions though: How would you go about using breakpoints on visual studio to debug the code? I notice that Godot detaches the process once it launches a new project from the initial compiled engine.
This is fantastic. Thanks!
Dude, I love the background music so much! Area you by any means using FOSS for your work?
Thanks! Godot is FOSS, but are you asking if I'm open-sourcing my games? I'm currently planning to sell them on Steam, because I don't think I can make a living from Patreon/donations alone.
I just realized you probably meant for the music, in which case I'm not. Most of my music has been made in Reason, but I've recently switched to Studio One.
Thank you so much!
I would like to see two things, first the FPS displayed, to see how fast it really is, and please port to C# to see how fast it will be.
If you're curious about comparing performance between C++ and C# in Godot, here are some benchmarks. Unsurprisingly, C++ yields far better performance than C#:
www.royaldonut.games/2019/03/29/cpu-voxel-benchmarks-of-most-popular-languages-in-godot/
github.com/cart/godot3-bunnymark
If you are getting linking errors, even though everything is set up correctly, make sure to use the 64 bit version of the build tool. I by accident used the 32 bit version and that does not work
trying to create a defenition for _register_methods(); is giving me the error "the selected text does not contain any function signatures". But trying to do it on _init(); works fine.
Did you ever solve the issue?
How you make the bottom bar?
Great video!
idk what's wrong but it keeps erroring saying that "cl" isn't a command
3:28 The absolute bare minimum here is MSVC and Windows 10 SDK
when i try to use the rng in one of my own functions the godot game instantly closes. Any way to solve this issue?
this is really complicated. i wanted to learn C++ with my own projects but i don't have a single clue on whats going on.
should i be learning C++ with Godot or should i just not bother with Godot?
do i need to set this all up every time i want to make a new project?
is there something i can watch to fully understand what is going on?
ngl sir. learning c++ is a long long way.
@@notlineeydupppz43 i figured, i was going in with the thought that it would be similar to other languages but boy was i wrong.
maybe I'll come back to this once I'm a bit more experienced.
Great tutorial! A few questions though.
1) How would you target the GDNative to another platform (such as android). Would the command line argument in scons automatically compile your custom C++ for the given platform? Or would you have to do more work to support other platforms?
2) Could you do a video discussing debugging GDNative script? You showed how to generate the PDB, but how would you go about debugging it? Typically I would using the debug feature built into MSVC, however, since you are creating a library that's being called by Godot, it's not clear to me how the two would integrate.
1. So far I've only built for OSX and Windows, but for OSX it's as simple as using "platform=osx" on the command line.
2. Tutorial videos like this take a long time to make so probably not. However, to answer your question about debugging: Just attach the debugger to the Godot.exe process for your running game; just make sure you're not attaching to the editor's process. Also, if it crashes and you have JIT debugging on, you can attach Visual Studio that way.
AMAZING VIDEO GOOD TUNES TO
I don't what's wrong but I'm getting only 5 fps more after building done. It's 7 fps using C++, 2 fps using GDscript
OK,I've copied your code and now it's working fine.Look like something is messed up by me in Level.cpp
Could you upload the complete project (after you migrated to C++ from Gdscript) for Visual Studio 2017 or 2019 community edition. That way it is easier for me as a template for my own game. I dont see the project in your listing. Thanks.
Why does none of this make any sense? Can somebody advise me where I can start to actually comprehend this whole meta-programming thing. Like, I've been using Godot for a number of months now and feel really quite comfortable with it, GDScript is super easy now, etc. I have also used C and C++ before, but something about this, like, wtf? xD
Can you please update the tutorial for GDExtension ?
how do you handle cases where a referenced node would get deleted ?
Avoiding broken references is a common problem for programming in general, and there are many ways to approach it. In general, I recommend making sure you can account for all references to an object that might be deleted so you can clear those references when it is deleted. For example, you might keep a list of everything that can hold a reference to destroyable game objects, and call a "notify_removal" method on each of them before deleting a game object. Then, the "notify_removal" method can just check for any references to the object being deleted and remove them.
I feel like maybe making a kind of wrapper class that always automatically accounts for it to be able to request the deletion on this wrapper class to make sure it affects all the others might be a good idea
it would this way be easily reusable
@@SeleDreams I did something similar for my first game - I basically had bi-directional references that can be invalidated on both ends when either side is destroyed. It definitely can be done, but it's not always the simplest approach
@@Thoughtquake I thought about implementing it by having a static std::map that would use the pointer as the key then a struct containing a bool defining if it's been destroyed or not and an int increasing if in a rare case, a valid node ends up instantiated on this same address to make the address valid again but keep the older ones invalid
GODOT_CLASS causes some warnings for me, as well as godot_gdnative_init_options. Everything else works
5:07 when I try to do the same, I get an error "can't find godot.hpp path" every time
I got the same thing and it seems like the problem is that you try to download the repository via Git Bash with command _git clone _ , which clones the *master* branch, not the one you've been looking at while copying the link. Why this matters? I don't know but it seems like current *master* branch is missing some of the files you might need. To download the specific branch use _git clone -b _
@Thoughtquake Hey, I see you're using `$Node` in you code in per-frame calls, even in loops in per-frame calls.
$Node is a short-hand for get_node(), which is a rather expensive call.
I suggest only calling get_node once and save the ref into a script variable. This way you have the get_node overhead just once on ready, and not multiple times each frame.
that's precisely what the onready keyword is for.
`onready var mine = $Mine`
then you can replace all your `$Mine` occurences in the code. that should already give you a slight performance increase.
another tip: when building, you can use `-jX` as additional flag to assign more than one thread for building.
I have a 6 core with 12 threads, so I add `-j12`. Building then takes minutes rather than hours. ^^
That was just a bit of laziness on my part - it may be expensive in the context of high-frequency operations, but a few node lookups per frame won't make a perceivable difference. As a test I tried calling get_node 10,000 times per frame with a path 3 levels down in the hierarchy, and the total time per frame averages about 17ms. So, that's about 1.7 microseconds per get_node call.
It's showing Sconstruct error
I have the following error: can someone help me?
fatal error C1083: 无法打开包括文件: “Sprite.hpp”: No such file or directory
gdnative_cpp_example-master\src\gdexample.h(5): fatal error C1083: 无法打开包括文件: “Sprite.hpp”: No such file or directory
have already solved
@@nimahe9224 I have the same error. How did you solve this?
@@gravitategames1500 I know it's late, but I just solved it!!!
Make sure your "godot-headers" file is populated BEFORE!! You build godot-cpp!!!
My version of godot-cpp had an empty "godot-headers" file by default, and I had to download the headers and paste them in.
If godot-headers is empty when you build, then the gen folder will not be populated and you wont get "sprite.hpp" as well as all the other node headers.
So in summary:
-clone godot-cpp
-Paste in godot-headers contents (if godot-headers is empty)
-BUILD godot-cpp, this will populate your include/gen folder
-be happy :)
Leaving this here in case it helps anyone else in the future
I have the following error: can someone help me? :s
C:\users\minix\gdnative_cpp_example-master\src\gdexample.h(4): fatal error C1083: Cannot open include file: 'Godot.hpp': No such file or directory
scons: *** [src\gdexample.obj] Error 2
scons: building terminated because of errors.
Sounds like the godot_headers vs godot-headers rename; you'll need to update this path in the SConstruct file. (They changed the name of the directory after I made this tutorial)
@@Thoughtquake i tryed that with underscore and also using dash still gave an error and couldnt build
@@samuraikina5908 Sorry, taking another look, I see that Godot.hpp should be in the main godot-cpp repository and not the headers submodule. Do you have the file under include/core?
@@Thoughtquake its ok, ill try again
Nice video, thanks for the share. would be interested to see a RUST one if you happen to know RUST.
I would love to keep up with the video but next time please make simple example. I only managed to watched half of the video until I became fatigued or exhausted. Great tutorial tho.
can i set breakpoint and debug step by step when using c++ to dev my godot game logic?
Yes, if you're using Visual Studio you can either attach to the process while your game is running and set breakpoints then, or if you dig through the project settings you can configure it to run your project under the debugger when you hit F5. However, if you are also using GDScript you'll need to debug that separately; I don't know of a good way to observe the interactions between the two.
@@Thoughtquake okay, thanks~
Does anyone else have an error: "LINK : error LNK2001: unresolved external symbol -DllMainCRTStartup"
I've spent hours trying to figure this out and I'm at my wits end.
I see solutions online but I don't know how to apply them to SConstruct
Edit: It does work with the example project though. Something with visual studio?
I ended up just modifying the example project
Try to write in SConstruct it:
env.Append(CPPPATH=['NativeLib/NativeLib/'])
sources = Glob('NativeLib/NativeLib/*.cpp')
@@АлександрКузнецов-ь9д Thank you so much!!! you saved the day.
@@rumidu403 Welcome!
"using namespace" is a pretty terrible thing to do, especially in header files.
If godot adds something to their namespace that happens to also be in std or your own namespace and you're "using" all of them, it's almost impossible to know which will be called since it's implementation dependent.
For example, if Godot were to add their own "Level" class, some or all of the instances of you referencing your own class could be interpreted as being godot::Level instead, since you're using their namespace globally.
You make a good point. I take this shortcut to save me time, because in most cases this would be easy to catch and address if/when it becomes a problem. Most compilers treat ambiguous symbols as an error, and even in circumstances where that might not happen there would likely be build-breaking mismatches.
That said, it's probably a bad idea to do what I did in a tutorial without very clear cautions at the least. I'll try to remember to change this when I eventually update/replace this tutorial.
If you really need to save the characters, instead of `using namespace godot`, I'd recommend namespace aliasing with `namespace gd=godot`.
I use it all the time for the absurdly long paths in `std::chrono` since it saves you time and makes the code more readable while keeping namespace safety.
And it's definitely not as big of a problem in smaller projects. I'm used to working in projects with tens or hundreds of thousands of lines across dozens or hundreds of files, so it's not reasonable to just be aware of any potential ambiguity across every library and every function call.
when I run the platform=windows it says it cant find reference.hpp
nvm im stupid I deleted godot-cpp and then when I downloaded the files I forgot to do the generate_bindings
Yo someone else who uses Windows 8.1 Let's go!!!!!
Every time I give Windows 10 a chance I rage-quit due to glaring bugs and ads/notifications everywhere.
I personally enjoy GNU/Linux more but I can understand that some people might want to stick to MS Windows due to software compatibility (I can run quite an amount of Windows software with Wine, though).
Pourquoi la video ne marche pas ?
Is GDNative faster than the C# version of Godot?
Yes, GDNative is way way faster than GDScript and GDNative (C++) is also faster than C#.
With GDNative you are talking in the same language as the engine itself and you are extending it with code. C# by itself is less performant than C++ but it's also used as a scripting language, meaning you don't talk with the engine directly but through translation. All of that has some impact ONLY if you have a heavy logic case.
@@NeZversSounds I moved to C# from gdscript because I dont think I will be able to learn C++ in a million years. I think the diff between C++ and C# in Godot is minimal so I think it should be good enough.
How to compile for android ?
Anyone get the includes working with VSCode?
Nevermind did it using:
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/../godot-cpp/include/**",
"${workspaceFolder}/../godot-cpp/godot_headers/**"
],
Not sure the headers folder is correct though
Can we animate multimeshinstance2d?
It should be possible, but I haven't tried it. You can have limited per-instance custom data that could be used to select the frame, and a custom shader could determine the UV coordinates using that frame number.
Greatttttttrr
@@HediDev where ?
great tutorial but you spoke a bit too fast
Jadyn Estate
Nice tutorial, I would suggest that never write using namespace inside a header file.
meh brain
c++ more like nope++
Why?
@@kidmosey Not sure why I gave that comment. I am sure I had some reasoning behind it, but I can't remember what it was.
C++ should be used when needed, but should not be used when not needed.
@@kidmosey >have you tried to read through the STL
I'll admit, I've never read through the entire thing, but it is *possible* to read. Even so, this point cannot be a valid argument because you don't have to read through the STL to use it in a C++ program. You are not the compiler.
>Add to that the fact that half of the features in the STL are designed around resolving a tedious memory model or other language deficiencies
I'm not sure where you got this from, but you seem to be saying things you don't completely understand. C++11 introduced a standard memory model (regardless of platform or compiler backend) that effectively voids whatever argument was in here, not that there was any argument. If you're not improperly locking a value that you write to, there's nothing to even worry about; the behavior will be the same no matter what even in the land of C++98 (no-man's land.). Besides, the same tediousness will occur no matter what native language you pick, and if you're going to complain about it, maybe you're better off in the land of Java or C# where you "don't have to worry about it" and you get to prance around and say that VM-based languages are the future when they're clearly not and never will be.
>C++ is a hard sell to anyone who hasn't been using it for 20+ years.
Correction: C++ is a hard sell to **you**. A large chunk of commercial applications that are native use it and aren't going to take the effort to switch overnight to some meme-tier language that's relatively unknown just for muh memory safety, so it's never going to "die" per se, no matter how much you wish it to.
0:56 If you prefer working with C++ you dont even need Godot lol
Sure, you could do everything from scratch in C++, but using an engine like Godot saves a ton of time. It gives you a cross-platform graphics engine, physics, audio, and lots more. For most people, I think it's a huge advantage to have all that pre-built and already tested by other people, regardless of what language you use to drive it.
@@Thoughtquake Hmm maybe you are right, But it's just too difficult to just to start writing in C++
@@Thoughtquake Have you tried with SDL2 or similar? or What pros do you see on Godot + C++ over SDL2? Thank you so much for the video.
@@cristianinujazznight3044 I used an older version of SDL long ago, but not SDL2. An engine like Godot just does a lot more of the work for you; i.e. you get a collection of useful UI components you can arrange and customize in a visual editor, a well-designed object hierarchy and scene manager, 2D and 3D physics engines, a cross-platform threading solution, etc. You could probably find open source solutions for all of these things elsewhere and piece them together yourself, but that takes more time. And if you're not procedurally generating everything you probably need an editor of some kind for building levels/environments unless you're really determined to do things the hard way. Having one built into the engine makes things way simpler.
@@Thoughtquake Thank you for the reply. One more question. Could you make a video of VS Code + C++? Thank you :D
I learned nothing from this video.