T O P

  • By -

XmasB

This is the first thing I do when starting a new project. Is it possible to set this by default for every new project?


KoBeWi

We might eventually get [per-project editor setting overrides](https://github.com/godotengine/godot/pull/69012), which means that some project settings could be moved to editor settings. This would be one of them.


XmasB

That would be be a nice change for sure.


obetu5432

why are they sitting on this for 2 years?


poyomannn

Because they still haven't figured out the visual design, you can read the comments yourself


VelsianOrder

makes make an empty project and set it as a template, copy and past and rename every time you make a new game


XmasB

Yeah, I've considered this. But it seems like almost the same amount of work (not a lot by all means) as just setting the options I want. Will have to test it out. I can just make a script as well I guess.


DrShocker

The main key isn't necessarily the amount of work imo, but rather the reproducibility of your environment. You can set it up manually, but the advantage to using a template is that you are much less likely to have missed a setting. That said, changing settings isn't a big deal and most projects would have at least some nuance specific to that project.


notpatchman

What happens if you don't set it? Do you uncontrollably start using variants?


XmasB

Hehe. No, but I like to enforce it regardless. I'm still learning gdscript, and this is just an extra tool in pushing me to have everything consistent. Especially when I copy/paste example code or from older projects.


me6675

Until we have an optional/nullable type and non-buggy typed arrays and dictionaries in the language I prefer to keep this on warning instead.


ErikThePirate

Agreed. Optional/nullable is a mandatory prerequisite to this.


TheHappyDoggoForever

While I do agree, can’t you just write a wrapper? (We would need generics then ofc… Worst case scenario, you write a class extending from the optional wrapper we wrote that types the variable)


simonschreibt

are there any numbers on how much not doing this affects performance?


SteinMakesGames

Some [official numbers for Godot 3](https://godotengine.org/article/gdscript-progress-report-typed-instructions/#how-faster-is-it) and third party analysis [for Godot 4](https://www.beep.blog/2024-02-14-gdscript-typing/).


simonschreibt

holy moly! that's huge! thanks for the links!


vgscreenwriter

Basically free performance with minimal effort


dumpworth

wow that is a lot


New-Ratio2001

Is this a godot 4 feature or does it exsist in 3 ?


Silpet

Godot 3 does have static typing, but enforcing it is a Godot 4 thing, I believe since 4.1 or 4.2.


Nerzhus

I think it's 4 only


AnObscureGame

I have 4.2 and am not seeing it, so I think you’re right.


Gary_Spivey

I wish they would support function overloads when static typing is enforced. I have a number of functions like "get_item(id)", where id can be an int (itemid), string (item name), or object reference (an item object), so without overloading, with static typing enforced I have to split that into 3 functions: get_item_by_id(), get_item_by_name(), and get_item_by_object(). Very inconvenient 


Asurio666

There's a design principle for this. I think it was in design principles of ID Software that you should not do overloads - get\_item\_by\_id() for id, get\_item\_by\_name() for name, etc. Keep in mind that it's just a principle - every game is different, so use it as you please.


mistabuda

Method overloading is a fairly common feature in most programming languages that have inheritance. This isn't something you use on a per game basis if the design allows it's a core language feature.


bitwes

You can override, but not overload. Override being implementing your own version in a subclass. Overloading being multiple method signatures with the same name.


mistabuda

I'm already aware of these things lol


Gary_Spivey

I suspect that's a relic of an era in which editors didn't have intellisense. I may be wrong, but overloading is very much a "normal" thing to do in modern, typed, compiled-language programming.


bitwes

You can make the parameter a variant and do the "overload" yourself using typeof.


runevault

Or is syntax, aka if variable is String:


susimposter6969

Just make sure to loudly fall though to an error if your variant is not one of the types you expected


susimposter6969

Just make sure to loudly fall though to an error if your variant is not one of the types you expected


TestSubject006

This is the way


DongIslandIceTea

The deeper you go into this rabbit hole the more you are reinventing the wheel called a "static type system" in a dynamically typed language by doing horrible hacks. If you want the benefits of a statically typed language, you already have the option of writing your code in C#.


Gary_Spivey

I think C# is ugly. It reminds me of Java.


trickster721

Well, C# is a response to Java, so that makes sense. Personally I think "var thing: bool = true" is pretty ugly compared to "bool thing = true", but to each their own. I'll also never get used to the meaningless : after every function declaration, it seems like the only reason that's there is because people are used to seeing the hideous { in K&R indentation. (Whitesmiths all day every day.)


DongIslandIceTea

You get the prize for worst reason not to use a language so far.


Gary_Spivey

LISP enjoyers be like


DongIslandIceTea

Strawman enjoyers be like


MrKiwi24

Isn't that just OOP? You can have 2 methods with the same name but different parameters.


Gary_Spivey

OOP is the general concept of working with objects (instances of classes). Functions are technically considered first-class objects in GDScript 2.0, but that isn't really relevant to the concept of overloads. You can't have 2 functions with the same name but different parameters in GDScript.


wektor420

C++ Templates would solve this


Riemero

In C/C++, functions with the same name but different parameter types are supported out of the box


wektor420

Yeah functions with auto are templates under the hood, idk why i got downvoted


xxmatxx

Because function overloading is diferent thing than auto variable. Google it.


TermosifoneFreddo

There's quite a few more I'd change: * Unassigned Variable: Error * Untyped Declaration: Error * Unsafe Property Access: Error * Unsafe Method Access: Error * Unsafe Cast: Warn * Unsafe Call Argument: Error * Narrowing Conversion: Ignore Part of [my blog post](https://brunofranco.io/pills/godot-vscode-integration#static-typing) about making Godot/GDscript work nicely with vscode was about static typing.


DaelonSuzuka

RE your blog post: There's no reason to change the Language Server port in the Godot Editor Settings anymore.


TermosifoneFreddo

hey thanks! I'll change that ASAP. You're one of the main authors of godot-tools, right? Thanks for your hard work, it's pretty safe to say that without you I and probably many others wouldn't be using Godot right now. So thanks a lot!


DaelonSuzuka

That's incredible to hear, thank you so much! I started contributing to the extension just to fix my own problems, so it's always a nice surprise when I hear that other people find it useful too.


Brickless

until Godot implements static strings and let's you define more than 1 level deep into an array I'm gonna stick with mixed typing. I think one of those two is coming in 4.3


beta_1457

I was reading about this the other day and I was actually curious why a few of the tutorials I watched did this automatically. The docs also recommend this: "If you prefer static typing, we recommend enabling the **Text Editor > Completion > Add Type Hints** editor setting."


RoyalBooty77

This comment is how it's started This OP is how it's going


aWay2TheStars

Why not use C# then? I find it a lot of typing to do this in Gdscript


SimplexFatberg

Alternatively: C#


Epsilia

Ayyy! I didn't even know this was possible! Thanks!


rpsHD

new to godot and game dev in general. does static typing remove the error highlighting or sth?


runevault

static typing adds error highlighting without having to run the game because it knows enough to tell you "this thing is going to fail" instead of having to wait until it hits that line of code (example, if you have an untyped parameter in your function, and then try to do paramter.method(), the editor has no way to know for certain if method exists on the parameter, but if you type it (such as value: String) it can tell you method does not exist.


rpsHD

oo, thats neat thx for explaining btw


runevault

The more people who are able to use godot and not run into issues, the more chances there are for good games for all of us to play, so I try to do my part :)


BaronVonMunchhausen

I just started a couple of weeks ago with Godot and thankfully my project is still kinda small but I'm glad I spent all my time today refactoring the code. The estimated performance improvements are huge! 16 files changed, 274 insertions(+), 252 deletions(-) That was a big commit!


edparadox

We're getting closer to a mixed language between Python and C++.


peerlessblue

These are the same type hints as Python. It's just not enforced.


Only_Expression7261

I do not understand why anyone in their right mind would not use static typing.


PoisnFang

I didn't know this when I started Godot, I might need to take another look at using Godot...


Yitzach

I just tried this and it threw a bunch of errors around for loop iterators that I don't know how to resolve, anyone got any advice?


DongIslandIceTea

Nobody is going to be able to help you without seeing your actual code and the errors, we're not mind readers.


Yitzach

Reading what I wrote again I thought I'd been much clearer lol. For loop iterator variables are throwing the "not statically typed" error and I don't know how/if I can resolve it. Anything of the form `for child in get_children():`.


DongIslandIceTea

It's because it's missing the type declaration: for child: Node in get_children(): If you expect a more specific type from the children than `Node`, use that and enjoy the benefits of static typing in the loop body too.


Yitzach

... I don't know why I never considered trying the colon syntax for typing for loop iterators lol. Thanks!


Araraura

Wouldn't marking them as errors break addons that don't use static typing?


Cant-Help-But-Help

There's an option to exclude the addon folder from all these settings at the very top.


Araraura

Neat


Smooth_Durian

Thank you!


mistabuda

This is the 3rd day in a row we've gotten a static typing post.


SteinMakesGames

Be the 4th you want to see in the world


[deleted]

[удалено]


haikusbot

*He is right i would* *Not want some teacher telling* *Any child of mine* \- Reasonable\_Edge2411 --- ^(I detect haikus. And sometimes, successfully.) ^[Learn more about me.](https://www.reddit.com/r/haikusbot/) ^(Opt out of replies: "haikusbot opt out" | Delete my comment: "haikusbot delete")


Salazar20

If I do this I will spend a month adding void to my functions lmao


FortuneDW

Can't you set up a linter to do that ? You can also enforce specific code rules (no unused variables, comments for each method)


mirithil

Love this! Only point of note for me is that for some reason when chain-accessing fields of nodes I sometimes lose typing and have to do an `as` casting and deal with the case when the return of the casting is null. Is that something people using full static typing with GDS are experiencing? Do you have any recommendations?


SpikyGames1

im pretty sure this the the default setting for it in godot 4.3 (at least in beta cuz i am using godot 4.3 beta-1 for no reason) so i guess that's a win


QuishyTehQuish

One of the reasons I love GDScript is because it allows for both. Of course static is better but sometimes I just don't know what a variable's going to be and the leniency it gives me is great. Dynamic language is a feature not a bug.


Hopeful_Bacon

C# and many other typed languages do this as well.


QuishyTehQuish

The problem with C# and others like it is that they are very verbose. GDScript syntax is closer to Python and is purposefully made to be easy to type/implement, but unlike python it allows for static typing. So while your refactoring just static type it then for that performance boost you may or not need. At the end of the day telling people to force themselves out of a language feature is silly.


Yffum

I believe Python does technically support static typing using the same syntax to specify parameter types and return types. What it doesn’t have is native type checking, so you need to do it manually or use an addon.


QuishyTehQuish

From what I understand Python static typing is only for type-checkers and has no effect on the interpreter.


mistabuda

It's not static typing. They're type hints. All objects still follow the rules of dynamic typing at runtime. The hints are just their for other developers to understand the intended interface.


Yffum

Oh that makes sense. So would you say it's kind of a misnomer for mypy to call itself "static typing for python" since it doesn't come with the runtime efficiency of static typing (unlike Godot)? Or maybe I'm caught up in the details and everyone understands what they mean haha.


Yffum

Yes I think that’s right, but stuff like that is such a breeze these days with VS Code extensions. I was just mentioning it in case you hadn’t used Python since they added support for the syntax.


mistabuda

It's not static typing. They're type hints. All objects still follow the rules of dynamic typing at runtime. The hints are just their for other developers to understand the intended interface.


Hopeful_Bacon

I've been a programmer for over 25 years, and this is probably the dumbest way to go about code efficiency I've ever heard.


QuishyTehQuish

I don't know what your getting uppity about but it's a part of the language so just use what you need. I don't know what's wrong about refactoring after writing logic but you do you.


Hopeful_Bacon

"I'll use typed variables when I need them" is dumb. That's not uppity. You're making more work for yourself.


RoyalBooty77

How do you prefer it?


Hopeful_Bacon

Use typed variables from the get go. It's 4x more performant that way, and typing your variables doesn't slow down rapid prototyping at all. I feel too many people in this sub in particular take the "optimize when you need to" principal too far. That doesn't mean "type bad code until you can't maintain it anymore," it means you shouldn't over-engineer solutions that are slowing down development.


Bwob

> sometimes I just don't know what a variable's going to be and the leniency it gives me is great Serious question: What is an example of a situation where you would know you're going to need to store data in a variable, but not know what kind of data you want to store in it? From my point of view, dynamic typing seems like pure downside - you open yourself up to a ton of possible errors, but I don't understand the benefit. So honest, non-judgmental question: What's a use case that would make you say "thank goodness this is dynamically typed?"


nerfjanmayen

Yeah, I have the same question. I've never had a situation where I actually needed dynamic typing. (unless they mean like, polymorphism? But you can do that with static typing) 


mistabuda

Service locators benefit from dynamic typing. Otherwise you end up with a bunch of inheritance boilerplate. The service locator should not know the concrete type of every service it can locate. It's should really only return the service mapped to specified key.


Bwob

Most of the places I've seen service locators, it was handled via generics, so there actually wasn't any inheritance boilerplate required. You would just call something like: MyServiceType myService = ServiceRegistry.Get(); So the type safety is already baked in, without needing any real boilerplate.


mistabuda

Unless you know the type of every single service your get interface has to return a variant therefore you get no benefit from static typing since every method by default gets and returns a variant


Bwob

That's not true, unless I'm completely misunderstanding what you're saying. ServiceRegistry.Get() // returns a variable of type VideoService ServiceRegistry.Get() // returns a variable of type AudioService ServiceRegistry.Get() // returns a variable of type DebugConsole etc. The types aren't actually related at all, they don't share any common base class or anything. There are no variants involved. Setting it up via generics means that the reference can be returned directly, as the correct type. (This is C# of course - I have no idea if you can do something equivalent in GDScript, as I'm much less familiar with it.)


mistabuda

This whole post is about gdscript so c# is completely irrelevant here. Again c# has a concept of generics so your example applies to c#. Gdscript does not so it does not apply. In gdscript because we don't have method overloading and overriding statically typed methods will result in error and we don't have interfaces. in your audio service example you'd have to have a base AudioService class that every implementation would have to inherit from. This is the boilerplate. It doesn't matter if your class only needs to conform to the interface provided. You're gonna need to inherit from the super class and take everything that comes with it. This defeats the whole purpose of a service locator.


Bwob

>This whole post is about gdscript so c# is completely irrelevant here I mean, at this point it's a post about "What's a situation of a good reason to want code to be dynamically typed?" >Again c# has a concept of generics so your example applies to c#. Yes, that would be why I wrote "This is C# of course". Well done. >in your audio service example you'd have to have a base AudioService class that every implementation would have to inherit from. This is the boilerplate. It doesn't matter if your class only needs to conform to the interface provided. You're gonna need to inherit from the super class and take everything that comes with it. This defeats the whole purpose of a service locator. The (usual) purpose of a service locator is to decouple the code that uses the service from needing to know the actual class that represents the service itself. (So that you can swap out a different audio system, without having to change all the code in your game that plays audio for example.) For that to work, you need SOME kind of common interface that all the listeners of whatever type conform to, whether you do it via a formal interface class, or just by remembering "every audio service needs a Play and Stop function, named `Play()` and `Stop()`) Alternately, if you're just using a service locator class as a way for random code to look up services from whatever random node they're executing from, (the other usual use-case) and AREN'T planning on swapping out services often (or ever) then you don't even need any interface classes. I'm just saying, for the case of service locators, I'm really not seeing any advantage to using dynamic typing. It doesn't seem to actually get you any benefits, and has all the usual downsides. (i. e. not catching type errors until runtime.)


QuishyTehQuish

It's not really a case of not knowing but more ease of use and flexibility. Say I have a current\_target variable but haven't sorted out what a target can be or it can be different things. I can then type check it and run the appropriate functions or check if it has functions without errors. Are there other ways to do this? Absolutely, but GDScript and Python are made to be quick to write and test which is where it shines. I'm not even against static-type. It's something I wish Python could implement but some people here just hate the idea of having options.


DongIslandIceTea

> Say I have a current_target variable but haven't sorted out what a target can be or it can be different things. I can then type check it and run the appropriate functions or check if it has functions without errors. In a statically typed language you just name a supertype of all the possibilities. If it's a 3D game, then any target will almost certainly be descendants of Node3D, so until you know better, you could go with that. (In extreme cases all built-in types can fit in Variant, but if you have to go that far you're probably doing something wrong.) You can then test its type and cast it down to more specific types if need be (preferably you'd try to use normal polymorphism and extension methods instead, but you very much can do it). Ultimately the code will end up very similar.


QuishyTehQuish

Yea it's totally doable and ultimately comes down to usecase and preference. At the end of the day GDScript is still a dynamic language with OPTIONAL static-typing so just use what's appropriate. For me I make a mix of long scripts and small scripts so bug fixing is relatively easy and being able to just mash out a working legible (to me) script that I know is going to get refactored anyway is way more helpful. That being said I do type most of my variables either on the initial wright or the refactored script which is why I like prototyping in GDScript so much.


flynnwebdev

Speed. I cut my teeth on typed languages, but they just slow me down now. I can code far more efficiently in a dynamic language.


Bwob

What part is actually slower though? Do you mean just the physical act of the extra letters required for `int myVar = 5` instead of `myVar = 5`? Because conceptually, I don't understand wanting to make a variable without knowing what you're going to put in it. I'm not trying to be obtuse - That's genuinely alien enough from my thought process that I'm trying to grok it.


flynnwebdev

But in that example, I know what's going in it - an integer. I name my variables so that I can tell what data type is in it from the name alone. What makes it slower is when you want to pass a structure that conforms to the correct interface, but the compiler won't allow it because it's not of the specified type. Typescript is notorious for this, especially when working with React. What happens is that you end up having to typecast everything to make it work, which consumes a lot of time and creates a lot of frustration, particularly when you know that if the type enforcement wasn't there it would work perfectly. Not to mention it makes the code ugly and less flexible. What if you need to change a data type? That could entail a codebase-wide refactoring in some circumstances. Edit: Thanks for trying to understand. Infinitely better than the cowards who downvoted me for expressing why I prefer dynamic languages.


terminal_styles

Then type it as Variant (the 'any' equivalent) . At least your code and you knows that it can be anything.


Donald_Raper

Are you trying to make my life easier?.. mehhh


zeroanaphora

No way I'm typing "void" that much.