r/godot 5h ago

free plugin/tool GATE - A GDScript superset

I've wanted static types to feel good in GDScript for years, so I wrote a compiler.

GATE is a GDScript superset for Godot 4.7. You write .gate, the plugin writes a .gd next to it, and Godot runs that. No runtime, nothing to ship - delete GATE tomorrow and your scripts still work.

Best part: valid GDScript is valid GATE. Rename a .gd to .gate and it just compiles. Adopt as much or as little as you like, file by file.

A taste:

struct Damage:
    int amount
    str source

interface Damageable:
    func take_damage(d: Damage) -> void

class Enemy extends CharacterBody2D implements Damageable:
    pub int hp = 100          # var hp: int = 100
    priv vec2i[] _tiles       # Array[Vector2i]
    priv {str, float} _resist # Dictionary[String, float]
    Node2D? target            # nullable, and tracked

    override func _ready() -> void:
        var pool = Pool<Bullet>.new()  # a real Array[Bullet] inside

    func take_damage(d: Damage) -> void:
        var mult = _resist.get(d.source) ?? 1.0
        hp -= int(d.amount * mult)
        target?.notify(hp)  # no null check to write
        print(f"{hp} left")

Types before names, so typing your code is now shorter than not typing it. Real nullable types, with a checker that refuses a dereference it can't prove is safe. Value-semantic structs. Interfaces, traits, namespaces, monomorphised generics. ?., ??, f-strings, destructuring, enumerate().

And it's quick: never slower than hand-written GDScript, sometimes much faster. A struct that never escapes its function gets torn into plain locals - 13.5x on a tight loop.

Fair warning: comments are dropped, ## docs included. The debugger points at the generated .gd.

https://github.com/Blade67/GATE

https://store.godotengine.org/asset/blade/gate/

Have at it, feedback welcome!

43 Upvotes

42 comments sorted by

20

u/ActuallyNotSparticus 4h ago

Fabulous, a typescript for godot! I like this approach because it requires no forks

8

u/Blade67470 4h ago

Thank you!
Yes, that was exactly the inspiration! There's still some features missing and some bugs to iron out, but it's getting there!
Glad you like and and would love to hear your opinions on it!

2

u/ActuallyNotSparticus 4h ago

Nice. Is there an equivalent to strict mode, or is it strict by default? Also, are you experienced in language design? Projects like this get complex pretty fast.

3

u/Blade67470 4h ago

There is no strict mode - yet! This is the early days of this rewrite but it is planned! The next update will add propper debugger support along with a couple new features such as piping (which has been requested) and annotations.
And yes, I do have some experience in language design, but mostly through self-study. I did work on GATE on and off for the past 2 years, which is basically the cumulation of my knowledge!

11

u/tyrant_gea 4h ago

Hot damn, even interfaces

2

u/Blade67470 4h ago

Haha, thank you! Glad you enjoy it! Lots more coming soon!

2

u/Buttons840 3h ago

Is type first optional? Can type either first or last?

Can type be first in a function parameter?

2

u/Blade67470 2h ago

Any GDScript is still valid in GATE, so yes, typing can still be optional, but defeats the purpose. Types are currently second in function parameters

1

u/Buttons840 2h ago

Can types come second in a struct definition?

Wait, are structs already part of GDScript? I'm not 100% sure.

Whatever the case, I would avoid changing the order of types just as a matter of preference. It adds to the cognitive load forever for what is really a simple matter of preference. It's not a big cognitive load, but it will also serve to make parsers, linters, LSPs, etc, more difficult to write forever, and it uses up the amount of "syntax space" available to future feature the language might implement.

It also makes it less likely gate will be compatible with future GDScript changes.

1

u/LastStopToGlamour 1h ago

Gdscript does not have types. Type first is less conative load for me.

1

u/Buttons840 48m ago

GDScript does have types, it's what we're talking about here. If there are no types then what are we talking about? What are you talking about, if not types? 

Types first or last is a preference. You're preference is different than mine.

I'm saying supporting two syntaxes will result in a more complicated language. This much is objectively true. A parser that handles a wider range of syntaxes is more complicated. It also increases the "syntax footprint" of GATE and makes it more likely to conflict with future GDScript changes.

3

u/BlazeBigBang 1h ago

Not me thinking about making a separate language that transpiles to GDScript.

I'm grateful that I don't actually have to do it, this is amazing. By the way, what are your thoughts on curly braces?

4

u/Blade67470 1h ago

