Skip to content
caphindsightPublic

About

Develop Godot projects in C++ with clean syntax and minimal boilerplate.

Resources

Stars

4 stars

Watchers

2 watching

Forks

Latest commit

 

History

314 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GD++

GD++ logo

GD++ is a programming language for Godot. It compiles to C++, and plugs into Godot through GDExtension. It's inspired by the conciseness and simplicity of GDScript.

GD++ looks like GDScript declarations, with C++ implementation. But it is neither GDScript nor C++:

  • Declarations are transpiled into C++ code that targets GDExtension via godot-cpp.
  • Function bodies are flavoured C++: C++ with a few custom quality of life features.

GD++ toolchain comes as one command line tool, gd++: the compiler, a build system that downloads required build dependencies for you, and a built-in manual.

See the GD++ sources of the Foliage3D addon for a real-life project written entirely in GD++.

Note

Disclaimer: The code was mostly written by AI, but a senior engineer made all design decisions.

Hello World

GD++ code: hello_world

Save it as hello_world.gd++ (or any other name with extension any of .gd++, .gdpp or .gg) anywhere in a Godot project, and run:

gd++ init . --bind 10.0.0-stable --spec 4.7.2-stable  # Replace this with the versions you're using.
gd++ fetch --missing
gd++ build

Open the project in Godot: HelloWorldNode is now a node type. Add it to the main scene and run it.

Getting started

You need Godot 4, and Go to build gd++ itself:

make && sudo make install   # builds gd++ and copies it to /usr/local/bin

Then install the tools that compile C++ (Git, SCons, Python and a C++ compiler):

gd++ install          # asks before running anything
gd++ install --echo   # or just prints the commands, to run them yourself

gd++ install supports Debian, Ubuntu, Fedora, Arch, openSUSE, macOS (with Homebrew) and Windows (with winget). It's experimental, and hasn't been tested on every platform. On Linux and macOS, it also installs MinGW-w64, to build for Windows.

The manual

The full documentation is built into the tool, and matches the version you run. Run gd++ man to list its pages, and start with gd++ man intro and gd++ man lang.

The language by example

Blocks use braces, and every value has a static Godot type. Most examples show a few members of a class.

Classes

GD++ code: classes

See gd++ man classes and gd++ man includes.

Functions

GD++ code: functions

See gd++ man functions.

Variables

GD++ code: variables

See gd++ man variables.

Signals

GD++ code: signals

See gd++ man signals.

Signal handlers

GD++ code: signal_handlers

See gd++ man signals.

Exports

GD++ code: exports

See gd++ man exports.

Default values

GD++ code: defaults

See gd++ man functions.

Enums and constants

GD++ code: enums

See gd++ man enums.

Bitfield enums

GD++ code: bitfield

See gd++ man enums.

Properties

GD++ code: properties

See gd++ man variables.

Ready-time initial values

GD++ code: onready

See gd++ man variables.

Callbacks

GD++ code: callbacks

Callbacks are on blocks: code that the engine runs for an object, at a notification like these, at a signal (see Signal handlers), or for a property (see Property callbacks).

See gd++ man callbacks.

Overrides

GD++ code: override

See gd++ man functions.

Typed arrays and dictionaries

GD++ code: typed_collections

See gd++ man types.

Creating and deleting objects

GD++ code: create

See gd++ man classes and gd++ man gd.

Casts

GD++ code: cast

See gd++ man cast.

Assertions

GD++ code: asserts

See gd++ man rewrites.

Doc comments

GD++ code: docs

See gd++ man docs.

Const and static functions

GD++ code: const_static

See gd++ man functions.

Inspector sections

GD++ code: sections

See gd++ man exports.

Virtual functions

GD++ code: virtual

See gd++ man functions.

Constructors and destructors

GD++ code: ctor_dtor

See gd++ man lifecycle.

Deferred functions

GD++ code: deferred

See gd++ man functions.

Thread-safe functions

GD++ code: thread_safe

See gd++ man functions.

Functions on worker threads

GD++ code: onthread

See gd++ man async.

Coroutines and await

GD++ code: async

Like GDScript's await. Scripts await a task with await task.until_done().

See gd++ man async.

Compute shaders

GD++ code: shaders

Shaders are functions written in GLSL, which run on the GPU. Without one, e.g. on a dedicated server, they run on the CPU. A call waits for results that come back to the CPU, e.g. an Image, and returns others right away. With @async, it returns an Async instead, which is done once the GPU is.

See gd++ man shaders.

Callables

GD++ code: callable

See gd++ man rewrites.

Property callbacks

GD++ code: property_callbacks

See gd++ man callbacks.

Singletons

GD++ code: singleton

See gd++ man classes.

Editor plugins

GD++ code: editor_plugin

See gd++ man classes.

Names from the project settings

