The short version
Summer Engine is a fork of Godot 4.6.1.stable (mono build). Its GDExtension ABI contract is byte-identical to upstream Godot 4.6.1, so:- A GDExtension built against stock Godot 4.6.1 loads in Summer. There are no Summer-specific headers, no Summer-specific godot-cpp, and no Summer build of anything.
- Third-party, non-Summer-signed libraries load in the shipped, notarized macOS editor. This is proven by loading one, not by reading a plist. See Proof.
- The one genuinely hard part is upstream, not ours: godot-cpp has no 4.6 branch or tag. See The godot-cpp gap.
Verified against the shipped binary. Everything on this page was measured against
4.6.1.stable.mono.custom_build.b708b1182 on macOS. Claims that were read from source rather than executed are labelled inline. Nothing here is inferred from Godot’s documentation.Why the ABI is identical
gdextension_interface.json is the file the whole GDExtension ABI is generated from. In the Summer tree it is unchanged from upstream 4.6.1:
4.6.1-stable and Summer’s HEAD. Alongside it:
The practical consequence: build for Godot 4.6.1, ship to Summer. Summer imposes no restriction that stock Godot 4.6.1 does not.
Proof: a third-party library running inside shipped Summer
macOS hardened runtime normally refuses to load a library that is not signed by the host application’s team. Summer ships withcom.apple.security.cs.disable-library-validation set to true (confirmed with codesign -d --entitlements - on the installed, Developer-ID-signed, notarized, stapled app).
Entitlements are a claim. Here is the measurement. A minimal GDExtension written in plain C, compiled with a bare clang -shared — so the dylib is ad-hoc signed, TeamIdentifier=not set, genuinely third-party — loaded into the shipped binary:
get_godot_version2 resolved through the interface function table, and the initialization callback fired. GDExtension is fully functional in the shipped macOS editor.
You can reproduce that exact result in about a minute — the recipe is below and needs nothing but clang.
Build and load a probe extension
This is the fastest way to confirm your toolchain and Summer agree, before you invest in a real extension. It uses no bindings library at all, only the C header the binary emits. Every command and file below was run end to end on the shipped binary.1
Create the project skeleton
2
Get the interface header from the binary, not from a repo
gdextension_interface.h into the current working directory. Use this file. Do not copy a gdextension_interface.h from anywhere else — see Do not trust a checked-in header.3
Write the extension
Save as
~/probe/src/probe.c:4
Write the .gdextension descriptor
Save as
~/probe/bin/probe.gdextension:5
Register it in extension_list.cfg
.gdextension file on its own loads nothing. See extension_list.cfg.6
Compile and run
PROBE: and [SE] lines shown in Proof. The run then exits with Can't run project: no main scene defined in the project. — that is expected and unrelated; the extension has already loaded and initialized by that point.The godot-cpp gap
Real extensions use godot-cpp, the C++ bindings. There is no godot-cpp for 4.6. Confirmed against the remote:
This is an upstream scarcity, not a Summer restriction — anyone using stock Godot 4.6.1 hits the identical wall.
Workaround: point godot-cpp at Summer’s own API dump
godot-cpp’s SCons build exposes acustom_api_file option — “Path to a custom GDExtension API JSON file (takes precedence over gdextension_dir and api_version)”, defined in tools/godotcpp.py. Feed it the API that Summer itself emits:
The dumped
extension_api.json carries version_full_name: "Summer Engine v4.6.1.stable.mono.custom_build", so it is not byte-identical to an upstream 4.6.1 dump even though the ABI contract is. The version string is cosmetic; the function table is what binds.The .gdextension file format
Read from core/extension/gdextension_library_loader.cpp in the Summer tree, which is unchanged from upstream apart from logging.
[configuration]
[libraries]
Keys are dot-separated feature tags; values are paths. Relative paths resolve against the directory containing the .gdextension file.
[dependencies]
Extra shared objects to stage alongside the library. The precedence rule here is the opposite of [libraries]: the loader takes the first fully-matching tag set and stops. Order matters in [dependencies] and does not in [libraries].
[icons]
Optional. Maps a class name to an editor icon path. Relative paths resolve against the .gdextension file’s directory.
Gotchas that will bite
The extension_list.cfg trap
A .gdextension file alone is not enough. The engine loads extensions from res://.godot/extension_list.cfg, a plain list of paths. Only the editor’s filesystem scan writes that file. A headless or scripted launch against a project where it does not exist loads nothing — and prints nothing, because there is no error to report; the engine simply has an empty list.
Verified by removing the file and re-running: zero GDExtension output, no warning, no error, silent success. This is the single most likely way for an agent to conclude an extension works when it never loaded.
res:// path per line. Opening the project in the editor once also produces it.
Ship a plain .dylib, and make its path resolve
The path in [libraries] must resolve to a real file. Do not rely on Apple’s bundle or @rpath lookup as a fallback.
When the primary load fails, upstream retries with an empty path to let Apple’s bundle lookup have a go. In Summer that retry short-circuits:
.dylib never reaches this code — that is the configuration proven to load, and it is what you should ship. We have not tested a .framework-packaged GDExtension in Summer and make no claim either way about it; a plain .dylib avoids the question entirely.
Do not trust a checked-in header
core/extension/gdextension_interface.h exists in the Summer tree and is stale — dated August 2025, generated from an older Godot generation, and not tracked by upstream 4.6.1 at all (upstream generates it from the JSON at build time). It is one of only two files that differ under core/extension/.
Always get the header from the binary you are targeting:
Platform support
macOS exports and library validation
Read fromplatform/macos/export/export_plugin.cpp; not exercised as a full signed export.
The macOS export preset defaults codesign/entitlements/disable_library_validation to false. The export plugin auto-enables it when the export is ad-hoc signed and carries shared objects, printing “Ad-hoc signed applications require the ‘Disable Library Validation’ entitlement to load dynamic libraries.”
Signing with rcodesign is unsupported when a dynamic library is embedded; the export plugin reports “‘rcodesign’ doesn’t support signing applications with embedded dynamic libraries.”
Web exports
Web GDExtension support requires the engine to be built with WebAssembly dynamic linking. Inplatform/web/detect.py, dlink_enabled defaults to False, and only that flag switches the build to -sMAIN_MODULE=1 / -sSIDE_MODULE=2. Summer ships no web export template, so a web export uses official Godot templates, which are not built with dlink.
Conclusion: do not plan on GDExtension in a web export. Inferred from source; we have not run a web export to confirm the failure mode.
Export templates on other platforms
Summer bundles macOS templates only —macos.zip under 4.6.1.stable/ and 4.6.1.stable.mono/ inside the app bundle. Verified by listing the directory. For other platforms you supply templates yourself, and they are stock Godot 4.6.1 builds.
Worth stating plainly: GDExtension portability across those templates is better than Summer-class portability. Stock templates contain none of Summer’s added classes, but the GDExtension ABI is identical, so a GDExtension built for Godot 4.6.1 runs in them.
Community plugin compatibility
Rules you can apply yourself, rather than a list that will be wrong next month.Godot 3.x addons
Dead. The loader hard-errors on any
compatibility_minimum below 4.1.0. Independently, GDScript 2.0 and the 4.x scene format break 3.x @tool addons. There is no path here.Pure-GDScript @tool addons
The safe bet. No ABI, no compilation, no code signing. If it works on stock Godot 4.6, it works on Summer. See Editor Plugins.
Precompiled GDExtension binaries
Version-locked, and 4.6 is a gap year. Summer adds no restriction beyond stock Godot 4.6.1; the scarcity is entirely upstream, and it is the same scarcity as godot-cpp’s.
Platform check first
Before recommending any GDExtension, resolve the target: macOS editor yes, macOS export yes with signing caveats, Windows and Linux export yes with stock templates, web no.
compatibility_minimum sit at or below 4.6.1 with no compatibility_maximum beneath it? Both must be true. Open the .gdextension file and read the [configuration] block — it is the authoritative answer, and it takes ten seconds.
When a load fails
Summer prints[SE]-prefixed diagnostics that stock Godot does not. They name the resolved absolute path, every fallback location tried, and the raw dlerror string. Search for them first; the stock ERROR: lines below them are less specific.
A missing library produces this, verbatim:
Hot reload of a
reloadable extension is enabled in the editor. It is off everywhere else, by design — the flag is only read in editor builds.
Summer’s own native classes
The live API dump contains 1032 classes; 8 are Summer’s:
These exist to run the editor’s own AI surfaces — authentication, the chat panel, the embedded webview, telemetry, the local tool server, edit coordination. They are documented here so you are not surprised to find them in an API dump. There is no reason to call them from a game. Relying on any of them makes your project unopenable in stock Godot for no benefit.
Next steps
Editor Plugins
Pure-GDScript
@tool plugins — no ABI, no compilation, no signingGodot Compatibility
What Summer shares with stock Godot, and what it adds
macOS Export
Signing, entitlements, and notarization for shipped games
What is open in Summer?
The exact split between open, free, and paid
Need help or have questions? Reach out to our founders at founders@summerengine.com or join our community on Discord for fast responses.