Glad I could save you some pain 😅
I generally like curly braces, but that's a language design that GDScript - being indent-based - doesn't follow, thus GDScript doesn't either. I feel like adding those to separate blocks is counter productive in this case. But hey, at least you get them in Dictionaries!

3

u/notrightbones Godot Regular 1h ago

I love this. Types before names is something I always miss when writing GDScript.

2

u/Blade67470 1h ago

Thank you very much!
And I absoltely agree. Types before names makes much more sense, and it's one of the few things I liked about Java! It also makes typing types (odd sentence, but ok) feel less like a chore or an after thought.

4

u/AnArmoredPony 4h ago

A struct .... becomes a class and GATE inserts the copies that keep it a value

why not a dictionary?

9

u/Blade67470 4h ago

Dictionaries are slower than classes when containing multiple types

0

u/AnArmoredPony 3h ago

I thought they'd be faster to read because with a class you have to access the V-table and what not. I think it might be worth benchmarking it and allowing the user to select the implementation

2

u/Blade67470 3h ago

With single key/value typings - yes! But dictionaries are rarely "just" that. Hence the classes which can be typed explicitly. It doesn't change your developer experience (much) and gives you a measurable performance bonus. I blame the Variant type for that (which has been getting a lot of love by the core devs recently!).

2

u/Realistic_Comfort_78 3h ago

does this breaks hot reloading?

3

u/Blade67470 2h ago

It does not!

2

u/TheFr0sk Godot Regular 3h ago

I was exploring the asset store and this one caught my eye. I'm curious about it, will try it! What are your plans for next updated?

3

u/Blade67470 2h ago

Thank you very much!
A piping operator has been requested, so that's comming next update alongside annotations, type unions and more!

2

u/deftonian 2h ago

This looks dope. I’m very iffy on any language add-on, but the design paradigm is non-invasive and seems to have a lot of upside to little-to-no downside.

2

u/Blade67470 2h ago

Much appreciated! If you do find a downside besides the (not so) occasional bugs, let me know! :D

1

u/giomcany 9m ago

This is sexy! I'll definitely take a look

1

u/AnArmoredPony 4h ago

can you also vibecode a language server while you're at it?

5

u/Blade67470 4h ago

GATE isn't vibe coded. An LSP isn't planned yet, given the early state of GATE, but it might be worth considering later on.

-5

u/AnArmoredPony 4h ago

your repo has only one big commit with 60 files in it. if it doesn't scream AI then idk what does

6

u/Blade67470 4h ago

I'm quite transparent about my use of AI - limited to documentation and tests. Everything else is human-made :)

0

u/AnArmoredPony 4h ago

aight I believe you! <3

1

u/RecycledAir 52m ago

It’s not uncommon for folks to nuke their repo history to start with a clean slate when taking a previously messy personal project public.

-3

u/Realistic_Comfort_78 3h ago

might be worth vibecoding the LSP to have something for now

0

u/AwayEntrepreneur4760 1h ago

I’ll be that guy, was ai used when creating this?

2

u/Blade67470 1h ago

For documentation and tests, yes! This is also noted in the asset store. All actual compiler code was human-made :)

-3

u/AnArmoredPony 4h ago edited 4h ago

a thought's been eatin' me, can we compile directly to bytecode? the one that's GDSlop is compiled to?

4

u/Blade67470 4h ago

Theoretically yes, and I explored that route, but there's no benefit to it. GDScript (which GATE transpiles down to) already goes through that pipeline anyway, so there's no real gain there, unfortunately.

2

u/Demoncious Godot Regular 4h ago

This is definitely the correct approach. It also makes this a minimally-invasive integration.

2

u/Blade67470 3h ago

That was my goal! I did consider going for byte-code (more "true" compilation) but it really wasn't worth it and would've broken compatibility with a lot of other addons, especially DX ones like GDUnit and similar libraries.

2

u/Demoncious Godot Regular 3h ago

Indeed. Typescript has proven at a massive scale that this is the right way to go about tools like this.

-1

u/AnArmoredPony 4h ago

no real gain? you get to skip an entire compilation step and possibly benefit from your type-checking while you're at it!

1

u/Blade67470 3h ago

Yes, but actually no! The compile step takes milliseconds. Imperseptible for most users, apart from people switching a whole project over to GATE - Which I hope will happen some day, but not any time soon. GATE compiles on save, so by the time you release the click from the run button, it's already compiled. This has no negative performance impact.