GD++ code: project_names

See gd++ man project-names.

Tool classes

GD++ code: tool

See gd++ man classes.

Scene classes

GD++ code: scene

See gd++ man classes.

Extending enums

GD++ code: enum_extends

See gd++ man enums.

Traits

GD++ code: traits

See gd++ man traits.

Structs

GD++ code: structs

See gd++ man structs.

Weak references

GD++ code: weak

See gd++ man types.

Remote procedure calls

GD++ code: rpc

See gd++ man rpc.

Object pools

GD++ code: pools

See gd++ man pools.

Tracing

GD++ code: trace

With gd++ build --trace Player, the game prints:

[f812] ▶ Player "Hero".take_damage(amount: 5)
[f812]   Player "Hero".health: 100 → 95  (in take_damage)
[f812] ◀ Player "Hero".take_damage → false  12.4 µs

See gd++ man debugging.

Profiling

GD++ code: profile

With gd++ build --profile ai --print, the game prints a table every 10 seconds:

━━ GD++ profile · last 10.0 s · 600 frames · debug, unoptimized ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Function                 Thread       Calls    Total ms     Self ms      Avg µs      Max µs    ms/frame  Budget (60 FPS)
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Soldier.find_cover         main        1200      846.31      846.31      705.26     4210.55       1.411             8.5%
Soldier.pick_target        main         600       41.82       41.82       69.70      290.04       0.070             0.4%

See gd++ man debugging.

Tests

GD++ code: tests

gd++ test builds the package, and runs the tests of its @test classes in a headless Godot. Only it registers them, and release builds leave them out:

[•] Testing res://.
[•] Passed WalletTest.pays in 0.1 ms.
[•] All 1 test passed.

See gd++ man tests.

Externs

GD++ code: externs

See gd++ man externs.

Cached string names

GD++ code: string_name

See gd++ man runtime.

C++ blocks

GD++ code: code_blocks

See gd++ man code.

Forcing and preventing includes

GD++ code: import

See gd++ man includes.

Templates

GD++ code: templates

See gd++ man templates.

Macros

GD++ code: macros

See gd++ man macros.

User annotations

GD++ code: user_annotations

See gd++ man annotations.

The build tool

  • A project is a normal Godot project.
  • A package is a directory with a .gd++pkg file. It builds into one GDExtension library.
  • Dependencies are the Godot C++ bindings (godot-cpp), the Godot API specs, and the Godot engines that run tests.
gd++ init --vcs git                                       # keep GD++'s files out of git
gd++ init . --bind 10.0.0-stable --spec 4.7.2-stable      # make the project root a package
gd++ init tools --bind 10.0.0-stable --spec 4.7.2-stable  # or add a package anywhere

gd++ fetch --index            # list the dependencies that are available
gd++ fetch --missing          # download what the packages need
gd++ checkin --spec 4.7.2-stable   # commit a dependency with the project
gd++ vendor --spec my-4.7 --from my-4.7   # add a custom one, e.g. from your own Godot build

gd++ build                    # build the packages in the current directory, for this machine, in debug mode
gd++ build res://...          # build every package of the project
gd++ build --ship --for l.x64 w.x64   # release builds for Linux and Windows
gd++ test                     # build them, and run their tests in a headless Godot
gd++ clean                    # delete their build caches

gd++ ls                       # an overview of the project
gd++ trans player.gd++        # print the C++ that GD++ generates from a file
gd++ doc TypedArray           # show what godot-cpp declares under a name
gd++ cat player.gd++          # show a file, highlighted
gd++ fix                      # tidy up the project

The build writes the libraries and a .gdextension file into the package root, so Godot loads them right away.

A package can also hold plain C++ classes, written the usual godot-cpp way. gd++ init . --class Foo --include pkg://foo.h registers them with Godot. Add --ptr, or --ref for refcounted classes, to let GD++ code use them by name.

Status

GD++ is ready to be used, but it's still experimental, and comes with absolutely no warranty. Syntax versions are designed for backward compatibility, but no guarantees can be given yet.

Syntax Status
0 Nightly: the language as it's being developed. Never use it in production.
1 Stable in theory, but experimental in practice.

Each package chooses its syntax version in its .gd++pkg.

See also

  • Foliage3D: a realistic project by the same author, written fully in GD++, which shows what GD++ can do.
  • gdpp-vim: Vim bindings for GD++.
  • Godot Object Compiler: a similar project, which generates the boilerplate of GDExtensions from macros in plain C++ code.

License and credits

GD++ is licensed under the MIT License.

GD++ was created by caphindsight. If GD++ helps you make a game, a mention in its credits would be very much appreciated. The MIT License doesn't require it.

About

Develop Godot projects in C++ with clean syntax and minimal boilerplate.

Resources

Stars

4 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages