first commit

This commit is contained in:
Leonid Pershin
2026-08-10 20:39:06 +03:00
commit f16f60445c
281 changed files with 43576 additions and 0 deletions
@@ -0,0 +1,69 @@
@tool
extends EditorExportPlugin
## Strips the MCP game-helper autoload from exported builds (#740).
##
## plugin.gd writes `autoload/_mcp_game_helper` into project.godot so the
## editor-spawned game process loads the helper. Exports bake project
## settings into the pack's project.binary, so without this plugin every
## export ships the autoload — and users who exclude addons/godot_ai/**
## in their export preset get three "Failed to instantiate an autoload"
## errors at game start. Even when the files ARE shipped, the helper is
## editor-tooling: no exported build should carry it.
##
## Strip mechanics: clear the in-memory ProjectSettings entry in
## _export_begin, restore it in _export_end. The export pipeline reads
## the live ProjectSettings when it bakes project.binary, which happens
## after _export_begin — verified end-to-end by
## script/ci-export-strip-smoke, which exports a real pack and asserts
## the autoload is absent inside it. We never call ProjectSettings.save()
## while stripped, so project.godot on disk keeps the autoload
## throughout; only the export snapshot loses it.
##
## Failure containment: if an export aborts so hard that _export_end
## never fires, the damage is bounded to the editor's in-memory settings
## — the running game reads project.godot from disk, and plugin.gd's
## _ensure_game_helper_autoload() re-asserts the entry on the next
## plugin enable / editor launch.
## Must equal "autoload/" + plugin.gd's GAME_HELPER_AUTOLOAD_NAME.
## Duplicated (not preloaded from plugin.gd) to avoid a cyclic preload —
## plugin.gd preloads this script. The pairing is locked by
## test_export_strip.gd's constants-contract test.
const AUTOLOAD_KEY := "autoload/_mcp_game_helper"
var _saved_value: Variant = null
var _stripped := false
func _get_name() -> String:
return "GodotAIStripAutoload"
func _export_begin(_features: PackedStringArray, _is_debug: bool, _path: String, _flags: int) -> void:
## `_stripped` guard: if a previous export died before _export_end,
## don't overwrite the genuinely-saved value with the already-cleared
## state — restore semantics stay anchored to the original value.
if _stripped:
return
if not ProjectSettings.has_setting(AUTOLOAD_KEY):
return
_saved_value = ProjectSettings.get_setting(AUTOLOAD_KEY)
## Setting a project setting to null erases it.
ProjectSettings.set_setting(AUTOLOAD_KEY, null)
_stripped = true
print("MCP | export: stripping %s from the exported pack (restored in the editor after export)" % AUTOLOAD_KEY)
func _export_end() -> void:
if not _stripped:
return
ProjectSettings.set_setting(AUTOLOAD_KEY, _saved_value)
## Mirror _ensure_game_helper_autoload()'s registration shape so the
## restored entry is indistinguishable from the original: initial
## value "" keeps project.godot diff-clean, basic keeps it visible in
## the non-advanced settings view.
ProjectSettings.set_initial_value(AUTOLOAD_KEY, "")
ProjectSettings.set_as_basic(AUTOLOAD_KEY, true)
_saved_value = null
_stripped = false
@@ -0,0 +1 @@
uid://np0cp6fwpim7