From 7f5f02940d57196be2f043a1e712129c9570863b Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Mon, 16 Jun 2025 09:01:33 -0500
Subject: [PATCH] Update for GDExtension interface changes in Godot 4.5

---
 binding_generator.py                      |  1 -
 gdextension/gdextension_interface.h       | 57 +++++++++++++++--------
 include/godot_cpp/godot.hpp               | 18 +++++--
 include/godot_cpp/variant/typed_array.hpp |  8 ++--
 src/godot.cpp                             | 28 ++++++++---
 src/variant/packed_arrays.cpp             |  4 --
 6 files changed, 78 insertions(+), 38 deletions(-)

diff --git a/binding_generator.py b/binding_generator.py
index 9e945b020..d5ffc1456 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -911,7 +911,6 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
         result.append("\tconst Variant &operator[](int64_t p_index) const;")
         result.append("\tVariant &operator[](int64_t p_index);")
         result.append("\tvoid set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);")
-        result.append("\tvoid _ref(const Array &p_from) const;")
         result.append("""
 	struct Iterator {
 		_FORCE_INLINE_ Variant &operator*() const;
diff --git a/gdextension/gdextension_interface.h b/gdextension/gdextension_interface.h
index ad31eb6e5..34849a671 100644
--- a/gdextension/gdextension_interface.h
+++ b/gdextension/gdextension_interface.h
@@ -724,6 +724,9 @@ typedef struct {
 
 } GDExtensionScriptInstanceInfo3;
 
+typedef void (*GDExtensionWorkerThreadPoolGroupTask)(void *, uint32_t);
+typedef void (*GDExtensionWorkerThreadPoolTask)(void *);
+
 /* INITIALIZATION */
 
 typedef enum {
@@ -734,6 +737,9 @@ typedef enum {
 	GDEXTENSION_MAX_INITIALIZATION_LEVEL,
 } GDExtensionInitializationLevel;
 
+typedef void (*GDExtensionInitializeCallback)(void *p_userdata, GDExtensionInitializationLevel p_level);
+typedef void (*GDExtensionDeinitializeCallback)(void *p_userdata, GDExtensionInitializationLevel p_level);
+
 typedef struct {
 	/* Minimum initialization level required.
 	 * If Core or Servers, the extension needs editor or game restart to take effect */
@@ -741,8 +747,8 @@ typedef struct {
 	/* Up to the user to supply when initializing */
 	void *userdata;
 	/* This function will be called multiple times for each initialization level. */
-	void (*initialize)(void *userdata, GDExtensionInitializationLevel p_level);
-	void (*deinitialize)(void *userdata, GDExtensionInitializationLevel p_level);
+	GDExtensionInitializeCallback initialize;
+	GDExtensionDeinitializeCallback deinitialize;
 } GDExtensionInitialization;
 
 typedef void (*GDExtensionInterfaceFunctionPtr)();
@@ -815,8 +821,12 @@ typedef void (*GDExtensionMainLoopShutdownCallback)();
 typedef void (*GDExtensionMainLoopFrameCallback)();
 
 typedef struct {
+	// Will be called after Godot is started and is fully initialized.
 	GDExtensionMainLoopStartupCallback startup_func;
+	// Will be called before Godot is shutdown when it is still fully initialized.
 	GDExtensionMainLoopShutdownCallback shutdown_func;
+	// Will be called for each process frame. This will run after all `_process()` methods on Node, and before `ScriptServer::frame()`.
+	// This is intended to be the equivalent of `ScriptLanguage::frame()` for GDExtension language bindings that don't use the script API.
 	GDExtensionMainLoopFrameCallback frame_func;
 } GDExtensionMainLoopCallbacks;
 
@@ -1035,7 +1045,7 @@ typedef void (*GDExtensionInterfaceVariantCall)(GDExtensionVariantPtr p_self, GD
  *
  * Calls a static method on a Variant.
  *
- * @param p_self A pointer to the Variant.
+ * @param p_type The variant type.
  * @param p_method A pointer to a StringName identifying the method.
  * @param p_args A pointer to a C array of Variant.
  * @param p_argument_count The number of arguments.
@@ -1321,7 +1331,7 @@ typedef GDExtensionVariantType (*GDExtensionInterfaceVariantGetType)(GDExtension
  * @param p_self A pointer to the Variant.
  * @param p_method A pointer to a StringName with the method name.
  *
- * @return
+ * @return true if the variant has the given method; otherwise false.
  */
 typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMethod)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_method);
 
@@ -1334,7 +1344,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMethod)(GDExtensionConst
  * @param p_type The Variant type.
  * @param p_member A pointer to a StringName with the member name.
  *
- * @return
+ * @return true if the variant has the given method; otherwise false.
  */
 typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMember)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member);
 
@@ -1505,7 +1515,7 @@ typedef GDExtensionPtrDestructor (*GDExtensionInterfaceVariantGetPtrDestructor)(
  * Constructs a Variant of the given type, using the first constructor that matches the given arguments.
  *
  * @param p_type The Variant type.
- * @param p_base A pointer to a Variant to store the constructed value.
+ * @param r_base A pointer to a Variant to store the constructed value.
  * @param p_args A pointer to a C array of Variant pointers representing the arguments for the constructor.
  * @param p_argument_count The number of arguments to pass to the constructor.
  * @param r_error A pointer the structure which will be updated with error information.
@@ -1728,7 +1738,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen2)(GDEx
  *
  * @param r_dest A pointer to a Variant to hold the newly created String.
  * @param p_contents A pointer to a UTF-16 encoded C string.
- * @param p_size The number of characters (not bytes).
+ * @param p_char_count The number of characters (not bytes).
  */
 typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count);
 
@@ -1740,7 +1750,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUni
  *
  * @param r_dest A pointer to a Variant to hold the newly created String.
  * @param p_contents A pointer to a UTF-16 encoded C string.
- * @param p_size The number of characters (not bytes).
+ * @param p_char_count The number of characters (not bytes).
  * @param p_default_little_endian If true, UTF-16 use little endian.
  *
  * @return Error code signifying if the operation successful.
@@ -1755,7 +1765,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen2)(GDE
  *
  * @param r_dest A pointer to a Variant to hold the newly created String.
  * @param p_contents A pointer to a UTF-32 encoded C string.
- * @param p_size The number of characters (not bytes).
+ * @param p_char_count The number of characters (not bytes).
  */
 typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count);
 
@@ -1767,7 +1777,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUni
  *
  * @param r_dest A pointer to a Variant to hold the newly created String.
  * @param p_contents A pointer to a wide C string.
- * @param p_size The number of characters (not bytes).
+ * @param p_char_count The number of characters (not bytes).
  */
 typedef void (*GDExtensionInterfaceStringNewWithWideCharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_char_count);
 
@@ -2084,6 +2094,7 @@ typedef const uint8_t *(*GDExtensionInterfaceImagePtr)(GDExtensionObjectPtr p_in
  * @param p_instance A pointer to a WorkerThreadPool object.
  * @param p_func A pointer to a function to run in the thread pool.
  * @param p_userdata A pointer to arbitrary data which will be passed to p_func.
+ * @param p_elements The number of element needed in the group.
  * @param p_tasks The number of tasks needed in the group.
  * @param p_high_priority Whether or not this is a high priority task.
  * @param p_description A pointer to a String with the task description.
@@ -2092,7 +2103,7 @@ typedef const uint8_t *(*GDExtensionInterfaceImagePtr)(GDExtensionObjectPtr p_in
  *
  * @see WorkerThreadPool::add_group_task()
  */
-typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask)(GDExtensionObjectPtr p_instance, void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description);
+typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask)(GDExtensionObjectPtr p_instance, GDExtensionWorkerThreadPoolGroupTask p_func, void *p_userdata, int p_elements, int p_tasks, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description);
 
 /**
  * @name worker_thread_pool_add_native_task
@@ -2108,7 +2119,7 @@ typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask)(GDExte
  *
  * @return The task ID.
  */
-typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeTask)(GDExtensionObjectPtr p_instance, void (*p_func)(void *), void *p_userdata, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description);
+typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeTask)(GDExtensionObjectPtr p_instance, GDExtensionWorkerThreadPoolTask p_func, void *p_userdata, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description);
 
 /* INTERFACE: Packed Array */
 
@@ -2526,10 +2537,10 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceGlobalGetSingleton)(GDExtensi
  * Gets a pointer representing an Object's instance binding.
  *
  * @param p_o A pointer to the Object.
- * @param p_library A token the library received by the GDExtension's entry point function.
+ * @param p_token A token the library received by the GDExtension's entry point function.
  * @param p_callbacks A pointer to a GDExtensionInstanceBindingCallbacks struct.
  *
- * @return
+ * @return A pointer to the instance binding.
  */
 typedef void *(*GDExtensionInterfaceObjectGetInstanceBinding)(GDExtensionObjectPtr p_o, void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks);
 
@@ -2540,7 +2551,7 @@ typedef void *(*GDExtensionInterfaceObjectGetInstanceBinding)(GDExtensionObjectP
  * Sets an Object's instance binding.
  *
  * @param p_o A pointer to the Object.
- * @param p_library A token the library received by the GDExtension's entry point function.
+ * @param p_token A token the library received by the GDExtension's entry point function.
  * @param p_binding A pointer to the instance binding.
  * @param p_callbacks A pointer to a GDExtensionInstanceBindingCallbacks struct.
  */
@@ -2553,7 +2564,7 @@ typedef void (*GDExtensionInterfaceObjectSetInstanceBinding)(GDExtensionObjectPt
  * Free an Object's instance binding.
  *
  * @param p_o A pointer to the Object.
- * @param p_library A token the library received by the GDExtension's entry point function.
+ * @param p_token A token the library received by the GDExtension's entry point function.
  */
 typedef void (*GDExtensionInterfaceObjectFreeInstanceBinding)(GDExtensionObjectPtr p_o, void *p_token);
 
@@ -2563,11 +2574,13 @@ typedef void (*GDExtensionInterfaceObjectFreeInstanceBinding)(GDExtensionObjectP
  *
  * Sets an extension class instance on a Object.
  *
+ * `p_classname` should be a registered extension class and should extend the `p_o` Object's class.
+ *
  * @param p_o A pointer to the Object.
  * @param p_classname A pointer to a StringName with the registered extension class's name.
  * @param p_instance A pointer to the extension class instance.
  */
-typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */
+typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance);
 
 /**
  * @name object_get_class_name
@@ -2632,7 +2645,7 @@ typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensio
  * @param p_object A pointer to the Object.
  * @param p_method A pointer to a StringName identifying the method.
  *
- * @returns true if the object has a script and that script has a method with the given name. Returns false if the object has no script.
+ * @return true if the object has a script and that script has a method with the given name. Returns false if the object has no script.
  */
 typedef GDExtensionBool (*GDExtensionInterfaceObjectHasScriptMethod)(GDExtensionConstObjectPtr p_object, GDExtensionConstStringNamePtr p_method);
 
@@ -2813,6 +2826,8 @@ typedef void (*GDExtensionInterfaceCallableCustomCreate2)(GDExtensionUninitializ
  *
  * @param p_callable A pointer to a Callable.
  * @param p_token A pointer to an address that uniquely identifies the GDExtension.
+ *
+ * @return The userdata pointer given when creating this custom Callable.
  */
 typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstTypePtr p_callable, void *p_token);
 
@@ -3068,10 +3083,12 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassSignal)(GDExtens
  *
  * Unregisters an extension class in the ClassDB.
  *
+ * Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first.
+ *
  * @param p_library A pointer the library received by the GDExtension's entry point function.
  * @param p_class_name A pointer to a StringName with the class name.
  */
-typedef void (*GDExtensionInterfaceClassdbUnregisterExtensionClass)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */
+typedef void (*GDExtensionInterfaceClassdbUnregisterExtensionClass)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name);
 
 /**
  * @name get_library_path
@@ -3154,7 +3171,7 @@ typedef void (*GDExtensionInterfaceEditorRegisterGetClassesUsedCallback)(GDExten
  * Registers callbacks to be called at different phases of the main loop.
  *
  * @param p_library A pointer the library received by the GDExtension's entry point function.
- * @param p_callback A pointer to the structure that contains the callbacks.
+ * @param p_callbacks A pointer to the structure that contains the callbacks.
  */
 typedef void (*GDExtensionInterfaceRegisterMainLoopCallbacks)(GDExtensionClassLibraryPtr p_library, const GDExtensionMainLoopCallbacks *p_callbacks);
 
diff --git a/include/godot_cpp/godot.hpp b/include/godot_cpp/godot.hpp
index 64b41f6f4..cf64b7e7d 100644
--- a/include/godot_cpp/godot.hpp
+++ b/include/godot_cpp/godot.hpp
@@ -40,10 +40,10 @@ extern "C" GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_add
 extern "C" GDExtensionClassLibraryPtr library;
 extern "C" void *token;
 
-extern "C" GDExtensionGodotVersion godot_version;
+extern "C" GDExtensionGodotVersion2 godot_version;
 
 // All of the GDExtension interface functions.
-extern "C" GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version;
+extern "C" GDExtensionInterfaceGetGodotVersion2 gdextension_interface_get_godot_version2;
 extern "C" GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc;
 extern "C" GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc;
 extern "C" GDExtensionInterfaceMemFree gdextension_interface_mem_free;
@@ -155,7 +155,6 @@ extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_inter
 extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const;
 extern "C" GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index;
 extern "C" GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const;
-extern "C" GDExtensionInterfaceArrayRef gdextension_interface_array_ref;
 extern "C" GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed;
 extern "C" GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index;
 extern "C" GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const;
@@ -204,6 +203,7 @@ extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_inter
 extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len;
 extern "C" GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw;
 extern "C" GDExtensionInterfaceImagePtr gdextension_interface_image_ptr;
+extern "C" GDExtensionInterfaceRegisterMainLoopCallbacks gdextension_interface_register_main_loop_callbacks;
 
 class DocDataRegistration {
 public:
@@ -228,6 +228,11 @@ class GDExtensionBinding {
 		GDExtensionInitializationLevel minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE;
 		Callback init_callback = nullptr;
 		Callback terminate_callback = nullptr;
+		GDExtensionMainLoopCallbacks main_loop_callbacks = {};
+
+		inline bool has_main_loop_callbacks() const {
+			return main_loop_callbacks.frame_func || main_loop_callbacks.startup_func || main_loop_callbacks.shutdown_func;
+		}
 	};
 
 	class InitDataList {
@@ -262,6 +267,13 @@ class GDExtensionBinding {
 		void register_terminator(Callback p_init) const;
 		void set_minimum_library_initialization_level(ModuleInitializationLevel p_level) const;
 
+		// Register a callback that is called after all initialization levels when Godot is fully initialized.
+		void register_startup_callback(GDExtensionMainLoopStartupCallback p_callback) const;
+		// Register a callback that is called for every process frame. This will run after all `_process()` methods on Node, and before `ScriptServer::frame()`.
+		void register_frame_callback(GDExtensionMainLoopFrameCallback p_callback) const;
+		// Register a callback that is called before Godot is shutdown when it is still fully initialized.
+		void register_shutdown_callback(GDExtensionMainLoopShutdownCallback p_callback) const;
+
 		GDExtensionBool init() const;
 	};
 };
diff --git a/include/godot_cpp/variant/typed_array.hpp b/include/godot_cpp/variant/typed_array.hpp
index 69afdaaea..93479c9a4 100644
--- a/include/godot_cpp/variant/typed_array.hpp
+++ b/include/godot_cpp/variant/typed_array.hpp
@@ -40,7 +40,7 @@ class TypedArray : public Array {
 public:
 	_FORCE_INLINE_ void operator=(const Array &p_array) {
 		ERR_FAIL_COND_MSG(!is_same_typed(p_array), "Cannot assign an array with a different element type.");
-		_ref(p_array);
+		Array::operator=(p_array);
 	}
 	_FORCE_INLINE_ TypedArray(const Variant &p_variant) :
 			TypedArray(Array(p_variant)) {
@@ -48,7 +48,7 @@ class TypedArray : public Array {
 	_FORCE_INLINE_ TypedArray(const Array &p_array) {
 		set_typed(Variant::OBJECT, T::get_class_static(), Variant());
 		if (is_same_typed(p_array)) {
-			_ref(p_array);
+			Array::operator=(p_array);
 		} else {
 			assign(p_array);
 		}
@@ -68,7 +68,7 @@ class TypedArray : public Array {
 	public:                                                                                                      \
 		_FORCE_INLINE_ void operator=(const Array &p_array) {                                                    \
 			ERR_FAIL_COND_MSG(!is_same_typed(p_array), "Cannot assign an array with a different element type."); \
-			_ref(p_array);                                                                                       \
+			Array::operator=(p_array);                                                                           \
 		}                                                                                                        \
 		_FORCE_INLINE_ TypedArray(std::initializer_list<Variant> p_init) :                                       \
 				Array(Array(p_init), m_variant_type, StringName(), Variant()) {                                  \
@@ -79,7 +79,7 @@ class TypedArray : public Array {
 		_FORCE_INLINE_ TypedArray(const Array &p_array) {                                                        \
 			set_typed(m_variant_type, StringName(), Variant());                                                  \
 			if (is_same_typed(p_array)) {                                                                        \
-				_ref(p_array);                                                                                   \
+				Array::operator=(p_array);                                                                       \
 			} else {                                                                                             \
 				assign(p_array);                                                                                 \
 			}                                                                                                    \
diff --git a/src/godot.cpp b/src/godot.cpp
index 06f8ca89a..dec614222 100644
--- a/src/godot.cpp
+++ b/src/godot.cpp
@@ -47,10 +47,10 @@ GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_address = null
 GDExtensionClassLibraryPtr library = nullptr;
 void *token = nullptr;
 
-GDExtensionGodotVersion godot_version = { 0, 0, 0, nullptr };
+GDExtensionGodotVersion2 godot_version = {};
 
 // All of the GDExtension interface functions.
-GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version = nullptr;
+GDExtensionInterfaceGetGodotVersion2 gdextension_interface_get_godot_version2 = nullptr;
 GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc = nullptr;
 GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc = nullptr;
 GDExtensionInterfaceMemFree gdextension_interface_mem_free = nullptr;
@@ -162,7 +162,6 @@ GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_interface_packed
 GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const = nullptr;
 GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index = nullptr;
 GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const = nullptr;
-GDExtensionInterfaceArrayRef gdextension_interface_array_ref = nullptr;
 GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed = nullptr;
 GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index = nullptr;
 GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const = nullptr;
@@ -211,6 +210,7 @@ GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor
 GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len = nullptr;
 GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw = nullptr;
 GDExtensionInterfaceImagePtr gdextension_interface_image_ptr = nullptr;
+GDExtensionInterfaceRegisterMainLoopCallbacks gdextension_interface_register_main_loop_callbacks = nullptr;
 
 struct DocData {
 	const char *hash = nullptr;
@@ -308,8 +308,8 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
 	internal::library = p_library;
 	internal::token = p_library;
 
-	LOAD_PROC_ADDRESS(get_godot_version, GDExtensionInterfaceGetGodotVersion);
-	internal::gdextension_interface_get_godot_version(&internal::godot_version);
+	LOAD_PROC_ADDRESS(get_godot_version2, GDExtensionInterfaceGetGodotVersion2);
+	internal::gdextension_interface_get_godot_version2(&internal::godot_version);
 
 	// Check that godot-cpp was compiled using an extension_api.json older or at the
 	// same version as the Godot that is loading it.
@@ -447,7 +447,6 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
 	LOAD_PROC_ADDRESS(packed_vector4_array_operator_index_const, GDExtensionInterfacePackedVector4ArrayOperatorIndexConst);
 	LOAD_PROC_ADDRESS(array_operator_index, GDExtensionInterfaceArrayOperatorIndex);
 	LOAD_PROC_ADDRESS(array_operator_index_const, GDExtensionInterfaceArrayOperatorIndexConst);
-	LOAD_PROC_ADDRESS(array_ref, GDExtensionInterfaceArrayRef);
 	LOAD_PROC_ADDRESS(array_set_typed, GDExtensionInterfaceArraySetTyped);
 	LOAD_PROC_ADDRESS(dictionary_operator_index, GDExtensionInterfaceDictionaryOperatorIndex);
 	LOAD_PROC_ADDRESS(dictionary_operator_index_const, GDExtensionInterfaceDictionaryOperatorIndexConst);
@@ -496,6 +495,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
 	LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars_and_len, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen);
 	LOAD_PROC_ADDRESS(image_ptrw, GDExtensionInterfaceImagePtrw);
 	LOAD_PROC_ADDRESS(image_ptr, GDExtensionInterfaceImagePtr);
+	LOAD_PROC_ADDRESS(register_main_loop_callbacks, GDExtensionInterfaceRegisterMainLoopCallbacks);
 
 	r_initialization->initialize = initialize_level;
 	r_initialization->deinitialize = deinitialize_level;
@@ -526,6 +526,10 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
 	}
 	level_initialized[p_level]++;
 
+	if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_CORE && init_data && init_data->has_main_loop_callbacks()) {
+		internal::gdextension_interface_register_main_loop_callbacks(internal::library, &init_data->main_loop_callbacks);
+	}
+
 	if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
 		internal::gdextension_interface_editor_register_get_classes_used_callback(internal::library, &ClassDB::_editor_get_classes_used_callback);
 
@@ -596,6 +600,18 @@ void GDExtensionBinding::InitObject::set_minimum_library_initialization_level(Mo
 	init_data->minimum_initialization_level = static_cast<GDExtensionInitializationLevel>(p_level);
 }
 
+void GDExtensionBinding::InitObject::register_startup_callback(GDExtensionMainLoopStartupCallback p_callback) const {
+	init_data->main_loop_callbacks.startup_func = p_callback;
+}
+
+void GDExtensionBinding::InitObject::register_frame_callback(GDExtensionMainLoopFrameCallback p_callback) const {
+	init_data->main_loop_callbacks.frame_func = p_callback;
+}
+
+void GDExtensionBinding::InitObject::register_shutdown_callback(GDExtensionMainLoopShutdownCallback p_callback) const {
+	init_data->main_loop_callbacks.shutdown_func = p_callback;
+}
+
 GDExtensionBool GDExtensionBinding::InitObject::init() const {
 	return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);
 }
diff --git a/src/variant/packed_arrays.cpp b/src/variant/packed_arrays.cpp
index 4206b886d..76fd90cd9 100644
--- a/src/variant/packed_arrays.cpp
+++ b/src/variant/packed_arrays.cpp
@@ -232,10 +232,6 @@ void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Var
 	internal::gdextension_interface_array_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_type, (GDExtensionConstStringNamePtr)&p_class_name, (GDExtensionConstVariantPtr)&p_script);
 }
 
-void Array::_ref(const Array &p_from) const {
-	internal::gdextension_interface_array_ref((GDExtensionTypePtr *)this, (GDExtensionConstTypePtr *)&p_from);
-}
-
 const Variant *Array::ptr() const {
 	return (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, 0);
 }
