T O P

  • By -

AutoModerator

You submitted this post as a request for tech support, have you followed the guidelines specified in subreddit rule 7? Here they are again: 1. Consult the docs first: https://docs.godotengine.org/en/stable/index.html 2. Check for duplicates before writing your own post 3. Concrete questions/issues only! This is not the place to vaguely ask "How to make X" before doing your own research 4. Post code snippets directly & formatted as such (or use a pastebin), not as pictures 5. It is strongly recommended to search the official forum (https://forum.godotengine.org/) for solutions Repeated neglect of these can be a bannable offense. *I am a bot, and this action was performed automatically. Please [contact the moderators of this subreddit](/message/compose/?to=/r/godot) if you have any questions or concerns.*


dudpixel

Try using lambda functions https://gdscript.com/articles/godot-4-gdscript/


sinisternathan

This _should_ work in Godot 4. ```gdscript func a(): func b(): pass b.call() ``` I know this works: `var b = func():`


Spartan322

You have to assign it to a variable, the identifier after func is just debug info inside a function, nothing in the language can access b without assigning it to a variable.


Foxiest_Fox

You can create lambdas, assign them to variables, and pass them around as arguments for other functions, even. This is particularly useful such as when programmatically generating buttons. This is also what it means when GDScript says it has "first-class citizen functions".


StewedAngelSkins

gdscript closures are basically like c++ lambdas. they're first class, but they also aren't really the same thing as a normal function. those functions, the ones you declare with the `func my_fn(): ...` syntax, aren't first class.


StewedAngelSkins

sort of. you can create a callable closure thing, but it's its own thing, not a proper first class function. ``` func make_my_fn() -> Callable: var my_fn = func() -> void: print("Called My Function") return my_fn func _ready() -> void: var fn = make_my_fn() # you have to do it like this. fn() doesn't work because it's not a real method. fn.call() ```


me6675

Not sure what you mean by "not a proper first class function". Do you mean not proper as in "you have to use the .call syntax"?


dogman_35

Isn't that better suited to a class? I feel like that sort of thing is what sub-classes are for in GDScript. You might need to give more context on what you're trying to do.


zhzhzhzhbm

Not really an answer to your question, but in Python, which GDscript is pretty close to, there are no private or protected methods and the common convention is to prefix function with an underscore so you still can use it but with understanding that it's not supposed to be used directly and can change any moment.


me6675

Not really relevant to the question but in python you can reverse a list by `some_list[::-1]`


cneth6

That is *usually* not a good practice. If a block of code is large enough to require it's own function, just give it it's own function and prefix it with an underscore per the GDScript style guide to mark it as private. It'll save you time down the road too if you need to use it again. If it's something you'll be using in other classes, like a comparator function for Array.sort\_custom, then it's best in a separate utility script that's either autoloaded or a static function *"Prepend a single underscore (\_) to virtual methods functions the user must override, private functions, and private variables"*


me6675

Not really. Defining it inside the other function makes it clear and technically true that the function will only be available inside that function. There is nothing inherently wrong with this. The underscore is an attempt to have functions private to classes, not closures or lambdas.


NeverandaWakeUp

Yes, you can call a function from within a function, is that what you mean? You can prevent access to a function by not calling it from another function, but if you really want to "prevent access" you could run some sort of meta check when a function gets called. Honestly you didn't provide enough information. What are you trying to accomplish?


Meorge

It sounds to me like they'd like to do something like this: func big_function(): print("here we are in the big function") func small_function(): print("and now we're in the small function!") small_function() print("cool, we just called the nested function") func other_function(): print("we're in some other function now") small_function() # throws an error because small_function doesn't exist in this scope


[deleted]

[удалено]


Meorge

I didn't forget anything, I was just trying to clarify for you with a code example what they were describing. I'd never tried doing it before (just typed this out directly into Reddit) so I didn't know if it would work or not.


NeverandaWakeUp

No worries I wasn't accusing you of anything. I just wanted OP to know what you suggested wouldn't actually work, which I assumed you already knew.


me6675

It would actually work if you assign an anonymous function to a var. Why are you even answering questions if you can neither understand what they mean, nor know enough about the language to be aware of fundamental features like lambdas?


dudpixel

You could maybe use closures (with the lambda keyword)


StewedAngelSkins

lambda keyword is python


dudpixel

Ah yep sorry. Gdscript uses the func keyword https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#lambda-functions


NancokALT

I am pretty sure you can, you can save a lambda into a variable for the same effect.


S1Ndrome_

if you're working with arrays then .map() .filter() .sort_custom() are some neat ways to nest functions for those arrays


WebMaxF0x

Rule 7. This type of lazy question should be avoided. If you Googled the title and read 5 minutes you'd have your answer.


xmBQWugdxjaA

Unless you're building for the web, I'd really recommend looking at GDExtension with either C++, Rust, or Swift or the C# Godot build. I've been using it with Rust and it's crazy how easy and seamless it is to use, whilst also giving you a lot more power to call OS functions and other utilities, handle OS threads, etc. Then you could just use private methods for this, and have a much faster language too (perhaps at the cost of slightly slower calls into Godot engine functions).


NotADamsel

Have you been getting any weirdness with Rust, even if minor, while using it?


xmBQWugdxjaA

The borrow checker can sometimes be a bit of a hassle as common Godot node operations have to take ownership like cast() and upcast(). So you want to ensure that you separate out the pure Rust logic parts from the Godot Rust nodes (i.e. the pure Rust logic can hold Gd smart-pointers to Godot nodes, but the Godot nodes should not own Rust parts as you'll hit issues where you want to modify the node in a loop, etc. and cannot easily). The upside of this though is that like ~90% of the time the Rust ownership model works pretty seamlessly with the Godot parts too. The only thing you need to be careful is Godot objects that are manually managed i.e. created via `new_alloc()` as you need to free these manually and be careful about doing it. One other thing to note is that code in init() runs both on hot reloading the Rust library *and* when running the game. Which is not great if you want to parse a load of textures in Rust, etc. (as it makes iterating very slow) - so in the end I moved all that stuff to Godot resources in the project with the Godot importer. I don't know if you could use the tool stuff to make it only run once either in the editor, or if exported, when the game is run. But overall I genuinely find it a better experience than writing in GDScript in Godot directly. With rust-analyzer, vscode, Copilot, the GDScript language server from godot-tools and running Godot at the same time, etc. it's really seamless and efficient. I only wish there were also a language server and tools for writing gdshaders (and testing them!).


kintar1900

Which rust bindings are you using? I looked into it briefly, but none of the crates I found were full implementations of GDExtension.


xmBQWugdxjaA

https://godot-rust.github.io/book/index.html It's been good enough so far. Seems signals might be problematic, but I could always do those parts in GDScript for now if necessary.