Read this first
You cannot add a custom module to Summer Engine. Godot C++ modules are compiled into the engine binary, which means adding one requires checking out the engine source and building it. The Summer engine source is not public —github.com/SummerEngine/SummerEngine returns 404, verified.
There is no workaround, no flag, and no plugin path that changes this. If you are looking to extend Summer, the two real options are:
GDExtension
Native C/C++ code, loaded at runtime from your project. Summer’s ABI is byte-identical to stock Godot 4.6.1, and unsigned third-party libraries are proven to load in the shipped macOS editor.
Editor Plugins
Pure-GDScript
@tool plugins. No ABI, no compilation, no code signing.For the exact split between what is open, what is free, and what is paid, see What is open in Summer Engine?. Nothing here should be read as a commitment to publish engine source.
What a Godot module is
A module is C++ compiled directly into the engine binary at build time. Unlike a GDExtension, it is not loaded at runtime, cannot be distributed separately, and cannot be added to an engine someone else built. It lives in themodules/ directory of the engine source tree, and SCons picks it up automatically.
The trade is straightforward: a module gets unrestricted access to engine internals and zero ABI constraints, and costs you the ability to ship it to anyone who is not also building the engine. GDExtension makes the opposite trade.
Summer’s own additions live in one module, modules/1summer_engine/. Everything the editor does beyond stock Godot — authentication, the chat panel, the embedded webview, the local tool server that MCP talks to, crash reporting, edit coordination, the updater — is inside it.
Anatomy
Summer’s module then subdivides by concern —
core/, auth/, gateway/, chat/, webview/, editor/, analytics/, api/, crash/, verify/, util/.
The two disciplines worth stealing
These are the parts that generalize. Both are about the same question: does this code exist in an exported game, or only in the editor?Initialization levels
initialize_<module>_module receives a ModuleInitializationLevel and switches on it. Registering at the wrong level either crashes or silently does nothing.
uninitialize_<module>_module mirrors it. Ordering in teardown is not cosmetic — Summer’s module unregisters its error handler before tearing down the telemetry client it forwards into, and drops a settings Ref while ObjectDB is still alive, because letting a static Ref destruct during process finalization raced ObjectDB teardown and crashed on every clean exit.
The same shape applies to a GDExtension: minimum_initialization_level in your GDExtensionInitialization struct is the same axis, and your initialize callback is invoked per level.
#ifdef TOOLS_ENABLED decides what ships
Export templates are built without TOOLS_ENABLED. Anything inside that guard does not exist in an exported game — not the class, not the symbol.
This is exactly why, of the 8 classes Summer adds to the engine, only SummerEngineSettings is available in an exported game. The other seven are registered inside #ifdef TOOLS_ENABLED and are editor-only. See Summer’s own native classes.
Get the guard wrong and you do not get a runtime error, you get a link error in the export template build — which is the good outcome. The bad outcome is next.
One cautionary tale: linking a framework unconditionally
Worth reading even if you never write a module, because the same failure is reachable from a GDExtension that links a framework. Summer’s macOS auto-updater uses Sparkle. The updater’s implementation file is entirely wrapped in#ifdef TOOLS_ENABLED, so export templates reference zero Sparkle symbols — the guard was correct. But the SCsub linked the framework unconditionally:
-framework link flag creates a load-command dependency in the produced binary whether or not any symbol from it is referenced. So every exported macOS game came out depending on @rpath/Sparkle.framework. Exports do not bundle it. dyld could not resolve it, and the kernel SIGKILLed the game on launch — presenting as a “Report to Apple” crash dialog, not a Gatekeeper prompt, which sent the first round of debugging in entirely the wrong direction.
The fix was to gate the link flags on the build type, not only the source:
#ifdef guards your source, not your link line. If your GDExtension links a system or third-party framework, check the produced binary’s load commands with otool -L before you ship, and confirm every dependency will actually be present on the user’s machine.
If you were going to ask for a module
Almost everything a module is reached for can be done another way in Summer:
If your case genuinely needs engine internals that GDExtension does not expose, tell us what and why — that is useful signal. founders@summerengine.com or Discord.
Next steps
GDExtension
The supported native extension path, with a verified end-to-end recipe
Editor Plugins
Pure-GDScript tooling inside the editor
What is open in Summer?
Open agent layer, free desktop app, paid hosted services
Godot Compatibility
What Summer shares with stock Godot 4.6.1
Need help or have questions? Reach out to our founders at founders@summerengine.com or join our community on Discord for fast responses.

